Nginx负载均衡
# 负载均衡相关概念
# 集群
- 完成相同任务或工作的一组服务器,例如WEB服务集群:web01、web02、web03。
- 相较于一台高性能服务器来说,它的特点有:
- 高性能,多台服务器集群在一起可以提供更高的性能。
- 价格有效性,多台低性能的集群,相较一台高性能更加便宜,价格更加透明,且对比单机需要停机维护来看维护成本更低。
- 高可用性,多台服务器集群在一起,冗余性更高更加安全。
- 可伸缩性,可以根据需求灵活的调整服务器的数量。
# 负载均衡
- 用于实现对用户的访问请求进行调度分配,实现用户访问压力分担,可利用反向代理实现负载均衡,以后端服务器高可用。
- Nginx可以实现四层和七层的负载均衡,实现四层使用stream,实现七层使用upstream。
- 四层就是基于IP+端口的负载均衡,可以转发TCP/IP协议、UDP协议,通常用来转发端口。
- 七层就是基于URL等应用层信息的负载均衡,通常用来转发HTTP和HTTPS协议的报文。
- 四层负载均衡数据包是在底层就进行了分发,而七层负载均衡数据包则在最顶端进行分发,所以四层负载均衡的效率比七层负载均衡的要高。但四层负载均衡不识别域名,而七层负载均衡可以识别域名。
# 反向代理
- 反向代理用于转发外网主机的请求到内网服务器。
- 外网主机 -> 代理服务器 -> 内网服务器,在外网主机和内网服务器中间加入一台代理服务器,其中代理服务器有2块网卡,内网网卡和外网网卡。然后客户端就可以通过代理服务器的外网IP访问内网服务器。
- 需要注意内网服务器不会知道外网主机的IP,除非报文中有信息传递了外网主机IP。
# 正向代理
- 正向代理用于转发内网主机的请求到外网服务器,内网主机本身不可以上网,但是可以通过代理服务器上网,也就是常说的共享上网和翻墙。
- 内网主机(局域网) -> 代理服务器 -> 互联网 -> 外网服务器,其中代理服务器有2块网卡,内网网卡和外网网卡。
# Nginx负载均衡配置
# 负载均衡模块
ngx_http_upstream_module模块
# 配置负载均衡 Syntax: upstream name { ... } Default: — # 只能在定义在http{}区中 Context: http
1
2
3
4
5使用例子
# 定义负载均衡的后端集群,可指定任意名称 upstream myweb { # 配置后端WEB服务器内网地址 server 10.0.0.7:80; server 10.0.0.8:80; }
1
2
3
4
5
6调度相关配置
轮询调度算法
# 轮询分配请求,按顺序一轮一轮的分配请求 server 10.0.0.7:80; server 10.0.0.8:80;
1
2
3权重调度算法
# 权重分配请求,权重数值越高,分配请求给该主机的次数就越多,用于后端服务器性能不均的情况 server 10.0.0.7:80 weight=[权重数值、默认是1]; server 10.0.0.8:80 weight=[权重数值]; # 比如下面的例子,假设有4个客户端连接请求,则会先调度3个连接到10.0.0.7,然后才会调度1个连接到10.0.0.8 server 10.0.0.7:80 weight=3; server 10.0.0.8:80 weight=1;
1
2
3
4
5
6
7热备功能
# 当其他所有节点都故障时,才会使用热备节点 server 10.0.0.7:80 backup;
1
2节点健康检查
# 定义最大失败次数,尝试连接后端主机失败的次数,失败就会将请求发送给其他节点。默认为1,企业中建议2~3次,或者根据业务需求调整 # 下面的例子表示发送5次都无响应的话,就算为失败故障 server 10.0.0.7:80 max_fails=5; # 定义失败之后的重发的间隔,定义重新尝试连接的间隔时间,尝试重连只会尝试1次。默认为10s,常规业务2~3秒,或者根据业务需求调整 # 下面的例子表示节点失败10秒后,才会继续尝试连接该节点,且下次只会尝试连接该节点1次,直到能正常连接为止 server 10.0.0.7:80 fail_timeout=10s;
1
2
3
4
5
6
7ip_hash调度算法
# 用户第一次访问时,会根据用户IP生成与之对应的hash值。用户下次访问时就会根据不同的hash值,调用有着不同hash池范围的WEB节点。这样只要用户源IP不变,那么用户的每次访问都会访问到相同的WEB节点 # 但是该方法会造成负载不均,应该是早期用来解决用户数据在不同后端可能有的存在、有的不存在的问题,现在可以用NFS网络文件系统解决,所以一般不会使用该调度方式 upstream averload { ip_hash; ... ... }
1
2
3
4
5
6least_conn最小连接调度算法
# 根据服务器连接数分配请求,优先分配请求给连接数最小的WEB节点 # 此负载均衡策略适合请求处理时间长短不一造成服务器过载的情况 upstream averload { least_conn; ... ... }
1
2
3
4
5
6
# 反向代理模块
ngx_http_proxy_module模块
# 配置反向代理 Syntax: proxy_pass URL; Default: — Context: location, if in location, limit_except
1
2
3
4使用例子
upstream myweb { server 10.0.0.7:80; server 10.0.0.8:80; } server { listen 80; server_name www.test.com; location / { # 将请求转发到指定URL # 可以此处指定负载均衡后端集群,此处的myweb就是upstream配置的集群名 proxy_pass http://myweb; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14转发请求到后端时添加自定头信息
proxy_set_head Host $host;
代理返回响应给客户端时添加自定头信息
add_header X-test-host $host;
# 负载均衡相关问题
# 访问网站时显示的页面内容不正确
可能是由于请求报文中的Host字段错误导致的,我们在负载均衡服务器上将客户端请求的Host信息,添加到转发给后端的请求报文上即可。
location / { proxy_pass http://myweb; proxy_set_header Host $host; }
1
2
3
4
# 服务网站WEB后端没有记录用户IP地址
我们在负载均衡服务器上将客户端请求的IP信息,作为X-Forwarded-For添加到转发给后端的请求报文上即可,然后访问日志格式中配置上打印X-Forwarded-For即可。
location / { proxy_pass http://myweb; proxy_set_header X-Forwarded-For $remote_addr; }
1
2
3
4
# Nginx负载均衡排错思路
- 先定位出错的负载均衡集群,再定位出错的服务器,再针对服务器进行错误排查。
- 测试后端WEB节点服务器是否可以正常访问,如
curl -H "host:www.learn.com" 10.0.0.8/test.html
。 - 负载均衡服务器,使用curl命令访问域名,测试是否可以正常调度。
- PC电脑PING域名,测试外网是否可以正常访问。
# 负载均衡应用案例
# 动静分离配置
根据用户访问的URI信息进行负载均衡,以实现动静分离。如果请求的是静态资源,则将请求负载均衡调度到静态资源服务器。如果请求的是非静态资源,则将请求负载均衡调度到处理动态请求的后端。
比如Nginx+Tomcat中,Nginx对于静态资源的请求是比Tomcat快的,所以动静分离可以提高网站静态资源的访问效率。
配置方法
# 负载均衡服务器上进行配置 # 静态资源服务器 upstream static { server 10.0.0.7:80; server 10.0.0.8:80; } # Tomcat服务器 upstream tomcat { server 10.0.0.9:80; server 10.0.0.10:80; } server { listen 80; server_name www.test.com; # 因为动态资源不好通过URI区分,所以一般会匹配静态资源,然后默认将请求调度到处理动态资源的后端 # 如果请求的是静态资源则将其负载均衡到静态资源服务器 # 可以配置匹配静态资源路径,也可以配置匹配静态资源URI,例如:location ~*/(img|js|css) location /static { proxy_pass http://static; proxy_set_header Host $host; } # 如果请求的是非静态资源,则将其负载均衡到处理动态资源的后端 location / { proxy_pass http://tomcat; proxy_set_header Host $host; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31