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 这个就是为了处理内部等待链接过多而设计的!!!
阅读(6193) | 评论(0) | 转发(0) |