1、request.getHeader("x-real-ip")

这种方式,不知道为啥获取不到ip,不管是用软负载,还是直接访问应用程序。

2、直接访问应用程序

获取ip方式为:

request .getRemoteAddr()

3、http请求软负载,间接访问应用程序

获取客户端ip的方式为:

request.getHeader("x-forwarded-for")

以下是网友的见解,抽空梳理下:

3、这段代码可以收藏一下:

/** * 获取当前客户端ip * @param request * @return */  public static String getClientIpAddr(HttpServletRequest request){  String clientIp = request.getHeader("x-real-ip");System.out.println("x-real-ip:"+clientIp);String ipAddress = request.getHeader("x-forwarded-for");  System.out.println("x-forwarded-for:"+ipAddress);if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {  ipAddress = request.getHeader("Proxy-Client-IP");  }  if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {  ipAddress = request.getHeader("WL-Proxy-Client-IP");  } if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {  ipAddress =request .getRemoteAddr();System.out.println("request .getRemoteAddr():"+ipAddress);if(ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")){  //根据网卡取本机配置的IP  InetAddress inet=null;  try {  inet = InetAddress.getLocalHost();  } catch (UnknownHostException e) {  e.printStackTrace();  }  ipAddress= inet.getHostAddress();  }  }  //对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割  if(ipAddress!=null && ipAddress.length()>15){ //"·".length() = 15  if(ipAddress.indexOf(",")>0){  ipAddress = ipAddress.substring(0,ipAddress.indexOf(","));  }  }  return ipAddress;   }

remote_addr:

代表客户端的IP,但它的值不是由客户端提供的,而是服务端根据客户端的ip指定的,当你的浏览器访问某个网站时,假设中间没有任何代理,那么网站的web服务器(Nginx,Apache等)就会把remote_addr设为你的机器IP,如果你用了某个代理,那么你的浏览器会先访问这个代理,然后再由这个代理转发到网站,这样web服务器就会把remote_addr设为这台代理机器的IP。

x_forwarded_for:

正如上面所述,当你使用了代理时,web服务器就不知道你的真实IP了,为了避免这个情况,代理服务器通常会增加一个叫做x_forwarded_for的头信息,把连接它的客户端IP(即你的上网机器IP)加到这个头信息里,这样就能保证网站的web服务器能获取到真实IP。
通过名字就知道,X-Forwarded-For 是一个扩展头。HTTP/1.1(RFC 2616)协议并没有对它的定义,X-Forwarded-For最开始是由 Squid 这个缓存代理软件引入,用来表示 HTTP 请求端真实 IP,现在已经成为事实上的标准,被各大 HTTP 代理、负载均衡等转发服务广泛使用,并被写入 RFC 7239 (Forwarded HTTP Extension)标准之中。

X-Forwarded-For 请求头格式非常简单,就这样:

X-Forwarded-For: client, proxy1, proxy2
可以看到,XFF 的内容由「英文逗号 + 空格」隔开的多个部分组成,最开始的是离服务端最远的设备 IP,然后是每一级代理设备的 IP。

如果一个 HTTP 请求到达服务器之前,经过了三个代理 Proxy1、Proxy2、Proxy3,IP 分别为 IP1、IP2、IP3,用户真实 IP 为 IP0,那么按照 XFF 标准,服务端最终会收到以下信息:

X-Forwarded-For: IP0, IP1, IP2【IP0是真正的ip】
Proxy3 直连服务器,它会给 XFF 追加 IP2,表示它是在帮 Proxy2 转发请求。列表中并没有 IP3,IP3 可以通过服务端的 Remote Address 字段获得。我们知道 HTTP 连接基于 TCP 连接,HTTP 协议中没有 IP 的概念,Remote Address 来自 TCP 连接,表示与服务端建立 TCP 连接的设备 IP,在这个例子里就是 IP3。
Remote Address 无法伪造,因为建立 TCP 连接需要 三次握手,如果伪造了源 IP,无法建立 TCP 连接,更不会有后面的 HTTP 请求。
如果用户真的是通过代理访问 Nginx, X-Forwarded-For 最后一节以及 X-Real-Ip 得到的是代理的 IP,安全相关的场景只能用这个,但有些场景如根据 IP 显示所在地天气,就需要尽可能获得用户真实 IP,这时候 X-Forwarded-For 中第一个 IP 就可以排上用场了

X-Forwarded-For变量:
squid开发,用于识别通过 HTTP代理(或 负载均衡器)原始IP一个连接到Web服务器的客户机地址
默认是没有的,需要强制添加,如果做了X-Forwarded-For设置的话,每次经过proxy转发都会有记录,格式就是client1, proxy1, proxy2,以逗号隔开各个地址
意思是增加一个$proxy_add_x_forwarded_for到X-Forwarded-For里去,注意是增加,而不是覆盖
由于默认的X-Forwarded-For值是空的,所以我们总感觉X-Forwarded-For的值就等于$proxy_add_x_forwarded_for的值,
实际上当你搭建两台nginx在不同的ip上,并且都使用了这段配置,
那你会发现在web服务器端通过request.getAttribute("X-Forwarded-For")获得的将会是客户端ip和第一台nginx的ip。

$http_x_forwarded_for
这个变量就是X-Forwarded-For,由于之前我们说了, 默认的这个X-Forwarded-For是为空的,
所以当我们直接使用proxy_set_header X-Forwarded-For $http_x_forwarded_for时会发现,
web服务器端使用request.getAttribute("X-Forwarded-For")获得的值是null【笔者亲测

如果想要通过request.getAttribute("X-Forwarded-For")获得用户ip,
就必须先使用proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;这样就可以获得用户真实ip。

青云软负载测试过程中获取ClientIP那点事儿相关推荐

  1. php负载均衡如何获得真实ip,nginx负载均衡后端RS中获取真实ip

    nginx负载均衡后端RS中获取真实ip 前端proxy配置 #################### worker_processes  1; events { worker_connections ...

  2. Android中获取软键盘状态和软键盘高度

    应用场景 在Android应用中有时会需要获取软键盘的状态(即软键盘是显示还是隐藏)和软键盘的高度.这里列举了一些可能的应用场景. 场景一 当软键盘显示时,按下返回键应当是收起软键盘,而不是回退到上一 ...

  3. 负载均衡中使用 Redis 实现共享 Session

    最近在研究Web架构方面的知识,包括数据库读写分离,Redis缓存和队列,集群,以及负载均衡(LVS),今天就来先学习下我在负载均衡中遇到的问题,那就是session共享的问题. 一.负载均衡 负载均 ...

  4. 几种软负载均衡策略分析

    版权声明:本文为Sunface原创文章,请随意转载,若有需要敬请联系CTO@188.com.同时欢迎大家加入Golang隐修会,QQ群894864,大神很多. 公司去年上了F5,好用是好用,但是费用太 ...

  5. 但是尚未从池中获取连接_SQLServer超时时间已到,但是尚未从池中获取连接

    小编最近开发了一个项目,数据库是SQLServer2008R2,在WinForm程序通过API接口短时间大批量上传数据时,出现了错误"超时时间已到,但是尚未从池中获取连接",数据是 ...

  6. 一文搞懂负载均衡中的一致性哈希算法

    一致性哈希算法在很多领域有应用,例如分布式缓存领域的 MemCache,Redis,负载均衡领域的 Nginx,各类 RPC 框架.不同领域场景不同,需要顾及的因素也有所差异,本文主要讨论在负载均衡中 ...

  7. 一致性 Hash 在负载均衡中的应用

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:干掉 Navicat:这个 IDEA 的兄弟真香!个人原创100W+访问量博客:点击前往,查看更多 转自:Mar ...

  8. [MySQL 源码] 从buffer pool中获取空闲block流程

    当我们将一个page读入内存时,需要先为其分配一个block,从buffer pool中获取.入口函数为buf_LRU_get_free_block 之前在http://mysqllover.com/ ...

  9. mysql 硬负载_软负载均衡和硬负载均衡

    一.负载均衡 负载均衡 建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽.增加吞吐量.加强网络数据处理能力.提高网络的灵活性和可用性. 负载均衡,英文名称为 Load ...

最新文章

  1. linux下数据库的基本管理,数据库的管理_linux 运维之道 基础篇的技术博客_51CTO博客...
  2. 简易贪吃蛇小游戏java版_用GUI实现java版贪吃蛇小游戏
  3. html文本最小长度,CSS中处理不同长度文本的几种小技巧
  4. 连载四:Oracle升级文章大全(完结篇)
  5. 【数据分析】脑图简介数据分析
  6. Webstrom史上总结超实用教程
  7. AKOJ-2021-逆序对(归并,二分)
  8. qtcreator 代码格式化工具使用
  9. 下载离线 Visual Studio 离线安装包
  10. 芒果 mysql插件,NoSQL代表:MongoDB(芒果数据库)
  11. Autocad中批量调整增强属性块中的元素的位置
  12. vs2010 solidworks2015 c# add-in模板 二次开发
  13. C语言#error的使用
  14. [译]Hierarchical Macro Strategy Model for MOBA Game AI(王者荣耀)--翻译
  15. OpenCV API使用笔记 —— 4. 如何保存视频文件
  16. Java 获取年份-月份
  17. 可重入函数与线程安全的区别与联系
  18. 栈和队列---算法题目
  19. Navicat Premium 12.0.18 / 12.0.24安装与激活
  20. 【MySQL】19-MySQL中如何创建数据库和管理数据库

热门文章

  1. vant日期选择器使用
  2. 卷积层、卷积层里的填充和步幅
  3. 爬虫学习笔记1——Python基本语法
  4. xadmin开发后台管理系统常见问题
  5. 在模仿中精进数据分析与可视化01——颗粒物浓度时空变化趋势(Mann–Kendall Test)
  6. Chapter4:Traing Model
  7. Codeforces Round #777 (Div. 2) 题解
  8. 某知名IT公司最近的一道笔试编程题
  9. 华为WLAN技术:AP上线及相关模板的配置实验
  10. 千峰java 笔记整理_千锋--多线程笔记