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负载均衡的官方文档上早就写得一清二楚了!?!

有时候在想卷八股文的意义在哪?
是否就在我需要花一天时间解决的问题,人家可能只需要几分钟?

posted @ 2022-06-05 23:21  whyfate  阅读(4457)  评论(0编辑  收藏  举报