From 63866a3db9bea50f08cf63541325e90bdff77f21 Mon Sep 17 00:00:00 2001 From: Ovidijus Narkevicius Date: Thu, 30 Jan 2025 16:09:17 +0200 Subject: [PATCH 1/5] feat: dynamic memory allocation for proxy-server Initial implementation Refs: XRDDEV-55 --- .../base/etc/xroad/services/global.conf | 105 ++++++++++++++++++ .../proxy/etc/xroad/services/proxy.conf | 14 ++- 2 files changed, 118 insertions(+), 1 deletion(-) diff --git a/src/packages/src/xroad/common/base/etc/xroad/services/global.conf b/src/packages/src/xroad/common/base/etc/xroad/services/global.conf index 794ed8660f..a61ef9d50f 100644 --- a/src/packages/src/xroad/common/base/etc/xroad/services/global.conf +++ b/src/packages/src/xroad/common/base/etc/xroad/services/global.conf @@ -15,6 +15,111 @@ fi export LD_LIBRARY_PATH="/usr/share/xroad/lib:$LD_LIBRARY_PATH" +function to_megabytes() { + if [[ "$2" == "g" || "$2" == "G" ]]; then + echo "$1*1024" | bc + else + echo "$1" + fi +} + +function find_xm() { + pattern="-Xm$1([0-9]+)(m|g)" + + text="$2" + if [[ $text =~ $pattern ]]; then + to_megabytes ${BASH_REMATCH[1]} ${BASH_REMATCH[2]} + else + echo "0" + fi +} + +function calc_percentile() { + if [ "$1" -gt "1000" ]; then + echo "First argument must be less than or equal to 1000" + exit 1 + fi + echo $2*$1/1000 | bc +} + +function get_total_memory() { + local total_memory="" + + if [ -f /sys/fs/cgroup/memory.max ]; then + # cgroup v2 + memory_limit=$(cat /sys/fs/cgroup/memory.max) + elif [ -f /sys/fs/cgroup/memory/memory.limit_in_bytes ]; then + # cgroup v1 + memory_limit=$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes) + fi + + if [[ -z "$memory_limit" || "$memory_limit" == "max" ]]; then + total_memory=$(free --mega | awk '/Mem:/ {print $2}') + else + total_memory=$(($memory_limit / 1024 / 1024)) + fi + + echo "$total_memory" +} + +#Calculates memory based on total memory and given percentiles +#Arguments: +#1. Total memory +#2. Minimum allowed memory in megabytes +#3. Maximum allowed memory in megabytes +#4. global array variable: memory_config. Percentiles list for getting memory based on total memory. +#For example: ("4000:125" "8000:500") means if total memory is less than 4000 then result is 1/8 of total memory, if less than 8000 then half of total memory. +#should be listed in ascending order based on total memory part. +memory_config=() +calc_xm() { + local -r total_mem="$1" + local -r min_val=$2 + local -r max_val="$3" + + local result="$max_val" + + for pair in "${memory_config[@]}"; do + + IFS=':' read -ra config <<< "$pair" + if [[ "$total_mem" -le "${config[0]}" ]]; then + result="$(calc_percentile ${config[1]} $total_mem)" + break + fi + done + + if [[ "$result" -gt "$max_val" ]]; then + result="$max_val" + fi + + if [[ "$result" -lt "$min_val" ]]; then + result="$min_val" + fi + + echo "$result" +} + +build_xm_args() { + local -r params_line="$1" + + local -r current_xms=$(find_xm s "$params_line") + local -r current_xmx=$(find_xm x "$params_line") + + local mem_params=" " + local total_mem=$(get_total_memory) + + if [[ "$current_xms" -eq "0" ]]; then + memory_config=("${xms_cfg[@]}") + mem_params="$mem_params -Xms$(calc_xm $total_mem $xms_min $xms_max)m " + fi + + if [[ "$current_xmx" -eq "0" ]]; then + memory_config=("${xmx_cfg[@]}") + mem_params="$mem_params -Xmx$(calc_xm $total_mem $xmx_min $xmx_max)m" + fi + + echo "$mem_params" +} + load_from_properties () { if [ -f /etc/xroad/services/local.properties ]; then while IFS='=' read -r key value diff --git a/src/packages/src/xroad/common/proxy/etc/xroad/services/proxy.conf b/src/packages/src/xroad/common/proxy/etc/xroad/services/proxy.conf index aa3d2c08fb..09385928b4 100644 --- a/src/packages/src/xroad/common/proxy/etc/xroad/services/proxy.conf +++ b/src/packages/src/xroad/common/proxy/etc/xroad/services/proxy.conf @@ -19,7 +19,7 @@ done CP="/usr/share/xroad/jlib/proxy.jar" -XROAD_PROXY_PARAMS=" -Xms100m -Xmx512m -XX:MaxMetaspaceSize=140m \ +XROAD_PROXY_PARAMS=" -XX:MaxMetaspaceSize=140m \ -Djavax.net.ssl.sessionCacheSize=10000 \ -Dlogback.configurationFile=/etc/xroad/conf.d/proxy-logback.xml \ -Dxroad.proxy.clientHandlers=${CLIENT_HANDLERS#?} \ @@ -27,3 +27,15 @@ XROAD_PROXY_PARAMS=" -Xms100m -Xmx512m -XX:MaxMetaspaceSize=140m \ -Dxroad.proxy.serverRestServiceHandlers=${SERVICE_REST_HANDLERS#?} $XROAD_PROXY_PARAMS" apply_local_conf XROAD_PROXY_PARAMS + +xms_max="${XROAD_PROXY_XMS_MAX:-2000}" +xms_min=100 +xms_cfg=("4000:50" "8000:64" "16000:125") + +xmx_max="${XROAD_PROXY_XMX_MAX:-16000}" +xmx_min=512 +xmx_cfg=("4000:125" "8000:250" "16000:500" "31000:516") + +memory_config=$(build_xm_args "$XROAD_PROXY_PARAMS") + +XROAD_PROXY_PARAMS="$memory_config $XROAD_PROXY_PARAMS" From f6c6c19265ce227dce871f689d258bf0f014975d Mon Sep 17 00:00:00 2001 From: Ovidijus Narkevicius Date: Fri, 31 Jan 2025 10:59:10 +0200 Subject: [PATCH 2/5] Revert "feat: dynamic memory allocation for proxy-server" This reverts commit ad32823bfc51c294efb8ee7fe76fce260a635f33. --- .../base/etc/xroad/services/global.conf | 105 ------------------ .../proxy/etc/xroad/services/proxy.conf | 14 +-- 2 files changed, 1 insertion(+), 118 deletions(-) diff --git a/src/packages/src/xroad/common/base/etc/xroad/services/global.conf b/src/packages/src/xroad/common/base/etc/xroad/services/global.conf index a61ef9d50f..794ed8660f 100644 --- a/src/packages/src/xroad/common/base/etc/xroad/services/global.conf +++ b/src/packages/src/xroad/common/base/etc/xroad/services/global.conf @@ -15,111 +15,6 @@ fi export LD_LIBRARY_PATH="/usr/share/xroad/lib:$LD_LIBRARY_PATH" -function to_megabytes() { - if [[ "$2" == "g" || "$2" == "G" ]]; then - echo "$1*1024" | bc - else - echo "$1" - fi -} - -function find_xm() { - pattern="-Xm$1([0-9]+)(m|g)" - - text="$2" - if [[ $text =~ $pattern ]]; then - to_megabytes ${BASH_REMATCH[1]} ${BASH_REMATCH[2]} - else - echo "0" - fi -} - -function calc_percentile() { - if [ "$1" -gt "1000" ]; then - echo "First argument must be less than or equal to 1000" - exit 1 - fi - echo $2*$1/1000 | bc -} - -function get_total_memory() { - local total_memory="" - - if [ -f /sys/fs/cgroup/memory.max ]; then - # cgroup v2 - memory_limit=$(cat /sys/fs/cgroup/memory.max) - elif [ -f /sys/fs/cgroup/memory/memory.limit_in_bytes ]; then - # cgroup v1 - memory_limit=$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes) - fi - - if [[ -z "$memory_limit" || "$memory_limit" == "max" ]]; then - total_memory=$(free --mega | awk '/Mem:/ {print $2}') - else - total_memory=$(($memory_limit / 1024 / 1024)) - fi - - echo "$total_memory" -} - -#Calculates memory based on total memory and given percentiles -#Arguments: -#1. Total memory -#2. Minimum allowed memory in megabytes -#3. Maximum allowed memory in megabytes -#4. global array variable: memory_config. Percentiles list for getting memory based on total memory. -#For example: ("4000:125" "8000:500") means if total memory is less than 4000 then result is 1/8 of total memory, if less than 8000 then half of total memory. -#should be listed in ascending order based on total memory part. -memory_config=() -calc_xm() { - local -r total_mem="$1" - local -r min_val=$2 - local -r max_val="$3" - - local result="$max_val" - - for pair in "${memory_config[@]}"; do - - IFS=':' read -ra config <<< "$pair" - if [[ "$total_mem" -le "${config[0]}" ]]; then - result="$(calc_percentile ${config[1]} $total_mem)" - break - fi - done - - if [[ "$result" -gt "$max_val" ]]; then - result="$max_val" - fi - - if [[ "$result" -lt "$min_val" ]]; then - result="$min_val" - fi - - echo "$result" -} - -build_xm_args() { - local -r params_line="$1" - - local -r current_xms=$(find_xm s "$params_line") - local -r current_xmx=$(find_xm x "$params_line") - - local mem_params=" " - local total_mem=$(get_total_memory) - - if [[ "$current_xms" -eq "0" ]]; then - memory_config=("${xms_cfg[@]}") - mem_params="$mem_params -Xms$(calc_xm $total_mem $xms_min $xms_max)m " - fi - - if [[ "$current_xmx" -eq "0" ]]; then - memory_config=("${xmx_cfg[@]}") - mem_params="$mem_params -Xmx$(calc_xm $total_mem $xmx_min $xmx_max)m" - fi - - echo "$mem_params" -} - load_from_properties () { if [ -f /etc/xroad/services/local.properties ]; then while IFS='=' read -r key value diff --git a/src/packages/src/xroad/common/proxy/etc/xroad/services/proxy.conf b/src/packages/src/xroad/common/proxy/etc/xroad/services/proxy.conf index 09385928b4..aa3d2c08fb 100644 --- a/src/packages/src/xroad/common/proxy/etc/xroad/services/proxy.conf +++ b/src/packages/src/xroad/common/proxy/etc/xroad/services/proxy.conf @@ -19,7 +19,7 @@ done CP="/usr/share/xroad/jlib/proxy.jar" -XROAD_PROXY_PARAMS=" -XX:MaxMetaspaceSize=140m \ +XROAD_PROXY_PARAMS=" -Xms100m -Xmx512m -XX:MaxMetaspaceSize=140m \ -Djavax.net.ssl.sessionCacheSize=10000 \ -Dlogback.configurationFile=/etc/xroad/conf.d/proxy-logback.xml \ -Dxroad.proxy.clientHandlers=${CLIENT_HANDLERS#?} \ @@ -27,15 +27,3 @@ XROAD_PROXY_PARAMS=" -XX:MaxMetaspaceSize=140m \ -Dxroad.proxy.serverRestServiceHandlers=${SERVICE_REST_HANDLERS#?} $XROAD_PROXY_PARAMS" apply_local_conf XROAD_PROXY_PARAMS - -xms_max="${XROAD_PROXY_XMS_MAX:-2000}" -xms_min=100 -xms_cfg=("4000:50" "8000:64" "16000:125") - -xmx_max="${XROAD_PROXY_XMX_MAX:-16000}" -xmx_min=512 -xmx_cfg=("4000:125" "8000:250" "16000:500" "31000:516") - -memory_config=$(build_xm_args "$XROAD_PROXY_PARAMS") - -XROAD_PROXY_PARAMS="$memory_config $XROAD_PROXY_PARAMS" From 80872cae682cdda38d67991e803e97a00b77230e Mon Sep 17 00:00:00 2001 From: Ovidijus Narkevicius Date: Tue, 4 Feb 2025 09:36:05 +0200 Subject: [PATCH 3/5] feat: help configure proxy memory allocation Refs: XRDDEV-55 --- ansible/roles/xroad-ss/tasks/ubuntu.yml | 1 + .../usr/share/xroad/scripts/_setup_memory.sh | 166 ++++++++++++++++++ .../proxy/etc/xroad/services/proxy.conf | 2 +- .../xroad/scripts/proxy_memory_helper.sh | 139 +++++++++++++++ .../xroad/ubuntu/generic/xroad-proxy.postinst | 42 ++++- .../ubuntu/generic/xroad-proxy.templates | 20 +++ 6 files changed, 368 insertions(+), 2 deletions(-) create mode 100755 src/packages/src/xroad/common/base/usr/share/xroad/scripts/_setup_memory.sh create mode 100755 src/packages/src/xroad/common/proxy/usr/share/xroad/scripts/proxy_memory_helper.sh diff --git a/ansible/roles/xroad-ss/tasks/ubuntu.yml b/ansible/roles/xroad-ss/tasks/ubuntu.yml index bbf84f179a..98f4a4f0b1 100644 --- a/ansible/roles/xroad-ss/tasks/ubuntu.yml +++ b/ansible/roles/xroad-ss/tasks/ubuntu.yml @@ -28,6 +28,7 @@ with_items: - { question: "xroad-common/username", value: "{{ xroad_ui_user }}" } - { question: "xroad-common/database-host", value: "{{ database_host }}" } + - { question: "xroad-common/proxy-memory", value: "d" } - { question: "xroad-common/admin-subject", value: "/CN={{ inventory_hostname }}" } - { question: "xroad-common/admin-altsubject", value: "IP:{{ ansible_default_ipv4.address }},DNS:{{ inventory_hostname }}" } - { question: "xroad-common/service-subject", value: "/CN={{ inventory_hostname }}" } diff --git a/src/packages/src/xroad/common/base/usr/share/xroad/scripts/_setup_memory.sh b/src/packages/src/xroad/common/base/usr/share/xroad/scripts/_setup_memory.sh new file mode 100755 index 0000000000..9467d24876 --- /dev/null +++ b/src/packages/src/xroad/common/base/usr/share/xroad/scripts/_setup_memory.sh @@ -0,0 +1,166 @@ +#!/bin/bash + +die () { + echo >&2 "$@" + exit 1 +} + +function to_megabytes() { + if [[ $1 =~ ^([0-9]+)m$ ]]; then + echo "${BASH_REMATCH[1]}" + elif [[ $1 =~ ^([0-9]+)g$ ]]; then + echo "${BASH_REMATCH[1]} * 1024" | bc + else + echo "" + fi +} + +get_params_line() { + grep --color=never "^${1}=" "/etc/xroad/services/local.properties" +} + +apply_memory_config(){ + local -r params_file="/etc/xroad/services/local.properties" + local -r params="$(get_params_line "$1")" + + local -r xms="-Xms$2" + local -r xmx="-Xmx$3" + + if [ -z "$params" ]; then + echo "$1=$xms $xmx" >> "$params_file" + else + local pattern="-Xms[0-9]+[mg]" + if [[ "$params" =~ $pattern ]]; then + sed -i -E "/^$1=/s/$pattern/$xms/" "$params_file" + else + sed -i "s/^$1=.*/\0 $xms/" "$params_file" + fi + + local pattern="-Xmx[0-9]+[mg]" + if [[ "$params" =~ $pattern ]]; then + sed -i -E "/^$1=/s/$pattern/$xmx/" "$params_file" + else + sed -i "s/^$1=.*/\0 $xmx/" "$params_file" + fi + fi + + local -r updated_params="$(get_params_line "$1")" + + if [ "$params" == "$updated_params" ]; then + echo "No changes for config line: $updated_params" + else + echo "Updated config line: $updated_params" + fi + +} + +function to_gigabytes_str() { + local mb=$1 + local gb="" + if [[ $1 =~ ^([0-9]+)g$ ]]; then + gb="${BASH_REMATCH[1]}" + elif [[ $1 =~ ^([0-9]+)m$ ]]; then + mb="${BASH_REMATCH[1]}" + fi + + if [[ -z "$gb" && "$mb" -lt "1024" ]]; then + echo "${mb}m" + elif [[ -z "$gb" && "$mb" -ge "1024" ]]; then + gb=$(($mb / 1024)) + echo "${gb}g" + else + echo "${gb}g" + fi +} + +function find_xms() { + if [[ "$1" =~ -Xms([0-9]+[mg]) ]]; then + echo "${BASH_REMATCH[1]}" + else + echo "" + fi +} + +function find_xmx() { + if [[ "$1" =~ -Xmx([0-9]+[mg]) ]]; then + echo "${BASH_REMATCH[1]}" + else + echo "" + fi +} + +function apply_percentile() { + if [ "$1" -gt "1000" ]; then + die "First argument must be less than or equal to 1000" + fi + echo $2*$1/1000 | bc +} + +#Returns total memory in megabytes +function get_total_memory() { + local total_memory="" + + if [ -f /sys/fs/cgroup/memory.max ]; then + # cgroup v2 + memory_limit=$(cat /sys/fs/cgroup/memory.max) + elif [ -f /sys/fs/cgroup/memory/memory.limit_in_bytes ]; then + # cgroup v1 + memory_limit=$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes) + fi + + if [[ -z "$memory_limit" || "$memory_limit" == "max" ]]; then + total_memory=$(free --mega | awk '/Mem:/ {print $2}') + else + total_memory=$(($memory_limit / 1024 / 1024)) + fi + + echo "$total_memory" +} + +#Returns used memory in megabytes +function get_used_memory() { + echo "$(free --mega | awk '/Mem:/ {print $3}')" +} + +#Calculates memory based on total memory and given percentiles +#Arguments: +#1. Total memory +#2. Minimum allowed memory in megabytes +#3. Maximum allowed memory in megabytes +#4. global array variable: memory_config. Percentiles list for getting memory based on total memory. +#For example: ("4000:125" "8000:500") means if total memory is less than 4000 then result is 1/8 of total memory, if less than 8000 then half of total memory. +#should be listed in ascending order based on total memory part. +memory_config=() +calculate_recommended_memory() { + local -r total_mem="$1" + local -r min_val=$(to_megabytes "$2") + local -r max_val=$(to_megabytes "$3") + + local result="$max_val" + + for pair in "${memory_config[@]}"; do + + IFS=':' read -ra config <<< "$pair" + local limit=$(to_megabytes "${config[0]}") + if [[ "$total_mem" -lt "$limit" ]]; then + result=$(apply_percentile "${config[1]}" "$total_mem") + break + fi + done + + if [[ "$result" -gt "$max_val" ]]; then + result="$max_val" + fi + + if [[ "$result" -lt "$min_val" ]]; then + result="$min_val" + fi + + if [[ "$result" -ge "2048" ]]; then + #round it up to nearest gb + result=$(echo "scale=0; (($result+512)/1024)" | bc) + echo "${result}g" + else + echo "${result}m" + fi +} diff --git a/src/packages/src/xroad/common/proxy/etc/xroad/services/proxy.conf b/src/packages/src/xroad/common/proxy/etc/xroad/services/proxy.conf index aa3d2c08fb..6af2d25c2d 100644 --- a/src/packages/src/xroad/common/proxy/etc/xroad/services/proxy.conf +++ b/src/packages/src/xroad/common/proxy/etc/xroad/services/proxy.conf @@ -19,7 +19,7 @@ done CP="/usr/share/xroad/jlib/proxy.jar" -XROAD_PROXY_PARAMS=" -Xms100m -Xmx512m -XX:MaxMetaspaceSize=140m \ +XROAD_PROXY_PARAMS=" $(/usr/share/xroad/scripts/proxy_memory_helper.sh 'get-default') -XX:MaxMetaspaceSize=140m \ -Djavax.net.ssl.sessionCacheSize=10000 \ -Dlogback.configurationFile=/etc/xroad/conf.d/proxy-logback.xml \ -Dxroad.proxy.clientHandlers=${CLIENT_HANDLERS#?} \ diff --git a/src/packages/src/xroad/common/proxy/usr/share/xroad/scripts/proxy_memory_helper.sh b/src/packages/src/xroad/common/proxy/usr/share/xroad/scripts/proxy_memory_helper.sh new file mode 100755 index 0000000000..bb6d262c10 --- /dev/null +++ b/src/packages/src/xroad/common/proxy/usr/share/xroad/scripts/proxy_memory_helper.sh @@ -0,0 +1,139 @@ +#!/bin/bash + +source /usr/share/xroad/scripts/_setup_memory.sh + +usage() +{ +cat << EOF +usage: $0 + +Check and update memory settings for proxy service. + +OPTIONS: + action Action to execute, supported values: + status - display current state: total memory, used memory, current memory configuration for proxy + get-default - displays default memory configuration for proxy service + get-recommended - displays recommended memory configuration for proxy service based on total memory + apply-default - applies default memory configuration for proxy service + apply-recommended - applies recommended memory configuration for proxy service based on total memory + apply - applies custom memory config, requires 2 arguments: min and max memory, for example: $0 apply 512m 5g + +EOF +} + +default_xms="100m" +default_xmx="512m" + +verify_config(){ + local -r xms=$(to_megabytes "$1") + local -r xmx=$(to_megabytes "$2") + + if [ -z "$xms" ]; then + die "Invalid first argument. Must be in format, for example 128m" + fi + + if [ -z "$xmx" ]; then + die "Invalid second argument. Must be in format, for example 3g" + fi + + if [ "$xms" -ge "$xmx" ]; then + die "First argument should be smaller than second" + fi +} + +find_used_by_proxy(){ + echo "$(ps -u xroad -o %mem,args | awk '/ProxyMain/ {print $1}')%" +} + +get_current_xms(){ + local -r ps_args="$(ps -u xroad -o args | grep ProxyMain)" + local -r local_params="$(get_params_line 'XROAD_PROXY_PARAMS')" + + local xms=$(find_xms "$local_params") + + if [ -z "$xms" ]; then + xms=$(find_xms "$ps_args") + fi + + echo "$xms" +} + +get_current_xmx(){ + local -r ps_args="$(ps -u xroad -o args | grep ProxyMain)" + local -r local_params="$(get_params_line 'XROAD_PROXY_PARAMS')" + + local xmx=$(find_xmx "$local_params") + + if [ -z "$xmx" ]; then + xmx=$(find_xmx "$ps_args") + fi + + echo "$xmx" +} + +get_recommended_xms(){ + local -r total_mem=$(get_total_memory) + + memory_config=("4g:49" "8g:63" "16g:125") + echo $(calculate_recommended_memory "$total_mem" "100m" "2g") +} + +get_recommended_xmx(){ + local -r total_mem=$(get_total_memory) + + memory_config=("4g:125" "8g:250" "16g:500" "31g:52") + echo $(calculate_recommended_memory "$total_mem" "512m" "16g") +} + +display_status(){ + local -r total_memory=$(get_total_memory) + local -r used_memory=$(get_used_memory) + local -r used_by_proxy=$(find_used_by_proxy) + local -r current_xms=$(get_current_xms) + local -r current_xmx=$(get_current_xmx) + local -r recommended_xms=$(get_recommended_xms) + local -r recommended_xmx=$(get_recommended_xmx) + + local -r total_memory_str=$(to_gigabytes_str "$total_memory") + local -r used_memory_str=$(($used_memory * 100 / total_memory)) + +cat << EOF +Status: + Total memory: ${total_memory_str} + Used: ${used_memory_str}% + Used by proxy service: ${used_by_proxy} + + Current proxy service memory config: ${current_xms} - ${current_xmx} + + Default config: ${default_xms} - ${default_xmx} + (Apply default config with '$0 apply-default') + + Recommended config based on total memory: ${recommended_xms} - ${recommended_xmx} + (Apply recommended config with '$0 apply-recommended') + +EOF + +} + +if [[ -z "$1" || "$1" == "status" ]]; then + display_status +elif [ "$1" == "get-current" ]; then + echo "$(get_current_xms) $(get_current_xmx)" +elif [ "$1" == "get-default" ]; then + echo "-Xms$default_xms -Xmx$default_xmx" +elif [ "$1" == "get-recommended" ]; then + echo "-Xms$(get_recommended_xms) -Xmx$(get_recommended_xmx)" +elif [ "$1" == "apply-default" ]; then + apply_memory_config "XROAD_PROXY_PARAMS" "$default_xms" "$default_xmx" +elif [ "$1" == "apply-recommended" ]; then + apply_memory_config "XROAD_PROXY_PARAMS" "$(get_recommended_xms)" "$(get_recommended_xmx)" +elif [ "$1" == "apply" ]; then + verify_config "$2" "$3" + apply_memory_config "XROAD_PROXY_PARAMS" "$2" "$3" +elif [ "$1" == "help" ]; then + usage +else + die "Unknown action. Use 'help' to get available actions" +fi + + diff --git a/src/packages/src/xroad/ubuntu/generic/xroad-proxy.postinst b/src/packages/src/xroad/ubuntu/generic/xroad-proxy.postinst index 62973da135..796f1cfa5e 100644 --- a/src/packages/src/xroad/ubuntu/generic/xroad-proxy.postinst +++ b/src/packages/src/xroad/ubuntu/generic/xroad-proxy.postinst @@ -24,6 +24,14 @@ function migrate_conf_value { fi } +function handle_error() { + ERR=$(/tmp/memory.err; then + handle_error + continue + else + break + fi + fi + done + db_stop + invoke-rc.d --quiet rsyslog try-restart || true invoke-rc.d --quiet xroad-confclient try-restart || true invoke-rc.d --quiet xroad-signer try-restart || true diff --git a/src/packages/src/xroad/ubuntu/generic/xroad-proxy.templates b/src/packages/src/xroad/ubuntu/generic/xroad-proxy.templates index 7bc0868491..0fff23086f 100644 --- a/src/packages/src/xroad/ubuntu/generic/xroad-proxy.templates +++ b/src/packages/src/xroad/ubuntu/generic/xroad-proxy.templates @@ -4,6 +4,20 @@ Default: 127.0.0.1:5432 Description: Insert database server connection string This will be used by the Security Server to connect to the database host. +Template: xroad-common/proxy-memory +Type: string +Default: d +Description: Insert proxy server memory config string + This will be used to setup initial and maximum heap size for the proxy service. + . + Allowed values: + . + d - default config: ${DEFAULT_XM} + . + r - recommended config: ${RECOMMENDED_XM} + . + - custom heap size constrains, for example '128m 2g' + Template: xroad-common/admin-subject Type: string Description: Insert admin interface TLS certificate subject name @@ -50,6 +64,12 @@ Description: Error during certificate generation, please fix issues output was: ${ERR} +Template: xroad-common/proxy-memory-error +Type: error +Description: Error applying selected memory config, please fix issues + output was: + ${ERR} + Template: xroad-common/username Type: string Default: From 8697ee929d90e5fbe8c09a3418d36c315bc5f139 Mon Sep 17 00:00:00 2001 From: Ovidijus Narkevicius Date: Tue, 4 Feb 2025 15:40:00 +0200 Subject: [PATCH 4/5] feat: peoxy memory helper fix redhat build Refs: XRDDEV-55 --- src/packages/src/xroad/redhat/SPECS/xroad-base.spec | 1 + src/packages/src/xroad/redhat/SPECS/xroad-proxy.spec | 1 + 2 files changed, 2 insertions(+) diff --git a/src/packages/src/xroad/redhat/SPECS/xroad-base.spec b/src/packages/src/xroad/redhat/SPECS/xroad-base.spec index db366e9b3a..467ba9536b 100644 --- a/src/packages/src/xroad/redhat/SPECS/xroad-base.spec +++ b/src/packages/src/xroad/redhat/SPECS/xroad-base.spec @@ -95,6 +95,7 @@ rm -rf %{buildroot} /usr/share/xroad/scripts/_backup_restore_common.sh /usr/share/xroad/scripts/serverconf_migrations/add_acl.xsl /usr/share/xroad/scripts/_setup_db.sh +/usr/share/xroad/scripts/_setup_memory.sh /usr/share/xroad/scripts/xroad-base.sh /usr/share/xroad/db/liquibase-core.jar /usr/share/xroad/db/liquibase-core-*.jar diff --git a/src/packages/src/xroad/redhat/SPECS/xroad-proxy.spec b/src/packages/src/xroad/redhat/SPECS/xroad-proxy.spec index 6c70dcb4b6..7099f53603 100644 --- a/src/packages/src/xroad/redhat/SPECS/xroad-proxy.spec +++ b/src/packages/src/xroad/redhat/SPECS/xroad-proxy.spec @@ -112,6 +112,7 @@ rm -rf %{buildroot} /usr/share/xroad/scripts/autobackup_xroad_proxy_configuration.sh /usr/share/xroad/scripts/get_security_server_id.sh /usr/share/xroad/scripts/read_db_properties.sh +/usr/share/xroad/scripts/proxy_memory_helper.sh %doc /usr/share/doc/%{name}/LICENSE.txt %doc /usr/share/doc/%{name}/3RD-PARTY-NOTICES.txt %doc /usr/share/doc/%{name}/CHANGELOG.md From f8a4dc8752a76c272267a7257a2193d3ff91ae01 Mon Sep 17 00:00:00 2001 From: Ovidijus Narkevicius Date: Mon, 10 Feb 2025 17:06:19 +0200 Subject: [PATCH 5/5] feat: help configure proxy memory allocation PR comment fixes Refs: XRDDEV-55 --- .../usr/share/xroad/scripts/_setup_memory.sh | 128 +++++++++++------- .../xroad/scripts/proxy_memory_helper.sh | 10 +- 2 files changed, 81 insertions(+), 57 deletions(-) diff --git a/src/packages/src/xroad/common/base/usr/share/xroad/scripts/_setup_memory.sh b/src/packages/src/xroad/common/base/usr/share/xroad/scripts/_setup_memory.sh index 9467d24876..484168d448 100755 --- a/src/packages/src/xroad/common/base/usr/share/xroad/scripts/_setup_memory.sh +++ b/src/packages/src/xroad/common/base/usr/share/xroad/scripts/_setup_memory.sh @@ -5,11 +5,30 @@ die () { exit 1 } -function to_megabytes() { - if [[ $1 =~ ^([0-9]+)m$ ]]; then - echo "${BASH_REMATCH[1]}" - elif [[ $1 =~ ^([0-9]+)g$ ]]; then - echo "${BASH_REMATCH[1]} * 1024" | bc +size_rx="([0-9]+)([kKmMgG]?)" +initial_heap_size_rx="(-Xms|-XX:InitialHeapSize=)($size_rx)" +max_heap_size_rx="(-Xmx|-XX:MaxHeapSize=)($size_rx)" + +function to_bytes() { + local -r regex="^${size_rx}$" + if [[ $1 =~ $regex ]]; then + local -r value=${BASH_REMATCH[1]} + local -r unit=${BASH_REMATCH[2]} + + case $unit in + k|K) + echo "$value * 1024" | bc + ;; + m|M) + echo "$value * 1024 * 1024" | bc + ;; + g|G) + echo "$value * 1024 * 1024 * 1024" | bc + ;; + *) + echo $value + ;; + esac else echo "" fi @@ -29,19 +48,15 @@ apply_memory_config(){ if [ -z "$params" ]; then echo "$1=$xms $xmx" >> "$params_file" else - local pattern="-Xms[0-9]+[mg]" - if [[ "$params" =~ $pattern ]]; then - sed -i -E "/^$1=/s/$pattern/$xms/" "$params_file" - else - sed -i "s/^$1=.*/\0 $xms/" "$params_file" + if [[ "$params" =~ $initial_heap_size_rx ]]; then + sed -i -E "/^$1=/s/$initial_heap_size_rx ?//g" "$params_file" fi + sed -i "s/^$1=.*/\0 $xms/" "$params_file" - local pattern="-Xmx[0-9]+[mg]" - if [[ "$params" =~ $pattern ]]; then - sed -i -E "/^$1=/s/$pattern/$xmx/" "$params_file" - else - sed -i "s/^$1=.*/\0 $xmx/" "$params_file" + if [[ "$params" =~ $max_heap_size_rx ]]; then + sed -i -E "/^$1=/s/$max_heap_size_rx ?//g" "$params_file" fi + sed -i "s/^$1=.*/\0 $xmx/" "$params_file" fi local -r updated_params="$(get_params_line "$1")" @@ -54,36 +69,55 @@ apply_memory_config(){ } -function to_gigabytes_str() { - local mb=$1 - local gb="" - if [[ $1 =~ ^([0-9]+)g$ ]]; then - gb="${BASH_REMATCH[1]}" - elif [[ $1 =~ ^([0-9]+)m$ ]]; then - mb="${BASH_REMATCH[1]}" - fi +function to_unit_str() { + local -r as_bytes="$(to_bytes $1)" - if [[ -z "$gb" && "$mb" -lt "1024" ]]; then - echo "${mb}m" - elif [[ -z "$gb" && "$mb" -ge "1024" ]]; then - gb=$(($mb / 1024)) - echo "${gb}g" + if [ -z "$as_bytes" ]; then + echo "" else - echo "${gb}g" + local value="$as_bytes" + local unit="" + + local bytes_in_k="1024" + local bytes_in_k_half="512" + local bytes_in_m=$(echo "$bytes_in_k * 1024" | bc) + local bytes_in_m_half=$(echo "$bytes_in_k_half * 1024" | bc) + local bytes_in_g=$(echo "$bytes_in_m * 1024" | bc) + local bytes_in_g_half=$(echo "$bytes_in_m_half * 1024" | bc) + + if [ "$value" -gt "$bytes_in_g" ]; then + #value=$(($value / $bytes_in_g)) + value=$(echo "scale=0; (($value+$bytes_in_g_half)/$bytes_in_g)" | bc) + unit="g" + elif [ "$value" -gt "$bytes_in_m" ]; then + #value=$(($value / $bytes_in_m)) + value=$(echo "scale=0; (($value+$bytes_in_m_half)/$bytes_in_m)" | bc) + unit="m" + elif [ "$value" -gt "$bytes_in_k" ]; then + #value=$(($value / $bytes_in_k)) + value=$(echo "scale=0; (($value+$bytes_in_k_half)/$bytes_in_k)" | bc) + unit="k" + fi + + echo "${value}${unit}" fi } function find_xms() { - if [[ "$1" =~ -Xms([0-9]+[mg]) ]]; then - echo "${BASH_REMATCH[1]}" + local -r last_match=$(echo "$1" | grep -o -E "$initial_heap_size_rx" | tail -n 1) + + if [[ "$last_match" =~ $initial_heap_size_rx ]]; then + echo "${BASH_REMATCH[2]}" else echo "" fi } function find_xmx() { - if [[ "$1" =~ -Xmx([0-9]+[mg]) ]]; then - echo "${BASH_REMATCH[1]}" + local -r last_match=$(echo "$1" | grep -o -E "$max_heap_size_rx" | tail -n 1) + + if [[ "$last_match" =~ $max_heap_size_rx ]]; then + echo "${BASH_REMATCH[2]}" else echo "" fi @@ -109,9 +143,7 @@ function get_total_memory() { fi if [[ -z "$memory_limit" || "$memory_limit" == "max" ]]; then - total_memory=$(free --mega | awk '/Mem:/ {print $2}') - else - total_memory=$(($memory_limit / 1024 / 1024)) + total_memory="$(free -b | awk '/Mem:/ {print $2}')" fi echo "$total_memory" @@ -119,7 +151,7 @@ function get_total_memory() { #Returns used memory in megabytes function get_used_memory() { - echo "$(free --mega | awk '/Mem:/ {print $3}')" + echo "$(free -b | awk '/Mem:/ {print $3}')" } #Calculates memory based on total memory and given percentiles @@ -133,15 +165,15 @@ function get_used_memory() { memory_config=() calculate_recommended_memory() { local -r total_mem="$1" - local -r min_val=$(to_megabytes "$2") - local -r max_val=$(to_megabytes "$3") + local -r min_val=$(to_bytes "$2") + local -r max_val=$(to_bytes "$3") local result="$max_val" for pair in "${memory_config[@]}"; do IFS=':' read -ra config <<< "$pair" - local limit=$(to_megabytes "${config[0]}") + local limit=$(to_bytes "${config[0]}") if [[ "$total_mem" -lt "$limit" ]]; then result=$(apply_percentile "${config[1]}" "$total_mem") break @@ -149,18 +181,10 @@ calculate_recommended_memory() { done if [[ "$result" -gt "$max_val" ]]; then - result="$max_val" - fi - - if [[ "$result" -lt "$min_val" ]]; then - result="$min_val" - fi - - if [[ "$result" -ge "2048" ]]; then - #round it up to nearest gb - result=$(echo "scale=0; (($result+512)/1024)" | bc) - echo "${result}g" + echo "$max_val" + elif [[ "$result" -lt "$min_val" ]]; then + echo "$min_val" else - echo "${result}m" + echo "$(to_unit_str $result)" fi } diff --git a/src/packages/src/xroad/common/proxy/usr/share/xroad/scripts/proxy_memory_helper.sh b/src/packages/src/xroad/common/proxy/usr/share/xroad/scripts/proxy_memory_helper.sh index bb6d262c10..7cb599ae7b 100755 --- a/src/packages/src/xroad/common/proxy/usr/share/xroad/scripts/proxy_memory_helper.sh +++ b/src/packages/src/xroad/common/proxy/usr/share/xroad/scripts/proxy_memory_helper.sh @@ -25,15 +25,15 @@ default_xms="100m" default_xmx="512m" verify_config(){ - local -r xms=$(to_megabytes "$1") - local -r xmx=$(to_megabytes "$2") + local -r xms=$(to_bytes "$1") + local -r xmx=$(to_bytes "$2") if [ -z "$xms" ]; then - die "Invalid first argument. Must be in format, for example 128m" + die "Invalid first argument. Must be in [k|m|g] format, for example 128m" fi if [ -z "$xmx" ]; then - die "Invalid second argument. Must be in format, for example 3g" + die "Invalid second argument. Must be in [k|m|g] format, for example 3g" fi if [ "$xms" -ge "$xmx" ]; then @@ -94,7 +94,7 @@ display_status(){ local -r recommended_xms=$(get_recommended_xms) local -r recommended_xmx=$(get_recommended_xmx) - local -r total_memory_str=$(to_gigabytes_str "$total_memory") + local -r total_memory_str=$(to_unit_str "$total_memory") local -r used_memory_str=$(($used_memory * 100 / total_memory)) cat << EOF