Nginx:13---反向代理之(负载均衡:upstream模块(代理多个上游服务器))
原创
©著作权归作者所有:来自51CTO博客作者董哥的黑板报的原创作品,请联系作者获取转载授权,否则将追究法律责任
一、复杂均衡概述
- 负载均衡也是Nginx常用的一个功能,负载均衡其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP 服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务
- 简单而言就是当有2台或以上服务器时,根据规则随机的将请求分发到 指定的服务器上处理,负载均衡配置一般都需要同时配置反向代理,通过反向代理跳转到负载均衡
二、upstream模块
- 在前一篇文章中我们介绍了反向代理,其中使用了proxy_pass指令指定了反向代理,但是proxy_pass只能指定一个反向代理服务器
- 而upstream模块会启用一个新的配置区段,在该区段定义了一组上游服务器
- 这些服务器可以被设置不同的权重(权重越高的上游服务器会被NgINX传递更多的连接)
- 这些服务器也可以是不同的类型(TCP、UNIX域)
- 也可能处于对服务器进行维护的原因,其中某些被标记为down
upstream模块指令
- 演示案例:下面的location块,其代理了三台服务器
http {
//上游服务器,其中有三台
upstream app {
server 127.0.0.1:9000;
server 127.0.0.1:9001;
server 127.0.0.1:9002;
}
server {
location / {
//反向代理三台上游服务器
proxy_pass http://app;
}
}
}
三、负载均衡的实现策略
- RR(Nginx自带的)
- 权重(Nginx自带的)
- ip_hash(Nginx自带的)
- least_conn(Nginx自带的)
- fair(第三方策略)
- url_hash(第三方策略)
- 6种实现策略适用情况不同,其中fair和url_hash策略需要安装第三方模块才能使用
①轮询(RR,默认策略)
- 概念:每个请求按时间顺序逐一分配到不同的后端服务器
- 默认模式的特点:
- 下面我们代理了两台服务器,一台为localhost:8080,另一台为localhost:8081
- 当有客户端连接进行时,第1个客户端会交给localhost:8080处理,第2个客户端交给localhost:8081处理,接着第3个客户端又交给localhost:8080处理,第4个客户端交给localhost:8081处理....以此类推
http {
upstream test {
server localhost:8080;
server localhost:8081;
}
server {
listen 81;
server_name localhost;
client_max_body_size 1024M;
location / {
proxy_pass http://test;
proxy_set_header Host $host:$server_port;
}
}
}
②权重
- 概念:指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况
- 格式:在server指令最后加上weight权重值
- 演示案例如下:
- 下面我们代理了两台服务器,一台为localhost:8080,其权重为7;另一台为localhost:8081,其权重为3
- 也就是说,每当10次客户端访问中,其中有7次是访问的localhost:8080,有3次是访问的localhost:8081
http {
upstream test {
server localhost:8080 weight=7;
server localhost:8081 weight=3;
}
server {
listen 81;
server_name localhost;
client_max_body_size 1024M;
location / {
proxy_pass http://test;
proxy_set_header Host $host:$server_port;
}
}
}
③ip_hash
- 前面介绍的两种方式都有一个问题,那就是下一个请求来的时候不确定到底被分发到哪一台机器上
- 应用场景之一:当我们的程序不是无状态的时候(采用了session保存数据),这时候就有一个很大的问题,比如把登录信息保存到了session中,那么跳转到另一台服务器的时候就需要重新登录了,所以很多时间我们需要一个客户只访问一台服务器,那么可以采用iphash了
- iphash的每个请求按访问ip的hash结果分配,这样每个访客固定一个端口服务器,可以解决上面的session问题
- 格式:只需要在upstream模块内添加一个ip_hash指令即可
- 演示案例如下:下面有两台代理服务器,当有客户端去访问时,每个客户端每次请求的都是同一台服务器
http {
upstream test {
ip_hash;
server localhost:8080;
server localhost:8081;
}
server {
listen 81;
server_name localhost;
client_max_body_size 1024M;
location / {
proxy_pass http://test;
proxy_set_header Host $host:$server_port;
}
}
}
④least_conn
- 把请求转发给连接数较少的后端服务器
- 轮询算法是把请求平均的转发给各个后端,使它们的负载大致相同;但是,有些请求占用的时间很长,会导致其所在的后端负载较高。这种情况下,least_conn这种方式就可以达到更好的负载均衡效果
- 格式:只需要在upstream模块内添加一个least_conn指令即可
- 演示案例如下:
http {
upstream test {
least_conn; #把请求转发给连接数较少的后端服务器
server localhost:8080;
server localhost:8081;
}
server {
listen 81;
server_name localhost;
client_max_body_size 1024M;
location / {
proxy_pass http://test;
proxy_set_header Host $host:$server_port;
}
}
}
⑤fair(第三方策略)
- 概念:该策略按后端服务器的相应时间来分配请求,响应时间短的优点分配
- 格式:只需要在upstream模块内添加一个fiar指令即可
- 演示案例如下:
http {
upstream test {
fair;
server localhost:8080;
server localhost:8081;
}
server {
listen 81;
server_name localhost;
client_max_body_size 1024M;
location / {
proxy_pass http://test;
proxy_set_header Host $host:$server_port;
}
}
}
⑥url_hash(第三方策略)
- 概念:该策略按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效
- 格式:在upstream模块内添加相应的hash指令即可
- 演示案例如下:
http {
upstream test {
hash $request_uri;
#指定hash算法
hash_method crc32;
server localhost:8080;
server localhost:8081;
}
server {
listen 81;
server_name localhost;
client_max_body_size 1024M;
location / {
proxy_pass http://test;
proxy_set_header Host $host:$server_port;
}
}
}
四、保持活动连接(keepalive指令)
- Nginx服务器将会为每一个worker进程保持同上游服务器的链接。在Nginx需要同上游服务器保持一定数量的打开连接时,连接缓存非常有用
- 该指令指定每一个worker进程缓存到上游服务器的连接数
- 如果上游服务器通过HTTP协议进行通信,那么Nginx将会使用HTTP/1.1协议的持久连接机制维护这些打开的连接,因此,proxy_http_version应该设置为1.1,并且应该使用proxy_set_header指令将Connection头设置为""
- 演示案例如下:
- 在这个配置中,我们指出127.0.0.1:8080的上游服务器保持32个打开的链接
- Nginx仅需要为每一个worker打开32个TCP握手连接,然后通过不发送close的Connection头保持这些连接的打开
- 另外使用proxy_http_version指令指定HTTP/1.1协议与上游服务器进行通信
- 另外使用proxy_set_header指令清除了Connection头的内容,因此我们没有直接代理客户端的连接属性
- 需要实际需求多于32个连接,Nginx仍然会打开它们以便满足需要。如果在此之后高峰已过,那么Nginx将关闭最近最少使用的连接,以使得这个数回落到32
http {
upstream apache {
server 127.0.0.1:8080;
keepalive 32;
}
location / {
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_pass http://apache;
}
}
- 这种机制也能够被用在代理非HTTP连接中。例如,下面我们展示了Nginx与两个memcached实例保持64个连接
upstream apache {
server 10.0.100.10:11211;
server 10.0.100.20:11211;
keepalive 64;
}