Chinaunix首页 | 论坛 | 博客
  • 博客访问: 749862
  • 博文数量: 116
  • 博客积分: 923
  • 博客等级: 准尉
  • 技术积分: 1635
  • 用 户 组: 普通用户
  • 注册时间: 2011-10-06 21:43
个人简介

一直帮老板搬运代码!!!

文章分类
文章存档

2013年(47)

2012年(69)

分类: LINUX

2013-02-21 14:30:47

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 这个就是为了处理内部等待链接过多而设计的!!!


阅读(6099) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~