셸 스크립트를 사용하여 "Lua 구성 템플릿 파일" 및 "속성 구성 파일"을 조합하고 구성 파일을 생성합니다...

【문제 배경】

며칠 전 'Nginx + Lua' 기반의 통합 권한 검증 기능 '을 출시했습니다 . 이 기능은 MySQL에서 "파트너 데이터"를 주기적으로 로드하기 위해 Nginx 데몬 스레드가 필요합니다. Lua 파일에 MySQL과 같은 구성 정보(하드 코딩됨)를 직접 작성한 다음 "중간 구성 파일"을 수동으로 수정하여 다른 배포 환경에 대해 다른 데이터 소스를 선택합니다 .

여기에는 함정이 있습니다 . 개발과 운영 및 유지 관리가 이 "중간 구성 파일"을 수정하는 것을 잊어버리면 다른 환경에 배포하여 가리키는 데이터 원본이 실제로 동일하여 확인 실패 오류가 발생합니다 . 기본값은 온라인 데이터 소스를 가리키는 것입니다.온라인으로 배포하고 모든 것이 정상임을 확인한 후 즉시 테스트 공동 디버깅 환경을 배포하기 시작합니다.결과는 이 "중간 구성 파일"을 수정하는 것입니다(배포가 완료된 후 로컬 curl을 통해 확인되지 않습니다. 실제로 이렇게 하면 실수할 가능성 줄일있습니다! ) . 오후에는 관련 환경 구축을 모두 교체했고, 그 결과 오후에도 동일한 호출이 여전히 정상적이었기 때문에 저녁에는 고객으로부터 API 검증 실패 오류에 대한 불만("돈 파기")이 접수되었습니다.

 

온라인 문제의 긴급 처리

그러나 운영 피드백을 받은 후 리더는 오후 기능 출시를 기반으로 새로 출시된 " 통합 권한 검증 기능 " 때문일 수 있음을 신속하게 확인 하고 테스트 공동 디버깅 환경의 Nginx 구성을 즉시 롤백하여 고객이 공동 디버깅을 할 수 있도록 했습니다 . (후에 확인 결과 문제의 근본 원인은 실제로 데이터 소스 로딩 오류로 인한 것이었다 . 테스트 합동 디버깅 환경의 데이터 소스를 로딩해야 하는데 온라인 데이터 소스를 로딩한 것이다 .)

 

【해결책】

위의 질문에서 우리는 인간의 수동 수정에만 의존하여 옳은 일을 하는 것은 비현실적 이며 그러한 상황은 가능한 한 피해야 한다는 것을 알 수 있습니다 . 따라서 위의 문제에 대한 대응으로 "Spring XML과 속성"의 분리 및 디커플링과 유사한 기술을 통해 이를 달성한 다음 Maven과 유사한 사전 컴파일을 통해 관련 구성 파일을 자동으로 생성할 수 있는지 궁금합니다 . 위의 아이디어에 대한 응답으로 "쉘 스크립트를 통해 구성 파일을 생성하기 위해 Lua 구성 템플릿 파일과 구성 속성 파일을 조합 "하려고 시도했습니다. 신이 나서 마침내 해냈습니다. 프로그램 단계는 다음과 같습니다.

  1. "Lua 구성 템플릿 파일" 정의
  2. 다른 배포 환경에 대해 관련 "구성 속성 파일"을 정의합니다.
  3. Shell 스크립트를 통해 최종 구성 파일 생성(물론 이 단계는 자동화할 수도 있음)

구체적인 구현 단계는 다음과 같습니다.

1. config-generator.sh에 "실행 권한"이 있는지 확인하십시오. 
ll -h nginx/lua/bin/config-generator.sh

 

2. config-generator.sh에 "실행 권한"이 없으면 "실행 권한"을 부여합니다. 
chmod a+x nginx/lua/bin/config-generator.sh

 

3. "구성 템플릿", "구성 속성 파일" 및 "배포 환경"에 따라 구성 파일(config.lua) 생성 
nginx/lua/bin/config-generator.sh -e test -c /usr/apps/nginx/lua/lib/cn/fraudmetrix/ngx/ 또는 nginx /lua/bin/config-generator.sh -e test -c nginx/lua/lib/cn/fraudmetri 엑스 엑스/ 
ngx 
/

 

【비포·애프터 플랜의 실현】

원래 실현

    중간 구성 파일 

-- 개발 중 
--return require "cn.fraudmetrix.ngx.config.config-dev" 

-- 프로덕션 
return require "cn.fraudmetrix.ngx.config.config-prod"

 

    개발 환경 구성

-- config value
local config = {
  version = "1.1",
  mysql = {
    host = "127.0.0.1",
    port = 3306,
    database = "dev",
    user = "dev",
    password = "123456",
    max_packet_size = 1024 * 1024, -- 1M mysql返回包大小上限
    timeout = 500, -- ms
    idle_timeout = 60000, -- ms
    pool_size = 4
  },
  cache = { -- 缓存大小上限
    partner = 10000, -- 合作方
    upstream = 100  -- 上游
  },
  timer = { -- timer执行周期
    partner = 3600, -- s
  },
}

return config

 

 

现在实现

    完整的代码见附件~~~

 

    Lua配置模板文件 

-- config value
-- 【变量占位符替换】若替换值为“字符串”类型的,以单引号(\')定义;若替换值为“数值”类型的,以双引号(\")定义。
local config = {
  version = '1.1',
  mysql = {
    host = '$mysql_host',
    port = "$mysql_port",
    database = '$mysql_database',
    user = '$mysql_user',
    password = '$mysql_password',
    max_packet_size = "$mysql_max_packet_size", -- 1M mysql返回包大小上限
    timeout = "$mysql_timeout", -- ms
    idle_timeout = "$mysql_idle_timeout", -- ms
    pool_size = "$mysql_pool_size"
  },
  cache = { -- 缓存大小上限
    partner = "$cache_partner_max_num", -- 合作方
    upstream = "$cache_upstream_max_num"  -- 上游
  },
  timer = { -- timer执行周期
    partner = "$timer_partner_period", -- s
  },
}

return config

 

    测试环境的配置属性文件

# 配置属性名称定义以下划线("_")分割,不能以点号(".")分割(因为在Shell脚本中,点号(".")是一个特殊字符)

# MySQL
mysql_host=127.0.0.1
mysql_port=3306
mysql_database=test
mysql_user=test
mysql_password=123456
# 风险点:随着”合作方“接入增多,未来”合作方“MySQL加载的数据大小可能超过该值!
mysql_max_packet_size=1024*1024
mysql_timeout=500
mysql_idle_timeout=60000
mysql_pool_size=4

# Local Cache
# 风险点:随着”合作方“接入增多,未来”合作方“的数量可能超过该值!
cache_partner_max_num=10000
cache_upstream_max_num=100

# Timer
timer_partner_period=3600

 

    Shell解析脚本

#!/usr/bin/env bash

# -----------------------------------------------------------------------------
# Generates 'Configuration' file of Lua (config.lua) automatically.
# -----------------------------------------------------------------------------

usage() {
    echo "Usage:"
    echo "  sh config-generator.sh [-e app_deploy_env] [-c config_file_dir]"
    echo ""
    echo "Description:"
    echo "  -e   application deploy environment. The option value is prod, test or dev."
    echo "  -c   configuration file directory for Lua (/absolute/path/to/lua/config)."
    echo ""
    echo "Example:"
    echo "  nginx/lua/bin/config-generator.sh -e test -c /usr/apps/nginx/lua/lib/cn/fraudmetrix/ngx/"
    echo "  nginx/lua/bin/config-generator.sh -e test -c nginx/lua/lib/cn/fraudmetrix/ngx/"
    echo ""

    exit 1
}

# 默认是“生产环境”
app_deploy_env="prod"
# “配置文件”默认放在“当前目录下”
config_file_dir="."

# 1. 接收“参数”
while getopts ":e:c:h" arg
do
   case $arg in
      e) app_deploy_env="$OPTARG";;
      c) config_file_dir="$OPTARG";;
      h) usage;;
      ?) usage;;
   esac
done

# 2. get 'config_file'
# 兼容“path”与“path/”的情况
config_file_dir_last_char="${config_file_dir: -1}"
if [ "$config_file_dir_last_char"x = "/"x ]; then
    # "path/" + "config.lua"
    config_file="$config_file_dir"config.lua
else
    # "path" + "/config.lua"
    config_file="$config_file_dir"/config.lua
fi

# 兼容“path”与“/path”(相对路径与绝对路径)的情况
config_file_dir_first_char="${config_file_dir:0:1}"
if [ "$config_file_dir_first_char"x != "/"x ]; then
    # relative path
    cur_prg_dir=`pwd`
    config_file="$cur_prg_dir"/"$config_file"
fi

# 3. 根据“配置模板”、“配置属性文件”和“部署环境”来生成“配置内容”
# resolve links - $0 may be a softlink  (解析链接 - $0 可能是一个“软链接”)
# 执行程序
PRG="$0"

while [ -h "$PRG" ] ; do
  ls=`ls -ld "$PRG"`
  link=`expr "$ls" : '.*-> \(.*\)$'`
  if expr "$link" : '/.*' > /dev/null; then
    PRG="$link"
  else
    PRG=`dirname "$PRG"`/"$link"
  fi
done

# ”执行程序“所在的”相对根目录“
PRGDIR=`dirname "$PRG"`
# 转换为”绝对根目录“
PRGDIR=`readlink -f "$PRGDIR"`

config_template_file="$PRGDIR"'/../config/config-template.lua'
config_properties_file="$PRGDIR"/../properties/config-"$app_deploy_env".properties

# 执行“配置模板解析器”
CONFIG_PARSER_EXECUTABLE="$PRGDIR"/config-parser.sh
if [ ! -x "$CONFIG_PARSER_EXECUTABLE" ]; then
    `sudo chmod a+x "$CONFIG_PARSER_EXECUTABLE"`
fi
exec "$CONFIG_PARSER_EXECUTABLE" "$config_file" "$config_template_file" "$config_properties_file"

 

#!/usr/bin/env bash

# -----------------------------------------------------------------------------
# Generates 'config.lua' by 'config-template.lua' and 'config-${mode}.properties'.
# -----------------------------------------------------------------------------

config_file="$1"
config_template_file="$2"
config_properties_file="$3"

# source the properties
. "$config_properties_file"

# replace the placeholder
eval "echo \"$(<$config_template_file)\"" > "$config_file"

echo "Generates 'Configuration' file of Lua to '$config_file'"

 

 

추천

출처blog.csdn.net/shupili141005/article/details/84720677