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 ...
随机推荐
- Linux shell while
sh count=1 while [ $count -le 5 ]; do echo 1234567890abcdefghqwertyuiopdasdk > /dev/ttyS1 & e ...
- Eclipse 下安装 SVN的方法
http://welcome66.iteye.com/blog/1845176 eclipse里安装SVN插件,一般来说,有两种方式: 直接下载SVN插件,将其解压到eclipse的对应目录里 使用e ...
- 在Linux下用make指令编译进度条程序。
首先建立一个新的文件,touch progress_bar.c 运行该vim progress_bar.c命令.写进度条的程序. 写进一个进度条程序: #include<stdio.h> ...
- Spring Cloud / Spring Boot There was an unexpected error (type=Unauthorized, status=401). Full authentication is required to access this resource.
访问EndPoint时会出现没有权限 There was an unexpected error (type=Unauthorized, status=401). Full authenticat ...
- eclipse创建文件夹河包
资源的平常使用的主要有三种source/fold/package
- JavaScript开源跨平台框架NativeScript
NativeScript是一款使用JavaScript语言来构建跨平台原生移动应用的开源框架,支持iOS.Android和Windows Phone.且NativeScript的使用没有过多繁杂的要求 ...
- Sword protobuf学习四
#include <iostream> #include <string> #include <sys/types.h> /* See NOTES */ #incl ...
- .NET Framework posters with Namespaces & Types
Framework is platform containing a huge library of types, methods, classes, etc., cataloged into nam ...
- HBase原理、设计与优化实践
转自:http://www.open-open.com/lib/view/open1449891885004.html 1.HBase 简介 HBase —— Hadoop Database的简称,G ...
- strcpy_s与strcpy的区别
strcpy_s和strcpy()函数的功能几乎是一样的.];];strcpy_s(str1,,;}#include<iostream> #include<]; ]; strcpy ...