2012/8/10 Hui Yu wrote:
> 问题描述:
>
> 目前我正在设计编写一通用的访问Oracle数据库的NGINX插件(handler),由于OCI没有提供异步操作机制,为提高TPS,因此想通过多线程方式解决这一问题,原理如下:
>
> Client -> Nginx -> Queue <- 多线程 -> OCI -> Oracle
>
> Client请求通过NGINX插件,放置在请求队列ReqQue中(放置的数据为:ngx_http_request_t),并且在ngx_http_request_t添加一状态属性以标识该请求的处理状态.proc_status,并置其值为waiting.
>
> 每个Work进程默认开启N个线程异步处理ReqQue队列中的请求,处理完毕后将proc_status置为done
>
> 当NGINX下一次事件来临时,发现proc_status为处理完毕,则返回Client,否则继续等待下一次事件
>
>
> “继续等待下一次事件”在handler中的代码为
> r->read_event_handler = ngx_http_request_empty_handler;
> r->write_event_handler = ngx_http_handler;
> ngx_http_post_request(r, NULL);
> return NGX_AGAIN;
>
> 进行压力测试时发现此种方式,响应时间10多秒,且随着时间的增长,响应时间也会增加,单个请求响应时间最短为0.2秒,最长3秒
>
>
> 请问“继续等待下一次事件”如何实现?,请给予指点,万分感谢!
大约二三年前,chaoslawful 老师曾尝试编写过 ngx_oracle 模块,并且貌似已经得到了一个可以运行的原型?我听
chaoslawful 介绍过 OCI 有提供非阻塞的查询 API,除了创建连接和释放连接的环节,并且提供了一个接口可以暴露底层
socket 的文件描述符,这样我们就可以像 ngx_postgres [1] 和 ngx_drizzle [2]
模块那样把这个文件描述符注册到 nginx 的事件模型中去进行事件监听与调度,并实现 C10K. 当然,必需阻塞的操作需要借助于内部 OS
线程池这样的东西。
我已抄送给 chaoslawful 和 openresty 邮件列表 [3] 。
Best regards,
-agentzh
注:
[1] https://github.com/FRiCKLE/ngx_postgres
[2] http://wiki.nginx.org/HttpDrizzleModule
[3] http://groups.google.com/group/openresty
TAF是需要具备的,看来多线程是眼前比较可行的方案;
现在在查Protothreads库,看其在后期对优化上可有什么帮助?
在 12-8-11,Chaos Wang<chaos...@gmail.com> 写道:
2012/10/9 ganggewudi:
> 很多队列在lua中的使用都是阻塞的,我没找到非阻塞的lua的消息队列,另外,可以支持mysql吗
>
可以看一下 Brian Akins 基于 ngx_lua cosocket 实现的这个 beanstalkd 队列的非阻塞客户端:
https://github.com/bakins/lua-resty-beanstalkd
当然,Redis 也是可以作为队列来使的,此时可以直接使用更为成熟的 lua-resty-redis 库:
https://github.com/agentzh/lua-resty-redis
同时,ngx_lua 支持 mysql 已经有多年了,有的用户通过 ngx.location.capture() 发起子请求访问 ngx_drizzle 模块:
http://wiki.nginx.org/HttpDrizzleModule
还有的用户直接使用 lua-resty-mysql 库:
https://github.com/agentzh/lua-resty-mysql
后者的功能更齐全一些,使用更方便一些。
Best regards,
-agentzh