nginx+lua实现按参数一致性哈希分发

1 问题在项目中我们用到了多级缓存(caffeine + redis),为了提高localcache的命中率,我们希望某些参数相同的请求能打到同样的机器。1.1 问题分析我们是内部服务,无法使用 ipHash因为请求不一定都带有userId/schoolId/studentcode等参数,需要根据不同url来配置不同hash策略端上/网关没有做统一公参的处理典型的需求case如下表所示:URI入参hash方式/class/class_infoschoolId, cl
摘要由CSDN通过智能技术生成

1 问题

在项目中我们用到了多级缓存(caffeine + redis),为了提高localcache的命中率,我们希望某些参数相同的请求能打到相同的机器

1.1 问题分析

  • 我们是内部服务,无法使用 ipHash
  • 因为请求不一定都带有userId/buildingId/guestCode等参数,需要根据不同url来配置不同hash策略
  • 端上/网关没有做统一公参的处理

典型的需求case如下表所示:

URI 入参 hash方式
/room/room_info buildingId, roomCode, needOwner buildingId + roomCode
/room/guest_list buildingId, roomCode buildingId + roomCode
/guest/last_lesson guestCode guestCode
/owner/virtual_room buildingId,ownerCode buildingId + ownerCode
/lessons_date userId,date userId
/owner_info userId,userIds 不hash
/room/virtual_total vRoomCode 不hash

2 方案探讨

个人想到两种方案:

2.1 应用分发

思路

  • 单起一个应用A,专门来做请求分发。
  • 假设后端应用B有N台服务器,应用B的每台服务器都单独订阅一个消息队列的topic。
  • 应用A收到请求后,根据需求解析参数,一致性hash计算出应该需要应用B的哪台机器来处理,然后将请求发送到对应的topic。
  • 应用B的服务器从对应的topic订阅请求消息并解析处理。

特点

适用场景:快速应答(应用A) + 异步处理复杂逻辑(消息队列 + 应用B)
优点:研发侧方便管控;
缺点:需要单独部署服务;异步处理可能需要在业务侧增加额外状态来表示处理状态

2.2 nginx分发

思路

nginx支持lua扩展,同时也支持一致性hash。可以用lua来解析请求并根据需求判断是一致性hash分发还是轮询分发。默认轮询分发;如果需要一致性hash分发,根据实际需求计算出hashKey,按hashKey分发即可。

特点

优点:适用于大部分场景,无需部署单独服务,对应用无侵入
缺点:lua语法需要适应,nginx性能会略有下降,需要运维侧配合实施
因为每个请求在nginx层都要增加一层逻辑,nginx性能会略有下降;如果不是对nginx吞吐量有特别高的要求,一般问题不大。
需要特别注意nginx版本/nginx各个模块/luajit的兼容性问题。

我们的应用采用nginx分发的方案。

3 环境安装

安装lua

参考:http://www.lua.org/download.html
curl -R -O http://www.lua.org/ftp/lua-5.4.0.tar.gz
tar zxf lua-5.4.0.tar.gz
cd lua-5.4.0
make all test
make install

下载nginx及各种插件
为了避免nginx的兼容性等问题,我们使用openresty版本, openresty自带了lua扩展。
下载openresty: https://openresty.org/en/download.html 。我是用的是 openresty-1.11.2.5 。
下载ngix一致性hash插件: https://github.com/replay/ngx_http_consistent_hash

安装依赖

brew update
brew install pcre openssl curl

安装nginx及插件

./configure --with-cc-opt="-I/usr/local/opt/openssl/include/ -I/usr/local/opt/pcre/include/" --with-ld-opt="-L/usr/local/opt/openssl/lib/ -L/usr/local/opt/pcre/lib/" -j2 --add-module=…/pkgs/ngx_http_consistent_hash-master //(-j2 2为核数)
sudo make -j2
sudo make install

检测是否安装成功:

/usr/local/openresty/nginx/sbin/nginx -V

nginx -V信息展示
默认conf文件位置: /usr/local/openresty/nginx/conf/nginx.conf

我们可以执行下面命令来简化nginx执行:

sudo ln -s /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx

4 nginx常用命令

nginx // 直接输入nginx命令启动
nginx -t //检测是否可以正常启动
nginx -s reload //重启
nginx -s stop //停止nginx进程
nginx -t -c /usr/local/nginx/conf/nginx.conf // 检测指定配置文件语法是否正确

5 代码开发

修改 nginx.conf:

    server {
   
        listen       80;
        server_name  localhost;
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
   
            root   html;
        }

        location / {
   
	        set $hashkey "";
	        set $backendupstream "rrbackend";
	        // lua脚本设置backendupstream和hashkey
            rewrite_by_lua_file '../set_upstream.lua';
            proxy_pass   http://$backendupstream;
        }
    }

    // 轮询
    upstream rrbackend {
   
      // 模拟4台后端服务器
      server 127.0.0.1
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值