georgi_g784
georgi_g784

Reputation: 31

NGINX IP Hash balancing method not working as expected

I'm currently facing a problem with the NGINX ip_hash; algorithm for balancing http requests to my backend nodes.

The version of NGINX that I am currently using is

nginx version: nginx/1.14.2

My configuration from sites-enabled

limit_req_zone $http_x_forwarded_for zone=some_zone:10m rate=10r/s;
upstream backend {
                ip_hash;
                server 192.168.0.100:5555; 
                server 192.168.0.101:5555; 
                server 192.168.0.102:5555;
    }
server {
            server_name some.server.com;
            listen      80;
            listen      443 ssl;
            server_tokens off;
            access_log /var/log/my_app/acess.log;
            ssl_certificate     /root/certificate.crt;
            ssl_certificate_key /root/key.key;


            ssl_verify_depth 3;
            ssl_protocols TLSv1 TLSv1.1 TLSv1.2 SSLv2 SSLv3;
            ssl_prefer_server_ciphers on;
            ssl_ciphers <sll_ciphers>;

            root /var/www/my_app;
            error_page 302 400 402 405 406 407 408 409 410 411 412 413 414 415 416 417 444 500 501 502 503 504 505 /error/error.html;

            error_page 401 /error/401.html;
            error_page 403 /error/403.html;
            error_page 404 /error/404.html;

            chunked_transfer_encoding on;

            location = / {
                if ($request_method = GET ) {
                    return 301 https://google.com;
                }
                if ($request_method != POST ) {
                    return 403;
                }
                set $no_cache 1;
                limit_req                   zone=some_zone burst=10 nodelay;
                proxy_buffering             off;
                proxy_pass                  http://backend;
                proxy_set_header            X-Real-IP $remote_addr;
                proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header            Host $http_host;
                proxy_intercept_errors      on;
                proxy_connect_timeout       120;
                proxy_read_timeout          120;
                proxy_ignore_client_abort   on;
                chunked_transfer_encoding   on;
            }
    }

The problem resides in the fact that I am seeing traffic only to one of the three backend nodes as opposed to them being spread out along all three of them. From my understanding, the ip_hash algorithm should make it so that once a connection X is made via the proxy to one of the backend nodes, the same connection X should go to the same node. A connection Y should go to the second node, keep the traffic going over to the second node, etc. Not having a connection be persistent to a backend node once it is established does not want to work.

I have also tried to use the latest nginx version available, but still to no avail.

Upvotes: 1

Views: 1950

Answers (1)

georgi_g784
georgi_g784

Reputation: 31

I found the solution. Instead of using "ip_hash;" or "hash $request_uri consistent;" use "hash $remote_addr;"

Looks like ip_hash hashes the first three octets of the destination upstream servers. No idea if that is the correct explanation, since my clients that are accessing the nginx server are from several different /24's, but it works.

Upvotes: 2

Related Questions