nginx耗时模块的不阻塞主事件循环的异步处理机制

发布: 2012-11-29 13:58

1) 在模块中生成线程池,把nginx的请求交给线程序池来处理

不过,需要在模块的handler中把r->main->count++,并且返回一个NGX_DONE,

这个值必须+1,否则在handler返回后,连接会被nginx断掉。

2)使用upstream机制,把耗时请求放在backend进程处理,把nginx当一个连接池使用

这种方式稍微复杂,不是单单nginx模块的问题,实际是开发一个独立的fastcgi进程或者其他协议服务进程,

通过upstream访问后端。

线程池模式示例代码:

static ngx_int_t ngx_http_nullimp_handler(ngx_http_request_t *r)
{
r->main->count += 1;
pthread_t pth;
int pcr;
pcr = pthread_create(&pth, NULL, test_thread_proc, (void*)r);

return NGX_OK;
}

static void *imp_thread_proc(void *arg)
{
ngx_int_t rc;
ngx_buf_t *b, pb;
ngx_chain_t out;



// do something long time logic

sleep(3);

// ..........

// ..........

rc = ngx_http_send_header(r);

rc = ngx_http_output_filter(r, &out);

pthread_mutex_lock(&g_mutex);
ngx_http_finalize_request(r, NGX_DONE);
pthread_mutex_unlock(&g_mutex);

}

注意,ngx_http_finalize_request第二个参数表示请求处理结果,一般为NGX_DONE表示成功。

每调用一次这个函数,相当于r->main->count--

由于使用了多线程方式,需要使用mutex保证函数执行的原子性。

这里的示例是不断创建新线程的方式实现,也可以用创建线程池,任务队列的方式实现。



原文: http://qtchina.tk/?q=node/699

Powered by zexport