Nginx 向客户端输出真实的后端IP地址
因为涉及到内外网的改造,所以狠多东西现在需要依赖于openresty来做总控实现。然后就碰见了一个比较难办的问题,即在upstream时候,如何获取实际处理请求的server地址。假设有如下upstream配置:
upstream backend {
server 127.0.0.1:
server 127.0.0.1:
}
location /test {
proxy_pass http://backend2
}
当我请求test的时候,我同时想直到到底是backend的哪一个server处理了,也就是我想得到实际处理的server地址。对于这个问题,我想了狠久,也走了狠多弯路,浪费了不少时间。
server return local ip?
首先,最简单的做法,就是对于实际的upstream server,在处理test这个请求的时候返回自己的ip地址就可以了,不过这种方法通用性太差,并且如果该server有多ip,可能取得的本机ip跟upstream里面配置的还不一样。
get upstream conf module?
然后,我想是不是nginx提供了一个模块,能够读取conf解析之后的所有信息,对这个模块的查找让我走了弯路,google了一下,发现没有相关东西,我还狠sb的一直不停的搜索。也不想想即使有这样的模块,如果我想要实现这个功能也是一件不怎么容易的事情。
upstream_addr
等到走了一些弯路,才发现nginx的upstream本来就有一个upstream_addr的模块,一下子我觉得找到了方向,不过看这个变量的说明,发现它主要用在记录log上面,而且没说明外界如何获取。查了一些资料之后,发现nginx有一个add_header,该指令干的事情就是在http response header里面加入自己定义的header,于是我在conf里面添加了这条指令,如下:
locaiton /test {
add_header Kss-Upstream $upstream_addr
proxy_pass http://backend2
}
这样,当我访问test的时候,response header里面就会有响应server的地址。
request:
curl -i http://127.0.0.1/test
response:
HTTP/1.1 200 OK
Kss-Upstream: 127.0.0.1:8888
subrequest response header
如果直接请求test,会狠好的得到upstream的addr,但是,如果是subrequest请求,就发现得不到了,如下:
location /test1 {
local res = ngx.location.capture("/test")
ngx.say(res.header["Kss-Upstream"])
}
请求test1的时候,发现subrequest的response header里面根本没有Kss-Upstream这个字段。当时狠迷惑,google之后发现这个:Headers not returned from subrequest,原来,subrequest的header是不会返回到parent request这个层面的。至于如何处理,我按照上面的说明采用了两种做法,发现都可行。
more_set_headers
agentzh举了more_set_headers这种做法的一个例子,直接把add_header换成more_set_headers "Kss-Upstream: $upstream_addr"2这条语句搞定。
header_filter_by_lua
另一个做法就是使用header_filter_by_lua这个指令,该指令是处理header response filter的,在里面将upstream_addr的值设置到nginx的一个变量里面。如下:
location /test {
proxy_pass http://_test2
header_filter_by_lua
ngx.var.upaddr = ngx.var.upstream_addr
}
location /test1 {
set $upaddr
content_by_lua
local res = ngx.location.capture("/test", {share_all_vars = true})
ngx.say(ngx.var.upaddr)
}
对于这种方式,实现较为繁琐,首先需要定义一个变量用来存储upstream_addr的值,同时在capture的时候还需要设置share_all_vars为true。鉴于此,还是使用more_set_headers这条语句方便狠多。
后来我又实现了一下,发现没必要这么复杂,完全可以不需要变量传递,只是在header_filter_by_lua里面这么做就可以了
header_filter_by_lua
ngx.header.kss_upstream_add = ngx.var.upstream_addr
记录下,送给不知道的朋友!
Nginx 向客户端输出真实的后端IP地址的更多相关文章
- JAVA获取客户端请求的当前网络ip地址(附:Nginx反向代理后获取客户端请求的真实IP)
1. JAVA获取客户端请求的当前网络ip地址: /** * 获取客户端请求的当前网络ip * @param request * @return */ public static String get ...
- 【Python】 http客户端库requests & urllib2 以及ip地址处理IPy
requests requests是个HTTPClient库,相比于urllib,urllib2等模块比更加简洁易用 ■ get请求 作为示例,讲一下关于requests如何发起并处理一个get请求 ...
- openstack私有云布署实践【19 通过python客户端 创建实例VM指定IP地址】
还有一种创建方式 是使用py开发工具,调用openstackclient的方法进行创建实例 ,好处就是可随意指定我们要的虚拟机IP地址,需求的场景就是,某天我们需要主动分配一个比较熟知的IP用作某个服 ...
- 【PHP开发篇】一个统计客户端商机提交的获取IP地址
1.对客服提交数据的ip地址记录. 获取ip地址的方法: public function getIP() { global $ip; if (getenv("HTTP_X_REAL_IP&q ...
- openresty(nginx)中使用lua脚本获取请求IP地址的代码
人狠话不多,直接上代码:------------------------------------------------------------------------------------- lo ...
- VMware虚拟机的CentOS7安装Nginx后本机用CentOS的IP地址无法访问
因为CentOS7的默认防火墙改成了Firewall,不再使用iptables为默认防火墙了 所以需要使用以下命令添加80端口 firewall-cmd --zone=public --add-por ...
- CDN下nginx获取用户真实IP地址
随着nginx的迅速崛起,越来越多公司将apache更换成nginx. 同时也越来越多人使用nginx作为负载均衡, 并且代理前面可能还加上了CDN加速,但是随之也遇到一个问题:nginx如何获取用户 ...
- nginx 设置ip地址访问,但是设置域名访问不了
一.导语 在Nginx的设置过程中,ip地址能正常访问的,但是把ip地址转换成域名,就访问不了了,这个是怎么回事呢?今天来探讨一下 二.设置ip地址做负载均衡 2.1.server端 server { ...
- 查找“CDN、负载均衡、反向代理”等大型网络真实IP地址的方法
首先,CDN.负载均衡.反向代理还分为很多层,有时查出来的是最外层的 CDN 服务器群,真实的机器是不对外开放的,类似这样的: 用户 → CDN 网络 → 一台或多台真实机器 ↗ CDN Server ...
随机推荐
- RabbitMQ文档翻译——Hello World!(上)
文章主要翻译自RabbitMQ官方文档,主要是为了练习英语翻译,顺便学习一下RabbitMQ
- 【Web安全】越权操作——横向越权与纵向越权
参考:http://blog.csdn.net/github_39104978/article/details/78265433 看了上面的文章,对越权操作的概念还是比较模糊,不明确实际场景. 横向越 ...
- Kafka内核中的分布式机制实现
Kafka内核中的分布式机制实现 一个Topic中的所有数据分布式的存储在kafka集群的所有机器(broker)上,以分区(partition)的的形式进行数据存储:每个分区允许存在备份数据/备份分 ...
- ssh登陆并执行命令不退出
如果希望SSH登陆后先执行shell命令,可以这样: ssh user@ip -t "cd /data ; /bin/bash"
- 对比几种在ROS中常用的几种SLAM算法
在此因为要总结写一个文档,所以查阅资料,将总结的内容记录下来,欢迎大家指正! 文章将介绍使用的基于机器人操作系统(ROS)框架工作的SLAM算法. 在ROS中提供的五种基于2D激光的SLAM算法分别是 ...
- PCL常见错误集锦
来自微信公众号的分享 我刚刚开始接触PCL,懂的东西也很少,所以总是出现各种各样的问题,每次遇见问题的时候要查找各种各样的资料,很费时间.所以,今天我把我遇见的常见问题分享给大家,讲解的步骤尽量详细, ...
- openh264 api 使用
IS_PARAMETER_SET_NAL:是不是参数集nal 头文件codec_api.h codec_app_def.h codec_def.h codec_ver.h SEncParamExt.i ...
- Visual Studio 2008 添加MScomm控件的方法
1.下载MSCOMM.zip,解压后包含4个文件:MSCOMM32.OCX, MSCOMM.SRG, MSCOMM32.DEP, MSCOMM32.OCA 2.将Mscomm.srg, Mscomm3 ...
- r语言 load Rdata 获取表名 并直接转为数据表
首先指定 load结果为一个对象 然后此对象的值 即为 str的 数据表名 然后使用 eval(parse(text = l)) 两个函数 将字符串 转可执行对象 即可完成重新赋值 > l & ...
- vb 三种启动模式
正常启动不用说了 就是虚拟机和显示部分在同一个程序里进行 直接关闭程序 就都关闭了 相当于我们普通的电脑, 有主机和显示器无界面启动 也很好理解 ,就是在后台启动虚拟机,如同服务器, 我们只有一个主机 ...