欢迎访问万博易官网

内部链接

nginx 进程内部链接过多的处理方式

发布时间:2020-03-28 06:57

nginx外围链接数的控制是,总连接数的1/8来负载均衡;

但如果很多个进程内处理的连接数超过所有可用链接数,怎么办?
下面就来看nginx对于进程内链接数量满的处理

1、后端服务器
//代理服务器接受完毕后,发送完毕的时候也没有ngx_reusable_connection(c, 1),因为接受后端完毕后,del_conn了。
ngx_reusable_connection(c, 0); fd =10
//什么都没做
c->reusable = reusable;

2、当前端客户端请求
//处理完
ngx_reusable_connection(c, 1);fd =9 //调用下面
ngx_queue_insert_head((ngx_queue_t *) &ngx_cycle->reusable_connections_queue, &c->queue);

//重新请求时
ngx_reusable_connection(c, 0);fd =9 //调用下面
 if (c->reusable) {
    ngx_queue_remove(&c->queue);
}

//处理完
ngx_reusable_connection(c, 1);fd =9 //调用下面
ngx_queue_insert_head((ngx_queue_t *) &ngx_cycle->reusable_connections_queue, &c->queue);

//到时间时:会调用 ngx_http_keepalive_handler
ngx_close_connection(ngx_connection_t *c)
ngx_reusable_connection(c, 0);fd =9 //调用下面
if (c->reusable) {
    ngx_queue_remove(&c->queue);
}

总结以上:
1)、反向代理不用处理请求数过多问题。
2)、每一次处理完客户端请求后,都要把对应的链接池(connection)放到一个池的队列里面(c->queue)的头部;
   重新请求也一样,只有在等待超时的时候,从队列中删除。

3、这个队列c->queue的控制

这个队列是在ngx_drain_connections里面,调用的。而这个ngx_drain_connections 在这个ngx_get_connection里面调用。

1)、ngx_get_connection函数的部分代码
//获取链接的内容
ngx_connection_t * ngx_get_connection(ngx_socket_t s, ngx_log_t *log)

c = ngx_cycle->free_connections; //释放的链接

if (c == NULL) {
ngx_drain_connections();
c = ngx_cycle->free_connections;
}

if (c == NULL) {
ngx_log_error(NGX_LOG_ALERT, log, 0,"%ui worker_connections are not enough",ngx_cycle->connection_n);

/* ngx_mutex_unlock */

return NULL;
}

说明:只有在if (c == NULL) 的时候,也就是没有可用链接的时候调用ngx_drain_connections()函数,然后再次去获取链接,如果为null那么就返回了。

2)、ngx_drain_connections函数的代码

//从队列里面读取信息
ngx_cycle->reusable_connections_queue 这个在这里调用的

static void ngx_drain_connections(void)
{
    ngx_int_t          i;
    ngx_queue_t       *q;
    ngx_connection_t  *c;

    for (i = 0; i < 32; i++) {
        if (ngx_queue_empty(&ngx_cycle->reusable_connections_queue)) {//判断是否为空
            break;
        }

        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");

        c->close = 1;
        c->read->handler(c->read); //读取处理 会调用ngx_http_keepalive_handler
    }
}

说明:这个函数,会找出最后32个中在链接的队列,然后对他们的读进行处理;然而默认处理会调用ngx_http_keepalive_handler,
当ngx_http_keepalive_handler函数调用读recv时,如果为n=0那么,它会认为客户链接可以关闭了(超时也是这样处理的)。

3)、ngx_http_keepalive_handler函数里的ngx_free_connection部分代码
//删除其他并释放链接
ngx_free_connection(ngx_connection_t *c)
{
    /* ngx_mutex_lock */
    c->data = ngx_cycle->free_connections;
    ngx_cycle->free_connections = c;
    ngx_cycle->free_connection_n++;

说明:它会在删除后,把链接给ngx_cycle->free_connections;从而
if (c == NULL) {
ngx_drain_connections();
c = ngx_cycle->free_connections;
}
中的C就有数据了。链接也就可以继续进行接收了!!!

总结:
c->queue 这个就是为了处理内部等待链接过多而设计的!!!


TAG标签:内部(16)处理(19)方式(7)nginx(1)进程(1)接过(1)多的(1)

上一篇:上一篇:中国内部审计协会

下一篇:下一篇:为什么const意味着C ++中的内部链接,当它不在C中时?