在大型服务器网关中,一台机器配置了几百个IP(每个IP对应一个域名,HTTPS中需要支持不带SNI的请求),每个域名有着不同的后端,但是如果按照默认路由,则可能存在只有一个物理IP与所有的后端建立连接,从而导致四元组地址耗尽。
因此期望的是用户访问IP1,则IP1与后端建立连接,用户访问IP2,则IP2与后端建立连接,nginx中的指令proxy_bind则可以解决这个场景。
基本原理是通过bind()和setsocket()来实现。
Syntax: proxy_bind address [transparent] | off;
Default: —
Context: http, server, location
指令说明:该指令第一次出现在0.8.22版本,设置到代理服务器的连接地址,参数可以包含变量。The transparent parameter (1.11.0) allows outgoing connections to a proxied server originate from a non-local IP address, for example, from a real IP address of a client:
示例:
proxy_bind $remote_addr transparent;
proxy_bind 127.0.0.1;
在ngx_http_upstream_init_request中调用ngx_http_upstream_set_local,主要是处理proxy_bind逻辑,设置pc->local和pc->transparent。
ngx_event_connect_peer是真正的处理和后端的连接,主要流程是:
(1)建立socket();
(2)设置NONBLOCK;
(3)设置SO_REUSEADDR;
(4)设置transport相关选项;
(5)bind;
(6)connect;