公司项目需要将同一个链接的请求打到同一台机器上;就是pm2(cluster)集群解决方案中从某个进程发起的请求将来要能回到这个进程中运用,第一个想到的当然是nginx的ip_hash了,这算是成本最低的方案了。

upstream io_nodes {
      ip_hash;
      server 127.0.0.1:3131;
      server 127.0.0.1:3132;
      server 127.0.0.1:3133;
      server 127.0.0.1:3134;
    }
    server {
        listen 80;
        server_name ws.vd.net;
        location / {
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection "upgrade";
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header Host $host;
          proxy_http_version 1.1;
          proxy_pass http://io_nodes;
        }
  }

项目顺利跑了起来,但是当查看客户端连接时发现几乎所有的连接都打到了一台机器上!

这就非常的离谱了,莫不是hash算法有问题,百度良久果然是hash的算法问题
nginx的ip hash只用了ip地址的前三位,这样做是为了让来自同一个地区的请求落在一个后台服务上。
但是咱内网项目,ip的前三段基本一样,所以就导致了基本上所有的链接都落在了一个后台服务商。

解决

既然知道了问题,解决就应该非常简单了,既然默认只用了前三段,那么大胆猜测加个配置应该就能用全部的ip来hash;果然现实是残酷的,并没有所谓的配置存在,各大技术大佬给出的方案是修改源码,虽然只改两个地方。

upstream backend {
    hash $remote_addr consistent;
    server 192.168.120.102:30000;
    server 192.168.120.104:30000;
    server 192.168.120.106:30000;
}