在 2012年3月16日 下午5:40,Zoom.Quiet <zoom...@gmail.com> 写道:
> 在 2012年3月10日 下午5:16,agentzh <age...@gmail.com> 写道:
>> On Sat, Mar 10, 2012 at 10:40 AM, Zoom.Quiet <zoom...@gmail.com> wrote:
>>> 在 2012年3月10日 上午10:36,lhmwzy <lh...@gmail.com> 写道:
>>> > 尽量不要破坏了openresty本身的非阻塞
>>>
>>> - 应该的,但是怎么避免?
>>> 进一步的:
>>> - 哪些操作是阻塞的?
>>> - 怎么进行非阻塞化?
>>> - 怎么测试真正异步了?
>>> ...
>>> 这都是乱入后,需要直面的问题,,,
>>>
>>
>> 非阻塞访问远方 http 服务有两种做法。下面以从 ngx_lua 中访问百度搜索为例,演示一下这两种做法:
>>
>> 1. 使用 nginx 子请求 + ngx_proxy 模块:
>>
>> resolver 114.114.114.114;
>>
>> location = /baidu {
>> internal;
>> proxy_pass http://www.baidu.com/s?wd=$arg_query;
>> }
>>
>> location = /test {
>> content_by_lua '
>> local res =
>> ngx.location.capture("/baidu", { args = { query =
>> "openresty" }})
>> if res.status ~= 200 then
>> ngx.say("failed to query baidu: ", res.status, ": ",
>> res.body)
>> return
>> end
>> ngx.say(res.body)
>> ';
>> }
>>
>
使用 angentzh 提供的示范,则 error:
no resolver defined to resolve www.baidu.com, client: 127.0.0.1,
server: localhost, request: "POST /=/test HTTP/1.1", subrequest:
"/baidu", host: "localhost:9090"
- 是版本问题?需要俺使用更新的稳定版本 openresty?
> 先尝试使用第一种内部代理:
> - 不断的出错:
> HTTPConnectionPool(host='localhost', port=9090): Max retries exceeded
> with url: /=/pchk
>
> 配置:
> location ~ ^/=/(\w+) {
> content_by_lua_file conf/lua/$1.lua;
> lua_code_cache off;
> }
> ...
> location = /pish {
> internal ;
> proxy_pass http://open.pc120.com/phish/?$arg_query ;
> }
> ...
>
> pchk.lua:
> ...
> local genURL = KSC.genValidUrl(args.uri)
> local res = ngx.location.capture("/pish?" .. genURL)
> if res.status ~= 200 then
> ngx.say("failed to query KSC: ", res.status, ": ", res.body)
> return
> end
> html = res.body
> ngx.say(res.body)
>
> 问题:
> - 如果我可以组合成合法的参数 url 就可以不使用 { args = {}} 模式吧?
> - 不过,这样一来是怎么和 location 配合呢?
> - 比如,俺内部代理的是 http://open.pc120.com/phish/?a=XXX&b=YYY
> - 那俺使用 ngx.location.capture 请求的是
> /phish/?a=XXX&b=YYY
> or
> /phish/a=XXX&b=YYY
> - 这种内部 url 获取处理中,怎么追查是哪里出问题了?
>
> location = /pish/ {
> internal ;
> content_by_lua '
> ngx.say(ngx.req.get_body_data)
> ';
> proxy_pass http://open.pc120.com/phish/?$arg_query ;
> }
> 这样加临时调试代码,也没有输出,,,
>
>
>> 然后请求这里的 /test 接口便可以得到 baidu 里搜索 openresty 查询词时的 HTML 结果页(不过要仔细字符编码哦)。
>>
>> 2. 使用 cosocket API 访问之:
>>
>> resolver 114.114.114.114;
>>
>> location = /test {
>> content_by_lua '
>> local sock = ngx.socket.tcp()
>> sock:settimeout(1000)
>> local ok, err = sock:connect("www.baidu.com", 80)
>> if not ok then
>> ngx.say("failed to connect to baidu: ", err)
>> return
>> end
>> local req = "GET /s?wd=openresty HTTP/1.0\\r\\nHost:
>> www.baidu.com\\r\\n\\r\\n"
>> sock:send(req)
>> local read_headers = sock:receiveuntil("\\r\\n\\r\\n")
>> headers, err = read_headers()
>> if not headers then
>> ngx.say("failed to read response headers: ", err)
>> return
>> end
>> local body, err = sock:receive("*a")
>> if not body then
>> ngx.say("failed to read response body: ", err)
>> return
>> end
>> ngx.say(body)
>> ';
>> }
>>
>> 这里直接用 TCP cosocket API 现写了一个简单的 HTTP 1.0 客户端访问 baidu.com,得到了 openresty
>> 查询词的结果页。当然,未来等有人仿照上面的做法,专门基于 cosocket 实现了完整的 HTTP 客户端库 lua-resty-http
>> 之后,便会更有方便,就像那些已经基于 cosocket 实现的 lua-resty-memcached, lua-resty-redis 和
>> lua-resty-mysql 库一样(见 https://github.com/agentzh/lua-resty-memcached
>> ,还有 https://github.com/agentzh/lua-resty-redis
>> 以及 https://github.com/agentzh/lua-resty-mysql )
>>
>> 以且仅以上面两种方式访问远方服务在 ngx_lua 中才是非阻塞的。
>>
>> Regards,
>> -agentzh
>>
>> --
> 人生苦短, Pythonic! 冗余不做,日子甭过!备份不做,十恶不赦!
> 俺: http://about.me/zoom.quiet
> 文字协议: http://creativecommons.org/licenses/by-sa/2.5/cn/
--
人生苦短, Pythonic! 冗余不做,日子甭过!备份不做,十恶不赦!
俺: http://about.me/zoom.quiet
文字协议: http://creativecommons.org/licenses/by-sa/2.5/cn/