前言:

   为了避免被勿喷,标题中提到的openresty坑,其实是 resty库使用不当,或者业务逻辑导致的。  我这边的高频接口多使用openresty构建的api,  这次遇到性能上不去的问题。 通过不断的追加的日志和strace系统调用,发现openresty redis没有使用长连接,更没有连接池….  下面是追查长连接问题的思路。


以前写过一篇关于内存泄露的问题,有兴趣可以瞅瞅,  http://xiaorui.cc/?p=4784


resty.redis

redis 命令监控:

追踪openresty工作进程worker的系统调用:

系统调用统计:

openresty的各个worker都未绑定6379的长连接.

resty.http

按照openresty lua-resty-redis模块文档说明,代码中其实使用了长连接的配置。 但事实,当一个协程使用完连接后,没有塞回连接队列.  对的,没有归还连接? 既然没有还回去,其他的请求必然找不到可用的,只能重建新连接。  一开始虽然调用了 redis_conn:set_keepalive 方法,但是没有放对地方,set_keepalive应该放在return前面。。。 也就是说,你每次new的时候,他其实是从全局队列里获取可用的连接.

set_keepalive用法:

错误代码演示:

另外,我们可以通过 redis_conn:get_reused_times 方法获取 该连接被使用的次数,如果为0,我们就把它作为新连接,针对新连接可以做 select db, auth密码认证。 如果不加新连接的判断,你会不停的触发redis_conn.auth, select db操作…  多废了两次网络io…

我简单看了下resty.redis.get_reused_times的实现方法,开辟一个lua_shared_dict,接着针对每个连接做计数。


Openresty里好用的http client也就lua-resty-http了, lua-resty-http 默认实现了连接池。 但因为业务上的需求会再次request第三方的接口,这时候如果第三方的接口处理时间过长,作为调用方的openresty http client 会造成大量的新连接的建立。

虽然这么多在线连接,但对方这么多的连接一点业务数据都没有吐回来,造成了client一直占用该连接,其他人拿不到可用的连接,另外你就算把连接池放大,本地的发起端口也只有理论的65535。

怎么解决? 针对我这个需求, 可以加 timeout 超时 中断请求的。


条件判断

不得不说,还有一个lua条件判断的坑,每次都是豁然惊醒,事后,又再次犯错。。。 在条件判断里,0,空字符 居然为 真 ….

END.



对Python及运维开发感兴趣的朋友可以加QQ群 : 478476595 !!!
{ 2000人qq大群内有各厂大牛,常组织线上分享及沙龙,对高性能及分布式场景感兴趣同学欢迎加入该QQ群 }

另外如果大家觉得文章对你有些作用!   帮忙点击广告. 一来能刺激我写博客的欲望,二来好维护云主机的费用.
如果想赏钱,可以用微信扫描下面的二维码. 另外再次标注博客原地址  xiaorui.cc  ……   感谢!
暂无相关产品

评论已关闭。