首页Openresty文章详情

【干货】Openresty在工作中的实际应用(一)

By Deyi / Mar 3, 2019 阅读 0 评论 0 发表于 Openresty 字数:2370 阅读时间:24秒

Openresty

摘要:通过改变NGINX中ROOT的PATH,路由到指定分支代

    在我们的业务版本迭代中,经常会出现新版本需要灰度上线,仅先用于部分门店(SAAS点餐系统),导致生产环境需要同时运行多个版本代码,一开始我们的临时处理方案是:在NGINX项目配置文件中,通过判断客户端上传的HEADER信息中的版本号,改变ROOT值,解析到相应的代码分支。这种方式每出一个新包都要手动做一次配置文件的修改,十分不便。


    后来自己将服务器上的NGINX换成了Openresty(这个过程并不复杂,对已有业务也没影响),然后写了一个LUA脚本,可以通过后台去配置门店所需要使用的分支,并且按照设备号对应出的分支缓存到REDIS,后台再增加一个按设备号(支持批量)清缓存的功能,便实现了代码灰度发布的自由配置。


    相关截图一(后台设置门店对应的接口分支名称):


    相关截图二(查看设备号对应的分支名称及清除缓存按钮)

   最后是改变ROOT的LUA代码:

local config            = require "config"
local g                 = require "lib.g"
local redis             = require "lib.redis"
local mysql             = require "lib.mysql"

local header = ngx.req.get_headers()
local device_no = header.deviceno
local store_id = header.storeid

if(device_no == nil and store_id == nil)
then
	g.log("empty device_no and store_id")
	return
end

local redis = redis:new(config:get("redis"))

local key,path
if(device_no ~= nil)	--设备号--
then
	key = "lua|device_no|api_path"
	path = redis:hget(key, device_no)
else	--门店ID--
	key = "lua|store_id|api_path"
	path = redis:hget(key, store_id)
end

if(path == 'default')
then
	return
end

if not g.empty(path)
then
	ngx.var.branch = path
	return path
end

if(device_no ~= nil)	--设备号--
then
	redis:hset(key, device_no, 'default')
	g.log("no lua cache|device_no:" .. device_no)
else	--门店ID--
	redis:hset(key, store_id, 'default')
	g.log("no lua cache|store_id:" .. store_id)
end

local db_config = config:get("mysql")
local db_base_config = db_config.db_base
local db_base = mysql:new(db_base_config)

local device_info
if(device_no ~= nil)	--设备号--
then
	--通过设备号获取门店ID
	local sql = "select store_id from wt_device where device_no=:device_no"
	local bind = {
		device_no = device_no
	}
	device_info = db_base:findOne(sql, bind)

	if g.empty(device_info)
	then
		g.log("empty device_info")
		return
	end

	if g.empty(device_info.store_id)
	then
		g.log("empty device_info.store_id")
		return
	end
end

--通过门店ID获取路径配置
local sql = "select path_name from wt_store_config where store_id=:store_id"

local bind
if(device_no ~= nil)	--设备号--
then
	bind = {
		store_id = device_info.store_id
	}
else	--门店ID--
	bind = {
		store_id = store_id
	}	
end

local store_config = db_base:findOne(sql, bind)

if g.empty(store_config)
then
	g.log("empty store_config")
	return
end

if g.empty(store_config.path_name)
then
	g.log("empty store_config.path_name")
	return
end

if(device_no ~= nil)	--设备号--
then
	redis:hset(key, device_no, store_config.path_name)
else	--门店ID--
	redis:hset(key, store_id, store_config.path_name)
end

ngx.var.branch = store_config.path_name
return

手机扫码阅读,舒服~

⌘ + Return 发表
最新 最早 全部评论0 条评论