背景
前面说完了nginx的反向代理功能,可能说的不够全面,后续在工作中遇到了需要补充的内容在持续更新。今天咱们来聊一聊Nginx的负载均衡功能。
负载均衡概述
1. 什么是负载均衡?
实际上负载均衡的功能就是基于在反向代理之上的,通过将多台后端服务器定义在一个组中,然后通过不同的调度方法将前端发来的请求,转发发到后端服务器上进行处理。即负载均衡就是将服务器接收到的请求按照规则分发的过程。其中负载均衡就分为硬件负载(f5硬件)和软件负载(nginx,lvs,haproxy等)。
2. 负载均衡与反向代理的区别
反向代理:仅代理一台服务器。
负载均衡:是将客户端请求通过proxy_pass代理到一组upstream资源池中。
3. 负载功能怎么实现?
nginx的所有功能都是通过Nginx的相应模块进行实现的,nginx的负载均衡模块是ngx_http_upstream_module
ngx_http_upstream_module模块用于定义可由proxy_pass、fastcgi_Pas、uwsgi_pass、scgi_ pass、memcached_pass和grpc_PAS指令引用的服务器组。
nginx至此四层和七层负载均衡。
四层负载均衡:传输层
优点:性能高,数据包在四层就进行了转发。
缺点:仅支持ip:port转发,无法完成复杂的业务逻辑应用。
七层负载均衡:应用层
优点:贴近业务,至此uri路径匹配,Header改写,Rewrite等
缺点:性能低,数据包需要拆解到顶层(应用层)才进行转发。
4. ngx_http_upstream_module
先通过一个基础的配置来说说ngx_http_upstream_module的相关参数。
resolver 10.0.0.1;
upstream dynamic {
zone upstream_dynamic 64k;
server backend1.example.com weight=5;
server backend2.example.com:8080 fail_timeout=5s slow_start=30s;
server 192.0.2.1 max_fails=3;
server backend3.example.com resolve;
server backend4.example.com service=http resolve;
server backup1.example.com:8080 backup;
server backup2.example.com:8080 backup;
}
server {
location / {
proxy_pass http://dynamic;
health_check;
}
}
4.1 upstream
定义一组服务器。用于处理按照规则转发来的请求。
Syntax: upstream name { ... }
Default: —
Context: http
示例:
upstream backend {
server backend1.example.com weight=5;
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
server backup1.example.com backup;
}
默认情况下,使用加权循环平衡方法在服务器之间分配请求。在上面的示例中,每7个请求将按如下方式分发:5个请求转到backend1.example.com和一个请求转发到127.0.0.1:8080和一请求转发到unix:/tmp/backend3。如果在与服务器通信过程中发生错误,请求将被传递到下一个服务器,以此类推,直到尝试所有正常运行的服务器。如果无法从任何服务器获得成功响应,客户端将接收与最后一台服务器(带有backup标记)的通信结果。
4.2 server
Syntax: server address [parameters];
Default: —
Context: upstream
定义服务器的地址和其他参数。地址可以指定为域名或IP地址,带有可选端口,也可以指定为“UNIX:”前缀后指定的UNIX域套接字路径。如果未指定端口,则使用端口80。解析为多个IP地址的域名一次定义多个服务器
参数 | 说明 |
| 默认情况下,将服务器的权重设置为1,权重越高访问的几率越大。 |
| 限制到代理服务器的同时,最大活动连接的数量(1.11.5)。默认值为零,表示没有限制。如果服务器组不驻留在共享内存中,则限制对每个工作进程有效。 |
| 与设置在fail_timeout参数配合使用,表示在fail_timeout时间内与服务器通信失败后尝试连接的次数。 |
| 在指定次数的与服务器通信的失败尝试发生的时间内,服务器不可用; 并且服务器将被视为不可用的时间段。 默认情况下,该参数设置为10秒。 |
backup | 将服务器标记为备份服务器。当主服务器不可用时,将传递请求。该参数不能与哈希、ip_哈希和随机负载平衡方法一起使用 |
down | 将服务器标记为永久不可用 |
resolve | 监控与服务器域名对应的IP地址的更改,并自动修改上游配置,无需重新启动nginx(1.5.12)。服务器组必须位于共享内存中。为了使此参数工作,必须在http块或相应的上游块中指定解析器指令。设置服务器路由名称。 |
更多参数见nginx官网:https://nginx.org/en/docs/http/ngx_http_upstream_module.html
负载均衡配置
1. 轮询策略
轮询(默认):接收到的请求按照顺序逐一分配到不同的后端服务器,即使在使用过程中,某一台后端服务器宕机,nginx会自动将该服务器剔除出队列,请求受理情况不会受到任何影响。
upstream webs{
server 192.168.65.130:80;
server 192.168.65.131:8080;
server 192.168.65.132:80;
}
server {
listen 80;
server_name proxy_web.com www.proxy_web.com;
location / {
proxy_pass http://webs;
proxy_set_header Host $http_host;
# proxy_set_header Host $host:$proxy_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
测试
C:\Users\xhz>curl www.proxy_web.com
web1-test
C:\Users\xhz>
C:\Users\xhz>curl www.proxy_web.com
web2-test
C:\Users\xhz>
C:\Users\xhz>
C:\Users\xhz>curl www.proxy_web.com
web3-test
C:\Users\xhz>
2. 权重
weight权重):权重调度室基于轮询的基础上, 这种方式下,可以给不同的后端服务器设置一个权重值(weight,默认weight=1),用于调整不同的服务器上请求的分配率;权重数据越大,被分配到请求的几率越大;该权重值,主要是针对实际工作环境中不同的后端服务器硬件配置进行调整的。
root@nginx:~# cat /etc/nginx/conf.d/proxy.web.com.conf
upstream webs{
server 192.168.65.130:80 weight=30;
server 192.168.65.131:8080 weight=20;
server 192.168.65.132:80 weight=10;
}
server {
listen 80;
server_name proxy_web.com www.proxy_web.com;
location / {
proxy_pass http://webs;
proxy_set_header Host $http_host;
# proxy_set_header Host $host:$proxy_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
测试:
C:\Users\xhz>curl www.proxy_web.com
web1-test
C:\Users\xhz>curl www.proxy_web.com
web1-test
C:\Users\xhz>curl www.proxy_web.com
web2-test
C:\Users\xhz>curl www.proxy_web.com
web1-test
C:\Users\xhz>curl www.proxy_web.com
web3-test
C:\Users\xhz>curl www.proxy_web.com
web2-test
C:\Users\xhz>
3. least_conn
least_conn:将请求传递到活动连接数最少的服务器,同时考虑服务器的权重。如果有几个这样的服务器,则使用加权循环平衡方法依次尝试它们。
此负载均衡策略适合请求处理时间长短不一造成服务器过载的情况.
root@nginx:~# cat /etc/nginx/conf.d/proxy.web.com.conf
upstream webs{
least_conn
server 192.168.65.130:80 weight=30;
server 192.168.65.131:8080 weight=20;
server 192.168.65.132:80 weight=10;
}
server {
listen 80;
server_name proxy_web.com www.proxy_web.com;
location / {
proxy_pass http://webs;
proxy_set_header Host $http_host;
# proxy_set_header Host $host:$proxy_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
4. ip_hash
Ip hash算法,对客户端请求的ip进行hash操作,然后根据hash结果将同一个客户端ip的请求分发给同一台服务器进行处理,可以解决session不共享的问题。
1)nginx版本1.3.1之前,不能在ip_hash中使用权重(weight);2)ip_hash不能与backup同时使用;3)此策略适合有状态服务,比如session。4)当有服务器需要剔除,必须手动down掉。
root@nginx:~# cat /etc/nginx/conf.d/proxy.web.com.conf
upstream webs{
ip_hash
server 192.168.65.130:80;
server 192.168.65.131:8080;
server 192.168.65.132:80;
}
server {
listen 80;
server_name proxy_web.com www.proxy_web.com;
location / {
proxy_pass http://webs;
proxy_set_header Host $http_host;
# proxy_set_header Host $host:$proxy_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
5. fair(第三方)
智能调整调度算法,动态的根据后端服务器的请求处理到响应的时间进行均衡分配,响应时间短处理效率高的服务器分配到请求的概率高,响应时间长处理效率低的服务器分配到的请求少;结合了前两者的优点的一种调度算法。但是需要注意的是nginx默认不支持fair算法,如果要使用这种调度算法,请安装upstream_fair模块。
root@nginx:~# cat /etc/nginx/conf.d/proxy.web.com.conf
upstream webs{
fair
server 192.168.65.130:80;
server 192.168.65.131:8080;
server 192.168.65.132:80;
}
server {
listen 80;
server_name proxy_web.com www.proxy_web.com;
location / {
proxy_pass http://webs;
proxy_set_header Host $http_host;
# proxy_set_header Host $host:$proxy_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
6. url_hash(第三方
按照访问的url的hash结果分配请求,每个请求的url会指向后端固定的某个服务器,可以在nginx作为静态服务器的情况下提高缓存效率。同样要注意nginx默认不支持这种调度算法,要使用的话需要安装nginx的hash软件包。
root@nginx:~# cat /etc/nginx/conf.d/proxy.web.com.conf
upstream webs{
hash $request_uri;
server 192.168.65.130:80;
server 192.168.65.131:8080;
server 192.168.65.132:80;
}
server {
listen 80;
server_name proxy_web.com www.proxy_web.com;
location / {
proxy_pass http://webs;
proxy_set_header Host $http_host;
# proxy_set_header Host $host:$proxy_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}