Sky26

one request and all worker accept

This project is maintained by wangfakang

nginx单个请求让多个worker同时接受处理:

有个开源的patchper-worker-listener,这个patch可以使得每一个worker进程都可以进行监听端口;

其实单个请求多个worker同时执行,可以使用子请求(ngx.location.capture)+反向代理(proxy_pass)来做(目前来看是最简单的一种方式);

简单列子:

worker_processess auto;

events {
    worker_connections  1024;
    accept_mutex off; #importent
}


http {

    server {
        listen 80;
        listen       8010 per_worker; #importent
        server_name  localhost;

        #ngx.location.capture只可以内部location跳转
        location /muti {
           content_by_lua '  
             local host = "127.0.0.1"
             local port = 8010
             local count = ngx.worker.count()
             for i = 1 , count  do
                 local res = ngx.location.capture("/internal?" .. "host=" .. host .. "&port=" .. port)
                 if res then
                     ngx.say("status: ", res.status)
                     ngx.say("body:")
                     ngx.print(res.body)
                 end
                 port = port + 1
            end
         ';
        }

        #利用proxy_pass进行发送http请求
        location /internal {
            proxy_pass http://$arg_host:$arg_port/showinfo;
        }

        #每个worker将会执行此location
        location /showinfo {
            content_by_lua '
                ngx.say("pid: " .. ngx.var.pid .. ", port: " .. ngx.var.server_port .. "\t")
           ';
        }

    }
}

请求:
curl localhost:80/muti

将会输出:

status: 200
body:
pid: 4785, port: 8010    
status: 200
body:
pid: 4786, port: 8011   
status: 200
body:
pid: 4787, port: 8012   
status: 200
body:
pid: 4788, port: 8013   

从输出结果可以看到nginx的4个worker都执行了这个请求;

其实此时就可以利用这个机制进行nginx内部worker之间的通信(其实nginx内部是通过channel实现的worker之间的通信) 其实也可以利用这个机制实现nginx集群的通信;



               M1                      M2

          w1   w2   w3           w1    w2    w3

                     nginx cluester

如上图所示,其中M1与M2是nginx cluster中的两个节点,M1与M2之间的worker之间可以使用http进行通讯;

欢迎一起交流学习

在使用中有任何问题,欢迎反馈给我,可以用以下联系方式跟我交流

Thx

Author