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

[经验分享] nginx keepalive连接回收机制

[复制链接]

尚未签到

发表于 2016-12-25 08:10:17 | 显示全部楼层 |阅读模式
我在nginx 1.0.12代码中发现了名为ngx_reusable_connection的函数(它是在哪个版本里被加上的就不去追究了),很好奇这个函数是做什么的。后来有一次在我的群里讨论nginx的时候,有人发现了一个奇怪的现象,这位同学报告说:并发量大的时候,一些keepalive的连接会被新连接给挤掉。。。




   关于这个问题,切入点在ngx_get_connection,并发足够大时,使连接池迅速耗尽,从代码角度上看:



    c = ngx_cycle->free_connections;
// 此时连接池已用尽
if (c == NULL) {
ngx_drain_connections(); // 将一些keepalive连接给释放掉
c = ngx_cycle->free_connections;
}
  这里出现了这样一个函数:ngx_drain_connections。

  static void
ngx_drain_connections(void)
{
ngx_int_t          i;
ngx_queue_t       *q;
ngx_connection_t  *c;
// 清理32个keepalive连接,以回收一些连接池供新连接使用
for (i = 0; i < 32; i++) {
if (ngx_queue_empty(&ngx_cycle->reusable_connections_queue)) {
break;
}
// reusable连接队列是从头插入的,意味着越靠近队列尾部的连接,空闲未被
// 使用的时间就越长,这种情况下,优先回收它,类似LRU
q = ngx_queue_last(&ngx_cycle->reusable_connections_queue);
c = ngx_queue_data(q, ngx_connection_t, queue);
ngx_log_debug0(NGX_LOG_DEBUG_CORE, c->log, 0,
"reusing connection");
// 这里的handler是ngx_http_keepalive_handler,这函数里,由于close被置1,
// 所以会执行ngx_http_close_connection来释放连接,这样也就发生了keepalive
// 连接被强制断掉的现象了。
c->close = 1;
c->read->handler(c->read);
}
}
  
   那么上面提到的reusable连接队列是如何建立的呢?这个比较简单,这里大体说一下:

在ngx_http_set_keepalive函数处理的最后阶段,会以第二个为1的形式调用ngx_reusable_connection函数。

而在ngx_http_keepalive_handler函数中会以参数0,来调用ngx_reusable_connection。



void
ngx_reusable_connection(ngx_connection_t *c, ngx_uint_t reusable)
{
// 一旦一个keepalive的连接正常处理了,就将其从reusable队列中移除
if (c->reusable) {
ngx_queue_remove(&c->queue);
}
// 在ngx_http_set_keepalive中会将reusable置为1,reusable为1的直接效果
// 就是将该连接插到reusable_connections_queue中
c->reusable = reusable;
// 当reusable为0时,意味着该keepalive被正常的处理掉了,不应该被再次添加
// 到reusable队列中了。
if (reusable) {
/* need cast as ngx_cycle is volatile */
// 这里使用头插法,较新的连接靠近头部,时间越久未被处理的连接越靠尾
ngx_queue_insert_head(
(ngx_queue_t *) &ngx_cycle->reusable_connections_queue, &c->queue);
}
}
  
   从高性能服务器的角度来说,nginx这样做也有它的合理之处,如果一个keepalive连接长时间不交互数据,而新连接到来又拿不到连接,处理这些占着坑不XX的家伙也是无奈之举,当然擅自drain掉连接始终是不对的,这里就得做权衡了,毕竟鱼和熊掌不能兼得。

运维网声明 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.iyunv.com/thread-318954-1-1.html 上篇帖子: nginx upstream 调度策略 下篇帖子: nginx working with header
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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