暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

分布式实战:Nginx缓存之流量分发层

TPVLOG 2021-06-21
1738

本文首发于Ressmix个人站点:https://www.tpvlog.com

本章,我将进行Nginx流量分发层的lua代码编写。流量分发层的Nginx服务器,会基于商品id执行流量分发策略:

  1. 获取请求参数productId;

  2. 对productId进行hash运算,将hash值与应用层的Nginx服务器数量取模,获取到一个应用层服务器;

  3. 利用http包发送请求到应用层nginx;

  4. 获取响应后返回。

一、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使用上的坑,也没有一个比较好的调试工具,所以出现错误时有时会很难排查。


文章转载自TPVLOG,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论