nginx代理ip哈希用法

系列文章目录

接下来介绍nginx中ip_hash的用法。


文章目录


前言

通常后端服务器集群无法会话共享(cookie,session,jwt)的时候,这就造成我们访问第一台服务器,获取了cookie信息,后续接口携带该cookie访问集群中其他服务器就会失败,因为这是第一台服务器分发的cookie,集群中其他服务器是无法识别的;无法改变上游系统的时候只能我们自己改变,ip哈希就是一个不错的方案,通过请求方ip计算固定路由到某台后端服务器,也就是我的cookie是从你这获取的,我后续的请求也还是固定发到你这台服务器;当然,这样就无法再负载均衡,可能会导致某台后端服务器比集群中其他服务器压力大,所以集群能做cookie共享,就尽量做cookie共享。


提示:以下是本篇文章正文内容,下面案例可供参考

一、ip_hash

bash 复制代码
#user  nobody;
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
	
	log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
				  '$status $body_bytes_sent "$http_referer" '
				  '"$http_user_agent" "$http_x_forwarded_for" "$http_cookie" "$upstream_addr"';

    access_log  logs/access.log  main;
	
    #新增-start
    upstream sysservers {
		ip_hash; #启用IP哈希负载均衡
        server 127.0.0.1:2005;
        server 127.0.0.2:2005;
        server 127.0.0.3:2005;
    }
    #新增-end
    server {
        listen       8099;
        server_name  localhost;
        location / {
            root   resource;
            index  index.html index.htm;
            try_files $uri /index.html;
        }
        location /gdp {
            alias resource/gdp;
            proxy_set_header Host $host:$server_port;
        }
        location /sys {
            alias /home/sys/app/system/web/sys;
            try_files $uri $uri/ /index.html;
        }
        #修改proxy_pass
        location /api/ {
            proxy_pass  http://sysservers/;
			proxy_set_header Host $host:$server_port;
			proxy_set_header X-Real-IP $remote_addr;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			client_max_body_size 100m;
			client_body_buffer_size 128k;
			proxy_connect_timeout 90;
			proxy_send_timeout 300;
			proxy_read_timeout 300;
			proxy_buffer_size 4k;
			proxy_buffers 4 32k;
			proxy_busy_buffers_size 64k;
			proxy_temp_file_write_size 64k;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

通过ip_hash声明,这样就能根据请求ip将请求固定到某台后端服务器

这里log_format的参数值也很重要,方便我们查看日志,分析请求链路

二、自定义ip_hash

Nginx 原生 ip_hash 不支持直接使用 http_x_forwarded_for,需通过 自定义 hash 配置 实现,核心是先提取真实客户端 IP(从 http_x_forwarded_for 中),再基于该 IP 计算 hash。

有些时候我们会遇到些复杂的请求,或者经过squidF5的代理导致我们的ip_hash失效,这时候就需要我们自己进行处理,下面是具体步骤,按步骤操作即可

1.真实 IP 提取

先通过 map 指令从 http_x_forwarded_for 中提取第一个真实客户端 IP(因该字段格式通常为 "客户端 IP, 代理 1IP, 代理 2IP"),并赋值给自定义变量 real_client_ip。若未获取到 http_x_forwarded_for(无代理场景),则默认使用 remote_addr 兜底。

bash 复制代码
# 在 http 块中配置(与 server 块同级)
map $http_x_forwarded_for $real_client_ip {
    # 正则提取第一个非空IP(匹配 IPv4 格式)
    ~^(\d+\.\d+\.\d+\.\d+) $1;
    # 若 $http_x_forwarded_for 为空,默认用 $remote_addr
    default $remote_addr;
}

2.使用自定义 hash 策略

upstream 块中,不使用原生 ip_hash,而是用 hash $real_client_ip; 指令,基于第一步提取的真实 IP 计算哈希。

bash 复制代码
#user  nobody;
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
	
	log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
				  '$status $body_bytes_sent "$http_referer" '
				  '"$http_user_agent" "$http_x_forwarded_for" "$http_cookie" "$upstream_addr"';

    access_log  logs/access.log  main;
	
    #新增-start
    upstream sysservers {
		hash $real_client_ip; #基于真实客户端IP计算hash(替代原生ip_hash)
        server 127.0.0.1:2005;
        server 127.0.0.2:2005;
        server 127.0.0.3:2005;
    }
    #新增-end
    server {
        listen       8099;
        server_name  localhost;
        location / {
            root   resource;
            index  index.html index.htm;
            try_files $uri /index.html;
        }
        location /gdp {
            alias resource/gdp;
            proxy_set_header Host $host:$server_port;
        }
        location /sys {
            alias /home/sys/app/system/web/sys;
            try_files $uri $uri/ /index.html;
        }
        #修改proxy_pass
        location /api/ {
            proxy_pass  http://sysservers/;
			proxy_set_header Host $host:$server_port;
			proxy_set_header X-Real-IP $remote_addr;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			client_max_body_size 100m;
			client_body_buffer_size 128k;
			proxy_connect_timeout 90;
			proxy_send_timeout 300;
			proxy_read_timeout 300;
			proxy_buffer_size 4k;
			proxy_buffers 4 32k;
			proxy_busy_buffers_size 64k;
			proxy_temp_file_write_size 64k;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

这样我们就能通过自定义ip_hash实现将请求固定到某台后端服务器,只要ip是稳定的,就能保证请求正常。


总结

提一嘴,现在豆包真挺好用

相关推荐
代码的奴隶(艾伦·耶格尔)13 小时前
Nginx
java·服务器·nginx
液态不合群13 小时前
Nginx多服务静态资源路径冲突解决方案
运维·nginx
岁岁种桃花儿15 小时前
详解kubectl get replicaset命令及与kubectl get pods的核心区别
运维·nginx·容器·kubernetes·k8s
zbguolei15 小时前
CentOS 7.6离线安装Nginx
linux·nginx·centos
倒流时光三十年21 小时前
阿里云 CentOS 7 使用 docker 安装 Nginx
nginx·阿里云·docker·centos
君义_noip1 天前
信息学奥赛一本通 1463:门票
c++·算法·哈希算法·信息学奥赛·csp-s
海棠AI实验室1 天前
第十五章 字典与哈希:高效索引与去重
算法·哈希算法
羱滒1 天前
Docker Compose + Nginx + 后端服务运行环境搭建全流程指南(redis、mongdb、nginx、nacos-registry)
redis·nginx·docker·docker-compose
xiaozenbin1 天前
宝塔8.5在nginx中部署动态php页面出现找不到页面处理
运维·nginx·php