Nginx
Nginx upstream
nginx upstream 需要做的事情主要有两个,第一个是当client 发送http 请求过来之后,需要创建一个到后端的upstream请求,第二个是当后端发送数据过来之后,将后端的数据再次发送到client。
upstream 语法:
server address [parameters];
后端分配模式
- rr
- weight
- ip_hash
- fair
- url_hash
一、 rr
轮询是nginx 默认的分配方式,即按照每个请求按照时间顺序轮流分配到不同的后端服务器,如果某个后端服务down掉后,能自动剔除。
upstream tomcat {
server 1.1.1.1:8080;
server 1.1.1.1:8090;
server 1.1.1.1:8070;
}
二、weight
权重可以指定每个后端的访问比率权重,主要用在后端服务器配置不同的情况下
upstream backennd {
server 1.1.1.1:8080 weight=1;
server 1.1.1.1:8090 weight=2;
server 1.1.1.1:8070 weight=1;
}
三、ip_hash
ip 哈希是对于每个请求按照访问IP,进行hash结果分配,这样能保证每个访客都会固定访问一个后台服务器,可以解决session 一致性问题
upstream tomcat {
ip_hash;
server 1.1.1.1:8080;
server 1.1.1.1:8090;
server 1.1.1.1:8070;
}
四、fair
fair 就是公平地按照后端服务器的响应时间(rt)来分配请求,响应时间短即rt小的后端服务器优先分配请求
upstream tomcat {
server 1.1.1.1:8080;
server 1.1.1.1:8090;
server 1.1.1.1:8070;
fair;
}
五、url_hash
按照访问的url 的结果来分配请求,使得每个url定向到同一个后端服务器,主要应用于后端服务器为缓冲时的场景
upstream tomcat {
server 1.1.1.1:8080;
server 1.1.1.1:8090;
server 1.1.1.1:8070;
hash $request_uri;
hash_method crc32;
}
其中hash_method 表示采用的hash 算法为crc32。
后端分配参数
parameters 是可选参数
- down : 表示当前server 已停用
- backup: 表示当前server是备用服务器,只有其他非backup后端服务器都挂掉了或者很忙才会分配到请求
- weight: 表示当前server负载权重,权重越大,请求几率越大,默认为1
- max_fails 和fail_timeout 如果某个server在fail_timeout 时间内出现了max_fails次失败,那么nginx 就会认为他已经挂掉
proxy 指令
-
proxy_next_upstream
确定在何种情况下将转发到下一台服务器
转发请求只发生在没有数据传递到客户端的过程中
proxy_next_upstream: 定义了什么时候转发
语法: proxy_next_upstream error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | off …;
默认值: proxy_next_upstream error timeout;
使用字段: http, server, location
error - 在连接到一个服务器,发送一个请求,或者读取应答时发生错误。
timeout - 在连接到服务器,转发请求或者读取应答时发生超时。
invalid_header - 服务器返回空的或者错误的应答
off - 禁止转发请求到下一台服务器
-
proxy_connect_timeout
语法:proxy_connect_timeout timeout_in_seconds
默认值:proxy_connect_timeout 60s
使用字段:http, server, location
指定一个连接到代理服务器的超时时间,单位为秒,需要注意的是这个时间最好不要超过75秒。 这个时间并不是指服务器传回页面的时间(这个时间由proxy_read_timeout声明)。如果你的前端代理服务器是正常运行的,但是遇到一些状况(例如没有足够的线程去处理请求,请求将被放在一个连接池中延迟处理),那么这个声明无助于服务器去建立连接。 可以通过指定时间单位以免引起混乱,支持的时间单位有”s”(秒), “ms”(毫秒), “y”(年), “M”(月), “w”(周), “d”(日), “h”(小时),和 “m”(分钟)。 这个值不能大于597小时。
-
proxy_read_timeout
语法:proxy_read_timeout time
默认值:proxy_read_timeout 60s
使用字段:http, server, location
决定读取后端服务器应答的超时时间,单位为秒,它决定nginx将等待多久时间来取得一个请求的应答。超时时间是指完成了两次握手后并且状态为established的超时时间。 相对于proxy_connect_timeout,这个时间可以扑捉到一台将你的连接放入连接池延迟处理并且没有数据传送的服务器,注意不要将此值设置太低,某些情况下代理服务器将花很长的时间来获得页面应答(例如如当接收一个需要很多计算的报表时),当然你可以在不同的location里面设置不同的值。 可以通过指定时间单位以免引起混乱,支持的时间单位有”s”(秒), “ms”(毫秒), “y”(年), “M”(月), “w”(周), “d”(日), “h”(小时),和 “m”(分钟)。 这个值不能大于597小时。
-
proxy_send_timeout
语法:proxy_send_timeout seconds
默认值:proxy_send_timeout 60s
使用字段:http, server, location
设置代理服务器转发请求的超时时间,单位为秒,同样指完成两次握手后的时间,如果超过这个时间代理服务器没有数据转发到被代理服务器,nginx将关闭连接。 可以通过指定时间单位以免引起混乱,支持的时间单位有”s”(秒), “ms”(毫秒), “y”(年), “M”(月), “w”(周), “d”(日), “h”(小时),和 “m”(分钟)。 这个值不能大于597小时。
-
proxy_next_upstream_tries:定义了重试次数
格式: proxy_next_upstream_tries number;
默认值: proxy_next_upstream_tries 0;
使用字段: http, server, location
This directive appeared in version 1.7.5.
看到这里,很多人可能会问:
- 如何判断后端是不可用的
- 如果nginx 判断对应的后端挂掉,如何检查这个后端是否进入可用状态呢
- 权重比例是怎样计算的呢? 是按照总得权重去取百分比计算吗
- 后端参数能和那些分配模式进行混用呢?
- ip_hash 实现的原理是什么呢
- server address [parameter] 中的address 能是那些格式呢?
问题解答:
-
nginx 判断失败节点状态以connect refuse 和time out状态为准,不以http 错误状态进行判断失败,因为只要http 能返回状态就说明该节点还可以正常连接,所以nginx判断其是存活状态
除非在proxy_next_upstream 指令对404,502, 503等错误进行了转到备机处理,在proxy_next_upstream 过程中会对fails进行累加,如果备机还是错误,则直接返回错误信息(404不会记录到错误数,如果不在proxy_next_upstream 中配置,错误状态也不会被记录)。
nginx 只会对timeout error, 500,502,503,504 这六种状态进行错误数记录,timeout 和error 永远都会记录50x只有在proxy_next_upstream后,nginx才会进行错误数进行记录,当在fail_timeout的时间内,某个server连接失败了max_fails次, 那么nginx就会认为该server不工作了,默认fail_timeout 10s, max_fails 1.
-
nginx 可以通过设置max_fails(最大尝试失败次数) 和fail_timeout (失效时间) 在失效时间内,在达到最大尝试次数后,在fail_timeout的时间内,节点被置为失效,除非所有的节点 都失效,否则该时间内,节点不进行恢复,当所有节点都失效,且备机也失效时,nginx 会为所有节点恢复有效,重新探测有效节点
-
权重比例是按照加权轮询算法来进行分配,不是常规的数学百分比
-
有以下几种
- 无法将权重和ip_hash 联合使用分发连接
- url_hash 无法和权重联合使用
-
ip_hash 能够将某个ip的请求定向到同一台后端server,这样这个ip下的客户端就和同一个后端server建立了稳固的session
ip_hash 的缺点
- nginx 必须是最前端的服务器,如果nginx 前端有squid,那么nginx获取ip时只能获取squied服务器的地址,无法根据这个地址进行分流
- nginx 后端还有其他负载均衡机制,如果nginx 后端有其他负载均衡的方式,那么就无法将session负载到同一台后端服务器
-
address 格式
address 可以是主机名,域名,ip或unix 套接字
示例
upstream socket {
server 1.1.1.1:8080 weight=1 max_fails=3 fail_timeout=20s;
server unix:/tmp/backend;
server 1.1.1.1:8090 backup;
server 1.1.1.1:7080 down;
}
server {
listen 80;
server_name www.xytiao.cn;
index index.html;
location / {
proxy_pass http://socket;
proxy_next_upstream http_500 http_502 http_503 http_504 error timeout invalid_header;
}
}
觉得不错,可以关注我的公众号