openresty实现动态服务转发


作者:李林成
推荐理由:该篇文档把openresty请求分发讲解的比较通俗易懂,而且有demo输出,其这篇文章的请求分发有着很高的应用价值。

为什么要用openrest,而没有选择nginx

主要是openresty实现的了,方便操作lua业务处理

openresty是什么

是一个基于nginx与lua的高性能web平台,其内部集成了大量精良的lua库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态web应用、web服务和动态网关。它打包了标准的 Nginx核心,以及很多的常用的第三方模块,以及它们的大多数依赖项。

比如:MySQL、PostgreSQL、Memcached 以及 Redis访问模块。它的主要语言是lua。

openresty特点

开发人员可以使用Lua脚本调动 Nginx 支持的各种 C 以及 Lua 模块,

可以快速构造出足以胜任 10K 以上并发连接响应的超高性能 Web 应用系统。

业务场景:

计量和供销原本都是通过dpp系统平台接口转发。如果出现集团网络网线断掉,或者出现网络波动和dpp服务器出现问题,都会导致所有厂区手持机和供销系统不能用。

因为考虑到app不能直接调两个系统接口。计量系统如果转换供销系统也是很不合理的,原本计量业务就已经很重,如果在转发供销接口。后期维护和扩展就会很困难,而且计量系统本身不适合做接口转换。

所以我们最终讨论在计量系统搭建openresty应用。那么50多家厂区不可能同时在维护每一台openresty应用。所以我们就通过接口转发的时候,把计量ip和供销ip做为参数,通过lua脚本解析参数拿到计量ip和供销ip来指定服务。并进行转发

在openresty解析所遇到的问题:

在请求post请求的时候出现了一直获取不到参数。
Lua接受post请求body过大导致get_post_args()无法获取到参数!

Lua实际问题则是request body大于client_body_buffer_size默认值,导致ngx.req.get.post.args()无法获取到参数。

原因:当post请求bodt size大于client_body_buffer_size默认值8k或者16时,请求报文参数将会被nginx缓存到硬盘当中,此时ngx.req.get_post_args()是无法获取到参数,此时可以通过ngx.req.get_body_data() 或者ngx.req.get_body_file()中获取。获取后的参数是通过unicode编码过的,我们如果要取得原始的值,还需要进行unicode解码。

而且ngx.req.get_post_args()只能在rewrite_by_lua, access_by_lua, content_by_lua*阶段使用,且在使用前需要先调用ngx.req.read_body(),或打开lua_need_request_body 选项强制本模块读取请求体(此方法不推荐)

在openresty使用到了

正则表达式

1.~ 为区分大小写、~* 为不区分大小写匹配、!和!*分别为区分大小写不匹配及不区分大小写不匹配、()匹配包含多个路径、||并且匹配相应的路径入口

2.Set 指令:该指令用于定义一个变量。并给变量赋值这个定义的变量是联合的

3.在使用rewritr_by_lua方法的还是要注意if在rewritr_by_lua之前执行。

4.在set_by_lua模块中read_body是被禁止调用的(failed to run set_by_lua: set_by_lua:6: API disabled in the context of set_by_lua stack traceback: [C]: in function ‘read_body’ set_by_lua:6: in function <set_by_lua:1>)

5.所以我使用rewrite_by_lua,通过rewrite_by_lua把lua文件直接嵌入到nginx.conf文件中

OpenResty:请求处理¥¥接口服务

location ~ /(app-business|smp|saleApp/smp)/ {

   set $userinfo '';

            rewrite_by_lua  '

local request_method = ngx.var.request_method

local cjson = require "cjson";

if request_method == "GET" then

local arg = ngx.req.get_uri_args()

ngx.var.userinfo = arg["supplyIp"]

elseif request_method == "POST" then

ngx.req.read_body()

                    local arg = ngx.req.get_body_data()

ngx.var.userinfo =cjson.decode(arg)["supplyIp"]

end;

if ngx.var.userinfo == nil then

    ngx.var.userinfo = arg["jlIp"]

end;




 if string.sub(ngx.var.userinfo,1,5) ~= "http:" then

ngx.var.userinfo="http://"..ngx.var.userinfo

 end;

         ';

            proxy_pass $userinfo/smp/$request_uri;

}

猜你喜欢

转载自blog.csdn.net/runlion_123/article/details/107057941