大家都知道nginx是一款负载均衡软件,用于将线上流量均匀分发给后端server集群,通过在 nginx.conf 里配置 upstream,示例如下:
默认采用轮询方式,轮流请求108和109这两台机器的8001端口,其中weight参数可以控制每台机器的权重,权重大的机器请求几率更大。
session粘连
轮询方式基本能满足需求,但有个不足,同一个用户的请求会随机分配到一台backend server,这样会导致一些问题,比如:
用户c第一次发送请求至nginx,nginx收到请求后,分配给108机器,在108机器上完成登录认证,即用户c的session存储在108机器上
用户c第二次请求,nginx分配给109机器,由于109机器没有用户的session数据,认为用户未登录,请求处理失败
这种情况下,要求nginx将同一个用户的请求定向到指定一台机器上,用户c不管请求多少次,只要后端server没有发生变化,都分配到同一台机器上,这个需求用专业术语讲叫“session粘连”。
ip_hash
nginx提供ip_hash指令可实现session粘连需求,根据用户ip计算hash值,从而每次都分配到指定机器上,ip_hash支持配置weight权重。
但是ip_hash也有个不足,要求nginx必须是最前端的机器,即用户不经过其他服务中转,直接请求nginx,这样ip_hash才能生效。如果在nginx和用户中间有别的服务,比如SLB、LVS等负载集群,nginx的ip_hash指令可能会失效。
upstream hash
既然自带的ip_hash指令不好使,那么能不能自己指定一个字段来计算hash值,替代ip值,比如cookie或者request uri里面的一个能标识用户id的字段。
有个第三方的nignx模块nginx_upstream_hash-0.3.1可以实现该效果,该模块提供hash指令,可以指定一个变量用于hash,示例如下:
hash指令后面的变量可以设置为其他有效的nginx变量。
不幸的是,hash指令不支持配置weight权重,如果有需求要设置每台机器的流量比例,怎么办?
这里提供一个蹩脚但很有效的方法,通过添加重复的server实现比例分配,比如 108机器分配20%的流量,109机器分配80%的流量,可以这么配置:
添加1个108机器,4个109机器,即可实现按比例分配的效果,不要笑,真的管用!
如果有更好的实现方法,不吝赐教。
领取专属 10元无门槛券
私享最新 技术干货