轮询
轮询是nginx默认的负载均衡实现方式,此时会将没给请求按时间顺序分配到对应server,如下所示:
upstream balance1{
server 47.104.61.1;#tomcat1所在地址
server 47.104.61.2;#tomcat2所在地址
}
对服务器的请求会按顺序分配到47.104.61.1和47.104.61.2。
这种方式下,如果47.104.61.1挂掉了,没事,47.104.61.2还能提供服务。这个nginx能自动检测出。所谓的双机热备,这就是很好的实现方式。所以对应的架构可为:
权重
上面架构在一些公司就出现问题了,由于历史原因,tomcat1所在服务器性能强大,tomcat2所在服务器性能比较垃圾(内存低、带宽低、响应慢),这样tomcat1其实性能都没发挥出来,tomcat2都快要累死了。
这时候也不着急,配置下轮询权重就是了,如下所示,80%的请求由tomcat1处理,20%tomcat2处理,完美。
upstream balance1{
server 47.104.61.1 weight:8;#tomcat1所在地址
server 47.104.61.2 weight:2;#tomcat2所在地址
}
1
2
3
4
哈希
上面的架构还是有问题啊,如果是需要用户登录之后反复操作的系统,例如商城。
假如用户是在tomat1登录的,然后系统用session保存了登录用户的信息。
结果用户第二个请求发送到了tomcat2,此时悲剧了,tomcat2认为用户没登录。
没关系,nginx已经考了到了这种情况,直接使用哈希策略,此时nginx会自动识别访问者的ip,然后通过哈希算法分配一个固定的服务器给该访问者,所以对同一个用户来说,每次访问都是由一个服务器响应了。
配置如下:
upstream balance1{
ip_hash;#如此简单的配置就能产生重大作用
server 47.104.61.1 weight:8;#tomcat1所在地址
server 47.104.61.2 weight:2;#tomcat2所在地址
}
1
2
3
4
5
后端无状态下负载均衡策略的使用
现在都讲究后端无状态,啥是无状态,简单理解就是后端没有session,用户的请求也不用每次都固定到后端一个服务器上。
那如何来识别用户是否登录呢。
此处举个简单的例子,假设咱们的系统是用户商城。
用户登录成功后,咱们生成一个UUID与用户编号一起存到数据库中,标志着会话开始。
用户在前端拿到UUID后,后续每次请求都携带UUID到达后端。
后端通过拦截器,看看UUID是否合法(数据库中存在且不超时),不合法的请求不响应即可。
当然在现实程序中,这种频繁访问数据的场景放到数据库中速度太慢,对数据库拖累严重。
所以可以放到缓存数据库如redis中,这样速度就大大加快了。
此时负载均衡策略的制定就很自由了,因为nginx重启非常迅速,后端接口又没有状态,我们可以通过监控看各个服务器的负载情况,然后动态的调整权重即可。
当所有服务器都不堪忍受的时候,加服务器,然后重新配置nginx即可,完全不会影响业务正常运作。