-
-
Save CraKeyBoy/6536805c78698ca405ab968284fb8390 to your computer and use it in GitHub Desktop.
在工作中经常使用Nginx的IP_hash策略做负载均衡,所以记录一下使用中的疑惑。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
当对后端的多台动态应用服务器做负载均衡时,ip_hash指令能够将某个客户端IP的请求通过哈希算法定位到同一台后端服务器上。这样,当来自某个IP的用户在后端Web服务器A上登录后,再访问该站点的其他URL,能够保证其访问的还是后端Web服务器A。 | |
如果不采用ip_hash指令,假设来自某个IP的用户在后端Web服务器A上登录后,再访问该站点的其他URL,有可能被定向到后端Web服务器B,C...上,由于用户登录后SESSION信息是记录在服务器A上的,B,C...上没有,这时就会提示用户来登录 | |
在ip_hash策略中,它选择最初的server的方法是根据请求客户真个IP计算出一个哈希值,再根据哈希值选择后台的服务器。 | |
1)由IP计算哈希值的算法如下, 其中公式中hash初始值为89,iphp->addr[i]表示客户真个IP, 通过三次哈希计算得出一个IP的哈希值: | |
for (i = 0; i < 3; i++) { | |
hash = (hash * 113 + iphp->addr[i]) % 6271; | |
} | |
2)在选择下一个server时,ip_hash的选择策略是这样的: | |
它在上一次哈希值的基础上,再次哈希,就会得到一个全新的哈希值,再根据哈希值选择另外一个后台的服务器。 | |
哈希算法仍然是 | |
for (i = 0; i < 3; i++) { | |
hash = (hash * 113 + iphp->addr[i]) % 6271; | |
} | |
在这种ip_hash策略,假如一个后台服务器不能提供提服务(连接超时或读超时),该服务器的失败次数就会加一,当一个服务器的失败次数达到max_fails所设置的值,就会在fail_timeout所设置的时间段内不能对外提供服务,这点和RR是一致的。 | |
假如当前server不能提供服务,就会根据当前的哈希值再哈希出一个新哈希值,选择另一个服务器继续尝试,尝试的最大次是upstream中server的个数,假如server的个数超过20,也就是要最大尝试次数在20次以上,当尝试次数达到20次,仍然找不到一个合适的服务器,ip_hah策略不再尝试ip哈希值来选择server, 而在剩余的尝试中,它会转而使用RR的策略,使用轮循的方法,选择新的server。 | |
3)除了以上部分不同外,IP_hash的其余部分和RR完全一样,由于它的其余部分功能的实现都是通过调用RR中的函数。 | |
4)IP_hash是把同一个客户IP的请求分配给同一个后台服务器。 | |
注意: | |
使用ip_hash指令无法保证后端服务器的负载均衡,可能有些后端服务器接收的请求多,有些后端服务器收到的请求少,而且设置后端服务权重等方法将不起作用。所以,如果后端的动态应用服务器能够做到SESSION共享,还是建议采用后端服务的SESSION共享方式代替Nginx的ip_hash方式。 | |
如果后端服务器有时要从Nginx负载均衡中摘除一段时间,你必须其标记为“down”,而不是直接从配置文件中删除或注释掉该后端服务器的信息。例如: | |
upstream backend { | |
ip_hash; | |
server backend1.example.com; | |
server backend2.example.com; | |
server backend3.example.com down; | |
server backend4.example.com; | |
} | |
这样,当原来为4台后端服务时,摘除backend3.example后,Nginx仍然会按4台服务器进行哈希。如果直接注释掉“server backend3.example.com”这行,Nginx就会按照3台服务器进行重新 | |
哈希,原来被哈希到backend1.example.com的客户端IP有可能被哈希backend2.example.com服务器上,原有的SESSION就会失效。 | |
附上:ip_hash实现源码 | |
https://github.com/nginx/nginx/blob/master/src/http/modules/ngx_http_upstream_ip_hash_module.c |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment