Nginx 之 ip_hash 问题
起因
公司项目上用到了Asp.Net Core SignalR,由于SignalR需要长链接,所以在进行水平扩展的时,不仅需要Redis做底板,还需要将同一个链接的请求打到同一台机器上;
作为一个资深面相百度编程的Coder,第一个想到的当然是nginx的ip_hash了,毕竟在session横行的年代,这算是成本最低的方案了。
问题
upstream backend {
ip_hash;
server 192.168.120.102:30000;
server 192.168.120.104:30000;
server 192.168.120.106:30000;
}
在使用如上配置后,项目顺利跑了起来,但是当查看客户端连接时发现几乎所有的连接都打到了一台机器上!
netstat -ano | grep 192.168.120.102:30000 | wc -l
100
netstat -ano | grep 192.168.120.104:30000 | wc -l
2
netstat -ano | grep 192.168.120.106:30000 | wc -l
0
这就非常的离谱了,莫不是hash算法有问题,百度良久果然是hash的算法问题;
nginx的ip hash只用了ip地址的前三位,这样做是为了让来自同一个地区的请求落在一个后台服务上。
但是咱内网项目,ip的前三段基本一样,所以就导致了基本上所有的链接都落在了一个后台服务商。
解决
既然知道了问题,解决就应该非常简单了,既然默认只用了前三段,那么大胆猜测加个配置应该就能用全部的ip来hash;
果然现实是残酷的,并没有所谓的配置存在,各大技术大佬给出的方案是修改源码,虽然只改两个地方,但是作为一个资深拿来党,是不可能这么做的!
那么还有没有其他办法呢?当然有,作为一个资深面向百度编程的Coder,我们要坚信,困难总比办法多,没有问题是别人没有解决的,只要咱keyword输得对,一切问题都不是问题
upstream backend {
hash $remote_addr consistent;
server 192.168.120.102:30000;
server 192.168.120.104:30000;
server 192.168.120.106:30000;
}
最后的最后,其实nginx负载均衡的官方文档上早就写得一清二楚了!?!
有时候在想卷八股文的意义在哪?
是否就在我需要花一天时间解决的问题,人家可能只需要几分钟?