首页

    openresty stream-lua-nginx-module尝鲜

    标签:openresty

    最新的openresty(1.13.6.1),stream-lua-nginx-module默认用的是v0.0.3.而stream-lua-nginx-module的作者上月加了一些特性,于是赶紧试一下

    编译安装stream-lua-nginx-module v0.0.5

    可以参见我的Dockerfilecommit

    说明

    • 需要在编译参数中加上--without-stream_lua_module,禁止编译默认的stream-lua-nginx-module版本。docker构建时删除,替换stream-lua-nginx-module无效
    • --add-module=/tmp/stream-lua-nginx-module-0.0.5,使用nginx动态编译模块

    lua_add_variable

    新的stream-lua-nginx-module添加了lua_add_variable指令,使得在stream block中,nginx的内置绑定变量可以通过ngx.var获得

    Add variable $var to the stream subsystem and makes it changeable. If $var already exists, this directive will do nothing.

    ssl preread

    nginx的ngx_stream_ssl_preread_module文档有个根据SNI路由的例子,在map中使用了$ssl_preread_server_name。现在直接ngx.var.ssl_preread_server_name就行了

    stream{
        upstream proxy_backend{
            server 127.0.0.1:9527;
            balancer_by_lua_block{
                local ssl_preread_server_name=ngx.var.ssl_preread_server_name
                ...
            }
        }
    
        server {
            listen 443;
            ssl_preread on;
            proxy_pass proxy_backend;
        }
    }
    

    dynamic route

    balancer_by_lua_*能实现动态路由,lua_add_variable结合preread_by_lua__*一样可以做到

    stream{
        lua_add_variable $route;
        server {
            listen 443;
            #ssl_preread on;
            preread_by_lua_block{
               ngx.var.route='127.0.0.1:9527';
            }
            proxy_pass $route;
        }
    }
    

    注意使用了preread_by_lua_*就不要设置ssl_preread on;了,因为nginx SNI解析成功后,会跳过preread阶段的剩余部分.而preread_by_lua_*总是在preread阶段的最后执行

    The preread_by_lua_block code will always run at the end of the preread processing phase

    可以设置preread_by_lua_no_postpone:on;改变preread_by_lua_*preread阶段的执行时间

    Controls whether or not to disable postponing preread_by_lua* directives to run at the end of the preread processing phase

    无法获取$ssl_preread_server_name

    1.13.6.1中,如果使用了preread_by_lua_*,则无法通过lua获取$ssl_preread_server_name

    stream{
        upstream proxy_backend{
            server 127.0.0.1:9527;
            balancer_by_lua_block{
                --ssl_preread_server_name:nil
                ngx.log(ngx.ERR,ngx.var.ssl_preread_server_name)
            }
        }
        server {
            listen 443;
            proxy_pass proxy_backend;
            preread_by_lua_block{
                --ssl_preread_server_name:nil
                ngx.log(ngx.ERR,ngx.var.ssl_preread_server_name)
            }
        }
    }
    

    这个问题在1.13.6.2中已修复

    feature: added patches to the nginx core to make sure ngx_stream_ssl_preread_module will not skip the rest of the preread phase when SNI server name parsing was successful. thanks Datong Sun for the patch.

    这样修改就好了

    stream{
        upstream proxy_backend{
            server 127.0.0.1:9527;
            balancer_by_lua_block{
                --it works!
                ngx.log(ngx.ERR,ngx.var.ssl_preread_server_name)
            }
        }
        server {
            listen 443;
            ssl_preread on;
            proxy_pass proxy_backend;
            preread_by_lua_block{
                --it works!
                ngx.log(ngx.ERR,ngx.var.ssl_preread_server_name)
            }
        }
    }
    
    • 这里必须要设置ssl_preread on;
    • 设置的ssl_preread on;不会像上面说的,与preread_by_lua_*有冲突,因为在1.13.6.2中,nginx SNI解析成功后,不会跳过preread阶段的剩余部分,preread_by_lua_*会在preread阶段最后执行
    • 不要设置preread_by_lua_no_postpone on;,因为如果设置了,preread_by_lua_*不会在preread阶段最后执行,这时nginx SNI还没解析

    不定期更新