Nginx | nginx 负载均衡的两种方式

一、sticky 法 [点击下载命名后的源码包]

  Stickynginx的一个模块,它是基于cookie的一种nginx的负载均衡解决方案,通过分发和识别cookie,来使同一个客户端的请求落在同一台服务器上,默认标识名为route

  1. 客户端首次发起访问请求,nginx接收后,发现请求头没有cookie,则以轮询方式将请求分发给后端服务器。
  2. 后端服务器处理完请求,将响应数据返回给nginx
  3. 此时nginx生成带routecookie,返回给客户端。route的值与后端服务器对应,可能是明文,也可能是md5、sha1Hash
  4. 客户端接收请求,并保存带routecookie
  5. 当客户端下一次发送请求时,会带上routenginx根据接收到的cookie中的route值,转发给对应的后端服务器。
1. 官方说明地址

   nginx-sticky-module-ng 官网 https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/src/master/

Installation
  You’ll need to re-compile Nginx from source to include this module. Modify your compile of Nginx by adding the following directive (modified to suit your path of course):

./configure ... --add-module=/absolute/path/to/nginx-sticky-module-ng
make
make install

Usage

upstream {
  sticky;
  server 127.0.0.1:9000;
  server 127.0.0.1:9001;
  server 127.0.0.1:9002;
}
2. 官方下载地址

   nginx-sticky-module-ng 官网 https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/downloads/

3. sticky 编译引入的方法
  • 下载软件包
wget https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/get/master.tar.gz
或者
wget https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/get/08a395c66e42.zip

在这里插入图片描述
-解压并重命名软件包

tar -zxvf master.tar.gz
mv nginx-goodies-nginx-sticky-module-ng-08a395c66e42 /usr/local/sticky-module
  • 编译时的引用
./configure --prefix=/usr/local/nginx \
--add-module=/usr/local/sticky-module \
--with-http_ssl_module
4. sticky 配置引入的方法
###使用方法
upstream {
  sticky;
  server 127.0.0.1:9000;
  server 127.0.0.1:9001;
  server 127.0.0.1:9002;
}
###参数说明
sticky [name=route] [domain=.foo.bar] [path=/] [expires=1h] 
       [hash=index|md5|sha1] [no_fallback] [secure] [httponly];
[name=route]       设置用来记录会话的cookie名称
[domain=.foo.bar]    设置cookie作用的域名
[path=/]          设置cookie作用的URL路径,默认根目录
[expires=1h]        设置cookie的生存期,默认不设置,浏览器关闭即失效,需要是大于1秒的值
[hash=index|md5|sha1]   设置cookie中服务器的标识是用明文还是使用md5值,默认使用md5
[no_fallback]       设置该项,当sticky的后端机器挂了以后,nginx返回502 (Bad Gateway or Proxy Error) ,而不转发到其他服务器,不建议设置
[secure]          设置启用安全的cookie,需要HTTPS支持
[httponly]         允许cookie不通过JS泄漏,没用过
###其他参数
session_sticky [cookie=name] [domain=your_domain] [path=your_path] [maxage=time][mode=insert|rewrite|prefix] 
         [option=indirect] [maxidle=time] [maxlife=time] [fallback=on|off] [hash=plain|md5]

mode设置cookie的模式:
  insert: 在回复中本模块通过Set-Cookie头直接插入相应名称的cookie。
  prefix: 不会生成新的cookie,但会在响应的cookie值前面加上特定的前缀,当浏览器带着这个有特定标识的cookie再次请求时,模块在传给后端服务前先删除加入的前缀,后端服务拿到的还是原来的cookie值,这些动作对后端透明。如:”Cookie: NAME=SRV~VALUE”。
  rewrite: 使用服务端标识覆盖后端设置的用于session sticky的cookie。如果后端服务在响应头中没有设置该cookie,则认为该请求不需要进行session sticky,使用这种模式,后端服务可以控制哪些请求需要sesstion sticky,哪些请求不需要。
option设置用于session sticky的cookie的选项,可设置成indirect或direct。indirect不会将session sticky的cookie传送给后端服务,该cookie对后端应用完全透明。direct则与indirect相反。
maxidle设置session cookie的最长空闲的超时时间
maxlife设置session cookie的最长生存期
maxage是cookie的生存期。不设置时,浏览器或App关闭后就失效。下次启动时,又会随机分配后端服务器。所以如果希望该客户端的请求长期落在同一台后端服务器上,可以设置maxage。
hash不论是明文还是hash值,都有固定的数目。因为hash是server的标识,所以有多少个server,就有等同数量的hash值。
5. 注意事项
1.同一客户端的请求,有可能落在不同的后端服务器上
如果客户端启动时同时发起多个请求。由于这些请求都没带cookie,所以服务器会随机选择后端服务器,返回不同的cookie。当这些请求中的最后一个请求返回时,客户端的cookie才会稳定下来,值以最后返回的cookie为准。
2.cookie不一定生效
由于cookie最初由服务器端下发,如果客户端禁用cookie,则cookie不会生效。
3.客户端可能不带cookie
Android客户端发送请求时,一般不会带上所有的cookie,需要明确指定哪些cookie会带上。如果希望用sticky做负载均衡,请对Android开发说加上cookie。
4.cookie名称不要和业务使用的cookie重名。Sticky默认的cookie名称是route,可以改成任何值。
5.客户端发的第一个请求是不带cookie的。服务器下发的cookie,在客户端下一次请求时才能生效。
6.Nginx sticky模块不能与ip_hash同时使用

二、ip_hash 法 [点击下载修改后的源码包]

1.使用原理

  ip_hash 使用源IP地址哈希算法,通过客户端请求ip进行hash,再通过hash值选择后端server。当你服务端的一个特定url路径会被同一个用户连续访问时,如果负载均衡策略还是轮询的话,那该用户的多次访问会被打到各台服务器上,这显然并不高效(会建立多次http链接等问题)。甚至考虑一种极端情况,用户需要分片上传文件到服务器下,然后再由服务器将分片合并,这时如果用户的请求到达了不同的服务器,那么分片将存储于不同的服务器目录中,导致无法将分片合并。所以,此类场景可以考虑采用nginx提供的ip_hash策略。既能满足每个用户请求到同一台服务器,又能满足不同用户之间负载均衡。

2.常见问题

  网上有很多相关的教程,但是配置后你确定你的负载均衡时有效的吗?你配置过负载均衡后,有去查看 tomcat 服务器的日志是轮询的吗?
  其实配置ip_hash后,是后话保持了,但是可能出现只分发到一台服务器的情况,这是因为在源码中需要调整而未调整。
  ip_hash是使用ip地址的前三段进行hash运算,根据结果的不同,重定向到不同的服务器上。我们的电脑都在同一个局域网(即192.168.0.*,前面的网络号是一样的),所以算出的hashcode都是一样的,所以没有负载分担的效果。

3.解决方案

  修改nginx的源代码后,重新编译安装,就能实现根据ip地址来区分重定向的目的。

  1. 找到nginx压缩包,进行解压;
  2. 进入nginx目录下的src/http/modules/ngx_http_upstream_ip_hash_module.c文件;
  3. 如图所示,找到180多行,根据循环里的i值引用处,将3次改成4次(总共三处)。
  4. 重新编译后,果然生效了,就可以根据ip的不同进行负载分担了。
vim src/http/modules/ngx_http_upstream_ip_hash_module.c

在这里插入图片描述

在这里插入图片描述
第一处,124行,由“3”修改为“4"

4.效果缺点
  1. 当后端服务器宕机后,session会丢失;
  2. 来自同一局域网的客户端会被转发到同一个后端服务器,可能导致负载失衡;
  3. 不适用于CDN网络,不适用于前段还有代理的情况。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值