用openresty实现动态upstream反向代理

前言

此文的读者定义为对openresty有一定了解的读者。

openresty:
https://github.com/openresty/lua-nginx-module

此文要讲什么

大家都知道openresty可以用ngx.location.capture和ngx.exec来实现内部跳转,
下面要讲怎么将ngx.location.capture和ngx.exec与upstream模块结合起来,实现一个动态的upstream。

下面的演示中:

80端口表示首次请求入口
8080端口表示upstream的出口

直接上配置和源码

配置: conf/nginx.conf

    worker_processes  1;  
    error_log logs/error.log;  
    events {  
        worker_connections 1024;  
    }  

    http {  

        log_format  main  '$msec $status $request $request_time '  
                          '$http_referer $remote_addr [ $time_local ] '  
                          '$upstream_response_time $host $bytes_sent '  
                          '$request_length $upstream_addr';  

        access_log  logs/access.log main buffer=32k flush=1s;  


        upstream remote_hello {  
            server 127.0.0.1:8080;  
        }  

        upstream remote_world {  
            server 127.0.0.1:8080;  
        }  

        server {  
            listen 80;  

            location /capture {  
                content_by_lua '  
                    local test = require "lua.test"  
                    test.capture_test()  
                ';  
            }  

            location /exec {  
                content_by_lua '  
                    local test = require "lua.test"  
                    test.exec_test()  
                ';  
            }  

            location /upstream {  
                internal;  

                set $my_upstream $my_upstream;  
                set $my_uri $my_uri;  
                proxy_pass http://$my_upstream$my_uri;  
            }  
        }  


        server {  
            listen 8080;  
            location /hello {  
                echo "hello";  
            }  

            location /world {  
                echo "world";  
            }  
        }  
    }  

源码: lua/test.lua

    local _M = { _VERSION = '1.0' }  

    function _M:capture_test()  
        local res = ngx.location.capture("/upstream",  
            {  
                 method = ngx.HTTP_GET,  
                 vars = {  
                     my_upstream = "remote_hello",  
                     my_uri = "/hello",  
                 },  
            }  
        )  
        if res == nil or res.status ~= ngx.HTTP_OK then  
            ngx.say("capture failed")  
            return  
        end  
        ngx.print(res.body)  
    end  

    function _M:exec_test()  
        ngx.var.my_upstream = "remote_world"  
        ngx.var.my_uri = "/world"  
        ngx.exec("/upstream")  
    end  

    return _M  

运行效果

标签:Openresty 发布于:2019-11-17 16:18:12