##请求分发详解
配置负载均衡服务器集群
upstream backend {
server x.x.x.x:1023;
server x.x.x.x:1024;
server x.x.x.x:1025;
}
对特定请求进行分发
server {
listen 1111;
server_name www.siguoya.name;
location / {
proxy_pass http://backend;
}
}
nginx负载均衡在分发请求的时候,默认会采用轮询的方式。即:
请求顺序 | 请求分发 |
---|---|
第一次访问:http://www.siguoya.name:1111/ | x.x.x.x:1023 |
第二次访问:http://www.siguoya.name:1111/ | x.x.x.x:1024 |
第三次访问:http://www.siguoya.name:1111/ | x.x.x.x:1025 |
假如Nginx本来要将请求分发到 x.x.x.x:1024 这台服务器的,结果这台服务器挂掉了,那么Nginx就会将此次请求再分发到x.x.x.x:1025,避免影响到用户访问。
Nginx负载均衡判断后端服务器挂了的依据:
- 首先,Nginx默认检测后端服务的方式是基于通信的,如:连接超时或者后端服务refuse都会标记为服务有问题。
- 然后,如果Nginx需要做到基于状态码来判断,大家可以了解下这个模块
proxy_next_upstream
,可以对后端响应404、502、503、504、500等状态码进行备用处理。 - 最后,如果还想要更好的完善后端的检测机制,需要通过第三方模块来做了,
ngx_http_upstream_check_module
如果我们想要测试某个服务器down掉,负载均衡会怎样处理,可以登录到特定的后端服务器,执行如下命令,假装该服务器已经down掉:
iptables -A INPUT -p tcp --dport 1024 -j DROP
服务器配置详解
upstream backend {
#down表示当前的服务器暂时不可用,不参与负载均衡
server www.aaa.com down;
#max_conns=100表示此服务器的最大连接数为100
server www.bbb.com:1234 max_conns=100;
#weight表示权重,权重越大,被分配到的次数就越多
server www.ccc.com weight=3;
#backup表示这是预留的备份服务器,只在其他的节点都不可用的时候才启用
server www.ddd.com backup;
#max_fails在连续超过3次失败后,30秒内不要再分发请求到此服务器,默认fail_timeout为10秒
server x.x.x.x:8080 max_fails=3 fail_timeout=30s;
}
服务器调度详解
方式 | 说明 |
---|---|
轮询 | 按时间顺序逐一分配 |
加权轮询 | 权重值越大,被分配到的次数就越多 |
ip_hash | 请求按访问IP的hash结果来分配,同一个IP固定的访问某台后端服务器 |
least_conn | 哪台服务器连接数少,就分发给哪台服务器 |
url_hash | 按照访问URL的hash结果来分配,同一URL固定的访问某台后端服务器 |
hash关键数值 | hash自定义的key |
经过实际测试,ip_hash并不能完全保持cookies的连续性,最好还是将cookies存放在redis等内存型数据库中
upstream heartide {
ip_hash;
server x.x.x.x:1023;
server x.x.x.x:1024;
server x.x.x.x:1025;
}
后端服务器定位
可以通过如下方法,定位负载均衡到底将请求分配给了哪台服务器,这有助于我们针对后端集群中特定的某台服务器进行调试。
add_header Backend-Server $upstream_addr;
负载均衡服务搭建注意事项
- 采购后端集群服务器时,最好都是购买同一地区的,例如阿里云华南A区,免得跨区域,无法直连Redis、RDS等
- 检查后端集群服务器的镜像源,
nginx.conf
中的worker_processes
、php.ini
中的pm
参数等是否设置为auto
。如果都是auto
,则可以买不同配置的服务器。如果不是,则需要修改相关配置文件,避免性能参数设置与机器硬件不相匹配 - 检查后端集群服务器的IP,是否全都放进了RDS、Redis、微信公众平台等各种服务的白名单。有条件的公司,可以通过阿里云
专有网络+EIP+NAT
的解决方案,统一后端集群服务器的出口IP - 后端集群服务器的各种日志文件,尽量放到阿里云的
OSS
中,便于统一存储、分析 - 如果需要保持用户访问的连续性,例如 cookies、用户上传的文件,这些数据都务必要存放到
Redis
、OSS
等位置进行集中存储 - 如果基于PHP之Laravel框架来开发,后端集群服务器的镜像源尽量不要配置涉及具体业务代码的任务调度,不然会导致代码在不同机器间的重复执行,例如定时将Redis数据写入到RDS数据库中
参考文档
- 使用阿里云发布分布式网站,开发时候应该注意什么? https://www.opengps.cn/Blog/View.aspx?id=238
- 阿里云ECS,使用VPC网络统一集群网络出口 https://www.jianshu.com/p/8045997f4345
- 阿里云弹性伸缩 https://essnew.console.aliyun.com/?spm=5176.2020520101.aliyun_sidebar.18.5b414df5jzpzAE#/ess/region/cn-beijing
- 如何选择公网类产品? https://help.aliyun.com/document_detail/53402.html?spm=a2c4g.11186623.2.17.56cb114fudHUpO#concept-d5j-5p5-sdb
- 关于access token 后端分布式部署的中控服务器的问题 https://github.com/overtrue/wechat/issues/947