
本文首发于Ressmix个人站点:https://www.tpvlog.com
本章,我将进行Nginx流量分发层的lua代码编写。流量分发层的Nginx服务器,会基于商品id执行流量分发策略:
获取请求参数productId;
对productId进行hash运算,将hash值与应用层的Nginx服务器数量取模,获取到一个应用层服务器;
利用http包发送请求到应用层nginx;
获取响应后返回。
一、OpenResty配置
我们需要对OpenResty做一些额外配置,引入依赖的工具包。我们目前的项目目录结构如下:
1/www
2 /conf
3 nginx.conf
4 /logs
5 /lua
6 main.lua
7 /lualib
首先修改nginx.conf
配置如下:
1worker_processes 1;
2error_log logs/error.log;
3events {
4 worker_connections 1024;
5}
6http {
7 lua_package_path "$prefix/lualib/?.lua;;";
8 lua_package_cpath "$prefix/lualib/?.so;;";
9 server {
10 listen 80;
11 location /product {
12 default_type text/html;
13 content_by_lua_file lua/main.lua;
14 }
15 }
16}
上面的$prefix
是指我们启动openresty时代入的-p
参数。然后,我们需要将一些官方或第三方的lua库放到lualib
目录下,比如我们可以直接将openresty默认安装包下的lualib直接复制到我们自己的项目的lualib中。
然后,在我们项目中的lualib/resty
目录下,执行以下命令,安装http库:
1cd /usr/local/www/lualib/resty/
2wget https://github.com/ledgetech/lua-resty-http/blob/master/lib/resty/http.lua
3wget https://github.com/ledgetech/lua-resty-http/blob/master/lib/resty/http_headers.lua
二、功能实现
接着,我们就要在ressmix-dsf01上的main.lua
中实现流量分发逻辑了,我们直接根据请求URI中的productId进行哈希:
1--获取http请求中的uri参数
2local uri_args = ngx.req.get_uri_args()
3local productId = uri_args["productId"]
4local shopId = uri_args["shopId"]
5
6--确定路由到那台应用层Nginx服务器
7local host = {"192.168.0.109", "192.168.0.110"}
8local hash = ngx.crc32_long(productId)
9
10hash = (hash % 2) + 1
11backend = "http://"..host[hash]
12
13local requestBody = "/product?productId="..productId.."&shopId="..shopId
14
15local http = require("resty.http")
16local httpc = http.new()
17
18--发起请求
19local resp, err = httpc:request_uri(backend, {
20 method = "GET",
21 path = requestBody
22})
23
24if not resp then
25 ngx.say("request error :", err)
26 return
27end
28
29--响应
30ngx.say(resp.body)
31
32httpc:close()
最后,分别启动ressmix-dsf01、ressmix-dsf02、ressmix-dsf03上的openresty:
1openresty -p /usr/local/www -c /usr/local/www/conf/nginx.conf
然后在ressmix-dsf01上发起两笔请求测试下:
1[root@ressmix-dsf01 lua]# curl -i http://192.168.0.107/product?productId=117&shopId=123
2HTTP/1.1 200 OK
3Server: openresty/1.15.8.3
4Date: Wed, 03 Jun 2020 19:25:55 GMT
5Content-Type: text/html
6Transfer-Encoding: chunked
7Connection: keep-alive
8
9http://192.168.0.107/product?productId=117&shopId=123
10<p>hello, world,ressmix-dsf02</p>
1[root@ressmix-dsf01 lua]# curl -i http://192.168.0.107/product?productId=112&shopId=123
2HTTP/1.1 200 OK
3Server: openresty/1.15.8.3
4Date: Wed, 03 Jun 2020 19:26:26 GMT
5Content-Type: text/html
6Transfer-Encoding: chunked
7Connection: keep-alive
8
9http://192.168.0.107/product?productId=112&shopId=123
10<p>hello, world,ressmix-dsf03</p>
可以看到,ressmix-dsf01上的OpenResty流量分发层已经能够根据productId将请求分发到应用层了。
三、总结
本章,我通过lua脚本脚本实现了Nginx流量分发层的分发逻辑,核心是利用了OpenResty的http包,读者在使用OpenResty时需要多参考官方的文档,因为OpenResty有很多API使用上的坑,也没有一个比较好的调试工具,所以出现错误时有时会很难排查。




