设为首页 收藏本站
查看: 1372|回复: 0

使用Shell脚本来组装“Lua配置模板文件”和“属性配置文件”并生成配置文件

[复制链接]

尚未签到

发表于 2017-5-16 11:44:31 | 显示全部楼层 |阅读模式
  【问题背景】
  前几天,我们上线了“基于’Nginx + Lua‘实现的统一权限校验功能”。该功能需要Nginx守护线程定期地从MySQL加载“合作方数据”,我们直接在Lua文件里写死了MySQL等配置信息(硬编码),然后通过一个“中间配置文件”手动修改来针对不同的部署环境选择不同的数据源
  这里有个坑当开发和运维都忘记修改这个“中间配置文件”时,部署到不同的环境指向的数据源确一样的,会导致验证失败错误。默认是指向线上数据源,当我们部署完线上之后,确认一切正常之后,就立马着手部署测试联调环境,结果都为了要修改这个“中间配置文件”(部署完成后,没有通过本地curl确认其实这样可以减少犯错的机会!)。下午刚把所有相关的环境部署替换完成,结果晚上就有运营接收到客户(“挖财”)的API验证失败错误投诉,因为下午同样的调用还是正常的。
  【线上问题紧急处理】
  虽然,当时接到运营反馈后,leader结合下午的功能上线动作,很快就确认可能由于刚上线的“统一权限校验功能马上先回滚了测试联调环境的Nginx配置,保证客户可以联调。(后来确认问题根源确实是由于数据源加载错误引起需要加载测试联调环境的数据源,结果却加载了线上数据源
  【解决方案】
  从上面这个问题可以看到,“如果依赖人的手动修改才能做正确的事情”是不现实的,应当尽可能地避免这样的情况出现。所以,针对以上问题,我们就联想到能不能通过类似“Spring XML与Properties”分离解耦的技术来实现,然后通过类似Maven预编译来自动生成相关的配置文件。针对以上想法,我做了“通过Shell脚本来组装Lua配置模板文件与配置属性文件来生成配置文件”的尝试,上苍不负有心人,最终搞定这事了。方案步骤,如下:


  • 定义“Lua配置模板文件”
  • 针对不同的部署环境,定义相关的“配置属性文件”
  • 通过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/ 
or 
nginx/lua/bin/config-generator.sh -e test -c nginx/lua/lib/cn/fraudmetrix/ngx/

  【前后方案实现】
  原实现
  中间配置文件 

-- in development
--return require "cn.fraudmetrix.ngx.config.config-dev"
-- in production
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'"

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-378135-1-1.html 上篇帖子: 基于Web的打印方案比较分析(三) 使用WScript.Shell通过编程方式进行复杂的WEB打印 ... 下篇帖子: 【Tiptop ERP T】Tiptop GP與資料庫操作有關的Shell loadx/unloadx createdb解析
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表