abtestingGateway错误集锦

管理接口访问报错

系统版本 内核版本
Ubuntu 14.04.2 3.13.0-32-generic

我们在这里通过curl来插入命令的时候直接报错:
curl命令写入规则

curl 'http://127.0.0.1:8080/ab_admin?token=zuesx&action=policy_set' -d '{"divtype":"30102","divdata":[{"30102_set":["hsy51234567qc","hsyf1a2c3d4b5"],"upstream":"newhsy"}]}'
2018/10/23 17:44:28 [error] 8738#0: *1090 lua entry thread aborted: runtime error: /opt/nginx/lua_gray/admin/ab_action.lua:5: loop or previous error loading module 'abtesting.utils.utils'  
stack traceback:
coroutine 0:
	[C]: in function 'require'
	/opt/nginx/lua_gray/admin/ab_action.lua:5: in function </opt/nginx/lua_gray/admin/ab_action.lua:1>, client: 127.0.0.1, server: localhost, request: "POST /ab_admin?token=zuesx&action=policy_set HTTP/1.1", host: "127.0.0.1:8080"

上面的报错很明显,又提示进入调用死循环关系或者前期错误当加载'abtesting.utils.utils' 模块的时候,怎么办呢?

  1. 先执行ldconfig,重新加载所有的动态链接库。
  2. 然后重启nginx即可。
    如下所示:
# ldconfig
# supervisorctl
nginx                            RUNNING   pid 8737, uptime 0:10:03
supervisor> restart nginx
nginx: stopped
nginx: started

yield报错

管理接口通过curl(同上)写入规则的时候,报这个错误

attempt to yield across metamethod/C-call boundary

这个的话,我是重新安装了这几步
原版本

  1. lua 5.1
  2. LuaJIT 2.0.2
  3. tengine是2.2.0,

安装后的版本是

  1. lua5.1
  2. LuaJIT 2.0.5
  3. tengine是2.2.0

其实升级的就是LuaJIT而已,主要是安装完LuaJIT后,需要重新编译下tengine,并且我这里使用lua-nginx-module版本是lua-nginx-module-0.10.13

redis连接提示Operation refused

我把ab部署到阿里云后,在阿里云开了一个redis,redis使用的域名连接,然后我在server段的redis配置,把$redis_host的地址设置为了 xxx.aliyun.com,这个域名就是redis连接域名。于是启动nginx+ab,发现在业务流量分流的时候,nginx日志里面总是提示 连接redis失败,所以灰度名单分流也失败,但是发现规则增删改查的接口都没有问题,也就是没有提示任何连接redis失败的原因,我剖析ab的源码,发现都是共用一个redis模块,或者说共用一个redis方法来实现连接的,为什么管理接口的却没有事呢,关键这个Operation refused并没有提示更多有用的信息,于是我把连接redis的那段代码,把err信息全部通过ngx.say这样的方式打印出来,发现完整的报错信息是xxx.aliyuncs.com could not be resolved (5: Operation refused) ,得,这很明显了,是redis域名无法解析出来。

根因找到了,那么就分析为啥会这样的,我仔细查看nginx的配置文件,发现有问题的那个业务配置文件,有一行这样的配置: resolver xxx.xxx.xxx.xxx valid=300s ,然后我又仔细上nginx官网查询了下这个resolver的配置,官网解释请戳这里 , 意思是说这个resolver的配置是表明这个server的所有域名解析都是用这个dns服务器来解析,而redis的域名是阿里云内部的域名,使用刚才配置单的那个dns,根本无法解析,所以才会提示redis连接不上了。

找到为什么会导致无法连接redis的原因后,我们就开始整改了,把resolver去掉或者添加一个阿里云的dns即可。添加完成后重启nginx就可以正常使用ab分流功能了。

redis 读取数据失败,错误信息不详,只显示closed

报错信息如下:

2020/09/08 00:03:15 [error] 5083#0: *617642 [lua] log.lua:28: errlog(): ab_div host [xxx] code : 40101, desc : redis error for closed ,cmd is:*2
$3
get
$54
ab:runtimeInfo:xxx:divsteps
, extrainfo : proxypass to upstream http://xxx, errstack : stack traceback:
        /xxx/nginx/lua_gray/lib/abtesting/error/handler.lua:17: in function </xxx/nginx/lua_gray/lib/abtesting/error/handler.lua:7>
        [C]: in function 'error'
        /xxx/nginx/lua_gray/lib/abtesting/adapter/runtimegroup.lua:114: in function 'getRuntime'
        /xxx/nginx/lua_gray/diversion/diversion.lua:274: in function </xxx/nginx/lua_gray/diversion/diversion.lua:218>
        [C]: in function 'xpcall'
        /xxx/nginx/lua_gray/diversion/diversion.lua:285: in function </xxx/nginx/lua_gray/diversion/diversion.lua:1>, client: 172.16.1.23, server: xxxx, request: "GET /xxx?user_req_id=h5_oFi_Xw58o2DXr4JiuRaW1 HTTP/1.1", host: "xxx"

日志错误很明显,都是从redis读取数据失败,于是重新捋了下abtestingGateway的代码,并未发现异常,返回的错误信息也就是短短的一个词:closed ,至于后面的cmd 内容是我自己把命令补全到错误日志里面的。
我手工拿着 redis 的地址 XXX.aliyun.redis.com 去连接,发现没有异常,可以正常连接,而且,在做灰度分流的时候,灰度名单生效也是时好时坏的。
而且很奇怪的是,线下测试环境跑的好好的lua代码,完全没有任何问题,一旦放在线上,就有问题,对比有关lua、灰度分流的相关配置,唯一不同点就是redis地址。
线下环境的 redis 地址就是 ip,如 1.1.1.1 ,是可以直接访问的,反倒是线上环境的redis地址 是 域名形式,xxx.aliyun.redis.com 这种,怀疑是DNS解析不稳定导致,排查nginx的配置文件,发现nginx配置文件单独配置了dns服务器地址,通过 resolver 1.1.1.1 ; 这种方式配置,于是修改dns地址,改为阿里云内网的dns地址,100.100.2.136 100.100.2.138 ,问题立马解决。

posted @ 2018-10-31 22:26  温柔易淡  阅读(726)  评论(0编辑  收藏  举报