# nginx通过X-Forwarded-For获取真实ip基于真实ip做hash

> 作者/来源: UCloud 运营管理员
> 发布时间: 2023-01-11T05:19:00.000Z
> 分类: CDN
> 标签: CDN
> 原文链接: http://117.50.162.249:3000/yun/articles/1388

---

# nginx通过X-Forwarded-For获取真实ip基于真实ip做hash

> 来源: https://www.ucloud.cn/yun/129461.html
> 作者: IT那活儿
> 发布日期: 发布于2023-01-11 13:19

nginx通过X-Forwarded-For获取真实ip基于真实ip做hash

**点击上方“IT那活儿”公众号，关注后了解更多内容，不管IT什么活儿，干就完了！！！**

# 01

**场景**

因为一次业务会多次访问，但是访问中会产生一些文件和图片，所以后端真实服务需要做会话保持或者做文件共享服务。

# 02

**解决方案**

- 文件共享服务可以使用nfs文件共享，也可以使用文件系统（如：fastdfs）做共享文件。
- 可以通过redis做session共享。
- **可以直接通过改动nginx做基于ip的会话保持，这种改动目前对于生产系统是改动最小，影响最小的。**

# 03

**Nginx解决方案**

nginx常用的就是基于ip做hash，但是nginx前面如果还有代理或者套了一层CDN，直接ip\_hash是无法均衡分配的，因为nginx会把前一层套的代理地址或CDN地址做hash算法分配给后端服务地址。

#### **3.1 在 Nginx 的 http 模块内加入如下配置：**

```
map $http_x_forwarded_for $clientRealIp {"" $remote_addr;~^(?P[0-9.]+),?.*$ $firstAddr;}
```

**注：**而且代码中还配合使用了$remote\_addr，因此$clientRealIP 还能兼容客户端直接访问nginx代理的情况，不像$http\_x\_forwarded\_for在直接访问模式中将会是空值！

**3.2 在nginx的upstream模块内加入如下配置：**

```
upstream web {hash $clientRealIp;server 192.168.1.100:8080;server 192.168.1.101:8080;}
```

# 04

**测试案列**

第一层代理：单台nginx：36

- nginx配置如下图所示：

![](https://ucloud-blog.cn-bj.ufileos.com/articles/129461/images/129461_000.png)

第二层代理：两台nginx:37/38

- 37/38nginx配置如下图所示：

![](https://ucloud-blog.cn-bj.ufileos.com/articles/129461/images/129461_001.png)

第三层web服务：三台web服务:39/40/41

**4.1 测试**

- 通过浏览器访问第一台nginx地址加端口，如：http://ip36:8088
- 通过其它服务器直接curl访问，如：curl http://ip36:8088

**4.2 验证**

第二层代理37/38nginx，统计两台nginx访问日志，把客户端地址和第三层web服务地址统计输出，发现同一个客户端只会出现在37/38其中一台nginx访问日志中，且也只会分发到后端web服务一台服务器，验证成功。

- 37nginx访问日志如图所示：

![](https://ucloud-blog.cn-bj.ufileos.com/articles/129461/images/129461_002.png)

- 38nginx访问日志如图所示：

![](https://ucloud-blog.cn-bj.ufileos.com/articles/129461/images/129461_003.png)

![](https://ucloud-blog.cn-bj.ufileos.com/articles/129461/images/129461_004.png)

END

## 本文作者：徐 苗

## 本文来源：IT那活儿（上海新炬王翦团队）

![](https://ucloud-blog.cn-bj.ufileos.com/articles/129461/images/129461_005.png)