Because it involves the transformation of the Intranet and Internet, many things need to be implemented by openresty. Then we met a difficult problem, that is, how to obtain the server address that actually processes the request during upstream. Assume that the following upstream configuration is available:
upstream backend {server 127.0.0.1:88882server 127.0.0.1:88892}location /test {proxy_pass http://backend2}
When I request test, I also want to know which server is backend for processing, that is, the address of the server that I want to actually process. I have been thinking about this problem for a long time and have made many detours, wasting a lot of time.
Server return local IP?
First, the simplest way is to return your own IP address when processing the test request for the actual upstream server. However, this method is too versatile, if the server has multiple IP addresses, the local IP address may be different from that configured in upstream.
Get upstream conf module?
Then, I wondered if nginx provided a module that could read all the information parsed by Conf. Searching for this module gave me a detour. Google found that there was no such thing, I keep searching for sb. Even if there is such a module, it is not easy to implement this function.
Upstream_addr
After some detours, I found that nginx's upstream originally had an upstream_addr module. I thought I had found a direction, but I can see the description of this variable, it is found that it is mainly used to record logs, and does not explain how the outside world gets it. After checking some information, I found that nginx has an add_header. The task of this command is to add the custom header to the HTTP Response Header, so I added this command to the conf file, as follows:
locaiton /test {add_header Kss-Upstream $upstream_addr2proxy_pass http://backend2}
In this way, when I access test, the response header contains the address of the response 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
If you directly request test, you will get the ADDR of upstream. However, if it is a subrequest request, you will find that you cannot get it, as shown below:
location /test1 {local res = ngx.location.capture("/test")ngx.say(res.header["Kss-Upstream"])}
When requesting test1, we found that there was no KSS-upstream field in the Response Header of subrequest. At that time, I was confused. Google later found this: headers not returned from subrequest. It turns out that the header of subrequest will not be returned to the parent request level. As for how to handle the problem, I adopted two methods according to the above instructions, and found that both methods are feasible.
More_set_headers
Agentzh uses the statement more_set_headers to replace add_header with more_set_headers "KSS-upstream: $ upstream_addr" 2.
Header_filter_by_lua
Another way is to use the header_filter_by_lua command, which processes the header response filter and sets the upstream_addr value to a variable in nginx. As follows:
location /test {proxy_pass http://_test2header_filter_by_lua 1ngx.var.upaddr = ngx.var.upstream_addr12}location /test1 {set $upaddr 112content_by_lua 1local res = ngx.location.capture("/test", {share_all_vars = true})ngx.say(ngx.var.upaddr)12}
For this method, the implementation is cumbersome. First, you need to define a variable to store the upstream_addr value, and set pai_all_vars to true during capture. In view of this, we still useThe statement more_set_headers is much easier.
Later, I implemented it again and found that there is no need to make it so complex that it does not need to pass variables. Just do this in header_filter_by_lua.
header_filter_by_lua 1ngx.header.kss_upstream_add = ngx.var.upstream_addr
Record and send it to unknown friends!