使用Nginx搭建负载均衡
什么是负载均衡
搭建负载均衡服务的需求如下:
1、把单台计算机无法承受的大规模并发访问数据流量分担到多台节点设备上,分别进行处理,以减少用户等待响应的时间,提升用户的体验;
2、单个重负载的运算分担到多台节点设备上做并行处理,每个节点设备处理结束之后,将结果汇总,返回给用户,系统处理能力将会得到大幅度提高;
3、7X24小时的服务保证,任意一个或者多个有限节电设备宕机,不能影响业务,
负载均衡集群中,同组集群的所有计算机节点都应该提供相同的服务,集群负载均衡器会截获所有对该服务的入站请求。然后将这些请求尽可能的平均分配在所有集群节点上。
严格的说,Nginx仅仅是作为Nginx proxy rewrite反向代理使用的,因为这个反向代理功能表现的效果是负载均衡集群的效果,所以也可以称之为Nginx负载均衡。
实现Nginx负载均衡的组件
1、ngx_http_proxy_module
模块
该模块为proxy代理模块,用于把请求后抛给服务器节点或者upstream服务器池。
2、ngx_http_upstream_module
模块
负载均衡模块,可以实现网站的负载均衡功能以及节点的健康检查。
upstream模块介绍
ngx_http_upstream_module模块允许Nginx定义一组或者多组节点服务器组,使用时可以通过proxy_pass代理方式把网站的请求发送到事先定义好的对应upstream组的名字上,具体写法为'proxy_ pass http://www_server_pools'
,其中www_server_pools就是一个upstream节点服务器组名字。ngx_http_upstream_module模块官方地址:upstream
upstream模块语法
基本的upstream配置案例:
upstream www_server_pools{
server 1.2.3.4:80 weight=5;
server 2.3.4.5:80 weight=10;
server 3.4.5.6:80 weight=15;
}
# upstream是关键字必须有,后面www_server_pools为一个upstream集群组的名字可以自己起名,调用时候就用这个名字
# server关键字是固定的,后面可以接域名或者IP,如果不指定端口则默认80端口,weight代表权重,数值越大被分配的请求越多,不写则默认1
较完整的upstream配置案例:
upstream blog_server_pool{
server 1.2.3.4;
server 2.3.4.5:80 weight=1 max_fails=1 fail_timeout=10s;
server 3.4.5.6:8080 weight=1 max_fails=2 fail_timeout=20s backup;
}
也就是添加了一些参数
使用域名及socket的upstream配置案例:
upstream backend{
server backend1 example.com weight=5;
server backend2.example.com:80;
server unix:/temp/backend3;
}
#第三行为指定socket文件
upstream模块相关说明
upstream模块的内容应放于Nginx.conf配置的http{}标签内,其默认节点调度算法为wrr(权重轮训weighted round-robin)
相关说明:
server标签 | 参数说明 |
---|---|
server 1.2.4.5:80 | 这个没啥好说的 可以写IP也可以写域名 |
weight=1 | 代表权重 |
max_fails=1 | Nginx尝试连接后端主机失败的次数 |
backup | 热备配置,当前面激活的RS都失败后悔自动启用。这标志着这个服务器会作为备份服务器,若主机全部宕机了则会向它转发请求 |
fail_timeout=10s | 在max_fails定义的失败次数后,距离下一次检查的时间间隔 |
down | 这标志着服务器永远不可用,这个参数可配合ip_hash使用 |
upstream模块调度算法
调度算法一般分为两类,第一类是静态调度算法,即负载均衡器根据自身设定的规则进行分配,不需要考虑后端节点的服务器情况,例如rr
,wrr
,ip_hash
等。
第二类是动态调度算法,即负载均衡器会根据后端节点的当前状态来决定是否分发请求,例如:连接数较少的优先获得请求,响应时间短的优先获得请求,例如least_conn
,fail
等。
下面介绍一下常见的调度算法。
1、rr轮训(默认调度算法,静态)
非常简单,就是对每个请求逐一分配给不同的后端节点服务器。
2、wrr(权重轮询,静态)
在rr轮询的基础上加上了权重,也比较好理解。
3、ip_hash算法(静态)
每个请求按照客户端IP的hash结果分配。当新的请求到达之后,先将其客户端IP通过哈希算法哈希出一个值,在随后的客户端请求中,客户IP的哈希值只要相同,就会被分配至同一台服务器,该调度算法可以解决动态网页的session共享问题,但有时候会导致请求分配不均匀,即无法保证1:1的负载均衡(因为国内大多数情况都是NAT方式)。
#ip_hash方式演示
upstream blog_a{
ip_hash;
server 1.2.3.4:80;
server 2.3.4.5:80;
}
upstream backend{
ip_hash;
server a.com;
server b.com;
server c.com down;
}
#当算法为ip哈希的时候,后端服务器在负载均衡调度中的状态不能有weight和backup,有也不会生效。
4、fair(动态)
此算法会根据后端节点服务器的响应时间来分配请求,相应时间短的优先分配。这个算法可以根据页面大小和加载时间的长短智能的进行负载均衡。Nginx本身是不支持fair调度算法的,如果要使用的话必须下载Nginx的相关模块upstream_fair
。
upstream blog_a{
fail;
server 1.2.3.4;
server 2.3.4.5;
}
5、url_hash(动态)
和ip哈希类似,这里是根据访问URL的哈希结果来分配请求的,让每个URL定向到同一个后端服务器,后端服务器为缓存服务器时效果显著,可以有效的提高后端缓存服务器的命中率。Nginx本身也不支持url哈希,如果需要使用的话必须安装Nginx的hash模块软件包。
upstream blog_a{
server squid1:123;
server squid2:123;
hash $request_url;
hash_method crc32;
}
http_proxy_module模块
proxy_pass指令介绍
该指令属于ngx_http_proxy_module模块,可以将请求转发到另一台服务器,在实际的反向代理工作中,会通过location功能匹配指定的URI,然后把接收到的符合匹配URI的请求通过proxy_pass抛给定义好的upstream节点池,详情见官方文档。
使用案例:
#将URI为name的请求抛给http://1.2.3.4/remote/
location /name/{
proxy_pass http://1.2.3.4/remote/;
}
#将URI为some/path的请求应用rewrite规则并抛给http://1.2.3.4
location /some/path/{
rewrite /some/path/([^/]+)/users?name=$1 break;
proxy_pass http://1.2.3.4;
}
proxy模块相关参数
http proxy 模块相关参数 | 说明 |
---|---|
proxy_set_header | 设置http请求header项传给后端服务器节点,例如:可实现让代理后端的服务器节点获取访问客户端用户的真实IP地址。 |
client_body_buffer_size | 用于指定客户端请求主题缓冲区大小 |
proxy_connect_timeout | 反向代理与后端节点服务器连接的超时时间 |
proxy_send_timeout | 表示代理后端服务器的数据回传时间,即在规定的时间之内后端本服务器必须传完所有的数据,否则Nginx将会断开这个连接 |
proxy_read_timeout | 设置Nginx从代理后端服务器获取信息的时间,也就是等待后端响应的时间 |
proxy_buffer_size | 设置缓冲区大小 |
proxy_busy_buffers_size | 用于设置系统忙时可以使用的proxy_buffers大小,官方推荐为上者两倍 |
proxy_temp_file_write_size | 指定proxy缓存临时文件的大小 |