[开发技巧]利用openresty来优化php-fpm的长轮询
Posted PHP技术大全
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[开发技巧]利用openresty来优化php-fpm的长轮询相关的知识,希望对你有一定的参考价值。
对于长轮询场景是比较常见的,客户端同步的不断的在同步请求,而服务端根据请求来决定是否响应或者hold请求以继续检查数据.
由于php-fpm是单进程单线程的,一个进程同时只能处理一个请求,所以对于这种长轮询的场景,需要启动特别多的php-fpm进程来应对高的并发,这是特别浪费资源的,因为大部分请求都是hold在服务器上。
现在我们用openresty来轮询php-fpm,php-fpm会很快的处理完成,不会hold住,减少了php-fpm的压力,配置文件如下:
location ~ /longpolling(/.*) { content_by_lua_block { local request_uri_without_args = ngx.re.sub(ngx.var.request_uri, "\\?.*", "") request_uri_without_args = ngx.re.gsub(request_uri_without_args,"/longpolling","") local url = {request_uri_without_args} local args = ngx.req.get_uri_args() local query = ngx.encode_args(args) if query ~= "" then url[#url + 1] = "?" url[#url + 1] = query end url = table.concat(url) for i = 1, 3 do local sleep = 1 local res = ngx.location.capture(url) for k, v in pairs(res.header) do if type(v) == "table" then if k == 'sleep' and v == 0 then ngx.header[k] = table.concat(v, ",") sleep = table.concat(v, ",") end else if k == "sleep" and v == "0" then ngx.header[k] = v sleep = v end end end if sleep == 1 then ngx.sleep(1) else ngx.say(res.body) break end end } }
将url中以”longpolling”开始的请求转换为长轮询.比如:/longpolling/aa 实际访问是/aa. 长轮询总共时间是3秒,每次停止一秒,根据php-fpm响应头sleep来决定是否输出还是继续轮询.PHP代码如下.
<?php header('Content-type: application/json');$time = $_GET["time"];$data = get_new_data($time);if ( $data ){ header('sleep:0'); echo json_encode(array("data"=>$data));}else{ echo json_encode(array("data"=>""));}
这样我们就做了一个相对通用的仅支持get请求的优化接口。
微信扫描二维码,关注PHP技术大全!
让知识地带无限蔓延!
以上是关于[开发技巧]利用openresty来优化php-fpm的长轮询的主要内容,如果未能解决你的问题,请参考以下文章
张超:又拍云 OpenResty / Nginx 服务优化实践