On Mon, Apr 2, 2012 at 12:29 AM, FoxBin <fo...@gmail.com> wrote:
> 这几天在研究ngx_lua的模块使用上遇到了一个阻塞问题,
> 我主要实现的功能是做一个api接口,接收到远程的url提交的get信息后根据get信息里面的host,ip,uri,md5信息
> 然后在本地nginx_cache做预加载操作.最后判断cache的信息是否和get_md5的信息一样再打印结果
> 这个功能在php上已经实现.但是想移植到ngx_lua上却遇到了阻塞问题,
> 我这么做是为了尽量不让单跑nginx的设备再安装个php-fpm.直接用ngx_lua模块来代替这个api接口.
> 现在碰到的问题是每次并发几个url过来(都是几KB小文件).nginx就处于等待状态一直没有反映.error debug日志也没信息.strace
> -p跟踪进程没详细信息.包括他的80端口服务也是没响应.
> 希望您有空的时候能指点一下.
> 1.在ngx_lua里面用lua的http和md5模块实现的功能 是否会容易导致阻塞?
使用 md5 模块的阻塞效应一般极小,可以忽略,毕竟是 CPU 计算型的。
直接使用 LuaSocket 的 http 库是使用的阻塞 I/O 方式,应当避免。建议使用 ngx_lua 的
ngx.location.capture 结果 nginx 标准的 ngx_proxy 模块发起 HTTP 请求,或者直接基于
ngx_lua 提供的和 LuaSocket 基本兼容的 cosocket API 编写 HTTP
客户端。这两种方式都是非阻塞的。相关细节可以参见这里:
https://groups.google.com/group/openresty/browse_thread/thread/55a3461e633bbf10
该链接从国内访问可能需要翻墙。
淘宝量子统计就是使用的第一种方式(即 capture API + ngx_proxy)来从 Lua 访问淘宝内部的 HTTP 服务的。
> 2.用ngx_lua去http请求有没有好的解决的办法?
>
见上面。另外,已经有多位同学在编写基于 cosocket 的 lua-resty-http 库了,呵呵。
Regards,
-agentzh
> 这个是我的ngx_lua配置
>
> server {
> server_name _ ;
> listen 10081 default;
>
> location /preload {
> default_type 'text/plain';
>
> content_by_lua '
> local target_ip = string.gsub(ngx.var.arg_target_ip,"(%w+):(%w+)","%1")
> local target_host = ngx.var.arg_target_host
> local target_filename = ngx.var.arg_target_filename
> local target_md5 = ngx.var.arg_target_md5
> --ngx.say("target_ip is: ", target_ip)
> --ngx.say("target_host is: ", target_host)
> --ngx.say("target_filename is: ", target_filename)
> --ngx.say("target_md5 is: ", target_md5)
>
> require("md5")
> local md5 = require("md5")
> local http = require("socket.http")
> local ltn12 = require("ltn12")
> local data={}
> local data2=""
>
> http.request{
> url="http://"..target_ip.."/"..target_filename,
> headers = {["Host"] = target_host},
> sink = ltn12.sink.table(data)
> }
>
> for i=1,#data do
> data2=data2..data[i]
> end
>
> local local_md5 = md5.sumhexa(data2)
>
> if local_md5 == target_md5 then
> ngx.say "success"
>
> else
> http = require("socket.http")
> http.request{
> url="http://"..target_ip.."/purge/"..target_filename,
> headers = {["Host"] = target_host}
> }
> ngx.say "failure"
>
> end
>
> ';
> }
> }
>
P.S. 我同时抄送给了 openresty
邮件组,这样其他用户也可以看到。也欢迎你加入:https://groups.google.com/group/openresty