# 以下只是自己总结,加深记忆
背景前提介绍:
工作需要,实现对二级nginx反向代理的备份请求;由于国内外网络不稳定原因。
拓扑:主站(北京BGP) 前端nginx,后端tomcat
自制CDN(nginx反向代理)
节点1: HK 香港
节点2:BM 北美
问题:BM nginx反向代理 到 北京BGP,由电信骨干网不稳定,时不时丢包与中断。
解决方案:在广州BGP 增加一个二级nginx反向代理,实现BM nginx反向代理故障,切换备份请求;从而变成了 三级nginx反向代理。
中间碰到问题:由于广州BGP节点,利用别的业务的资源。80端口被占用的情况,实现三级nginx不同端口之间的反向代理。如果使用同样的端口,部署没有什么问题与难度。
深入理解nginx server_name,proxy模块,nginx处理请求过程;变量:$hostname,$host,$http_host,$server_name,$server_port,$proxy_host,$proxy_port。
测试验证,增加nginx log配置信息,增加以上变量,用于观察:
log_format main ‘$remote_addr - $remote_user [$time_local] "$request" ‘
‘$status $body_bytes_sent "$http_referer" ‘
‘"$http_user_agent" "$http_x_forwarded_for" "[$hostname $host $http_host $server_name $server_port $proxy_host $proxy_port]"‘;
配置命令:server_name
三种类型的server_name: 精确命名,通配符命名,正则表达式命名
通配符命名:只能以*开头或结尾,并在.的前面或后面
正则表达式命令:以~开头标记
匹配顺序:精确命名 -> *开头通配符命令 -> *结尾通配符命名 —> 正则表达式命名
默认匹配server,当没有以上三种类型匹配到后;第一个定义的server为默认匹配或定义的listen 80 default;为默认匹配。
基于域名与基于IP的虚拟服务:
基于IP的虚拟服务:处理请求时,是要根据HTTP包的进入IP(网卡)+ 端口进行 匹配,然后再根据 server_name进行匹配,否则使用默认匹配server。
基于域名与IP的虚拟服务,都是根据 HTTP包头中的 "host"字段进行区别
三级(多级)nginx 反向代理的原理,及实现不同端口反向代理。
BM nginx 80 端口:
upstrean testweb {
server test1.test.com:82;
}
server {
listen 80;
server_name test2.test.com;
location / {
proxy_redirect off;
proxy_read_timeout 300;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_buffers 32 64k;
proxy_pass http://testweb;
expires epoch;
}
}
广州 nginx 82 端口:
upstrean testweb {
server www.test.com;
}
server {
listen 82;
server_name test1.test.com test2.test.com; 此处需要添加最前面反向代理的访问域名或者IP地址。
location / {
proxy_redirect off;
proxy_read_timeout 300;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_buffers 32 64k;
proxy_pass http://testweb;
expires epoch;
}
}
北京BGP nginx 80 端口:
upstrean testweb {
server 127.0.0.1:8080;
}
server {
listen 80;
server_name *.test.com;
location / {
proxy_redirect off;
proxy_read_timeout 300;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_buffers 32 64k;
proxy_pass http://testweb;
expires epoch;
}
}
nginx test2.test.com -> nginx test1.test.com:82 -> nginx www.test.com
如果 test1.test.com:82,不需要实现访问www.test.com,只需要中转代理的话,由于test2.test.com 与 www.test.com都是80端口, proxy_set_header Host $host;就可以了。否则应该设为:proxy_set_header Host $http_host;
非默认端口时,nginx 反向代理应该 传送给 tomcat服务 Host有端口,像这样:proxy_set_header Host $http_host;或 proxy_set_header Host $host:$server_port,还可以手动指定:proxy_set_header Host $host:82
变量:$hostname,$host,$http_host,$server_name,$server_port,$proxy_host,$proxy_port
$hostname: 本机的hostname的值
$host: http包头中的host值,默认不带端口;可以设置附加端口:proxy_set_header Host $http_host;
$http_host: client客户端请示地址+端口,一般为:域名:端口
$server_name:server中定义server_name的值
$server_port:server中定义listen的值
$proxy_host: proxy_pass(proxy_pass http://testweb;)中testweb值
$proxy_port:proxy_pass(proxy_pass http://testweb;)中端口值,默认端口为80;如果把端口定义在upstearm中,$proxy_port的值也是80。$proxy_port取值只取值proxy_pass指令后的端口值,不取upstream中的端口值。
nginx反向代理请求原理与过程:
示意:test2.test.com -(nginx反向代理)-> test1.test.com:82 -(nginx反向代理)-> www.test.com -(nginx反向代理)-> tomcat:8080
请求包头处理过程:
用户通过浏览器,访问test2.test.com;通过nginx匹配(通$host test2.test.com 匹配server段)后,通过反向代理模块,请求test1.test.com:82,并把用户的请求HTTP包转发给test1.test.com:82的nginx。
test1.test.com:82的nginx(通$host test2.test.com 匹配server段),进行处理。 接着test1.test.com:82对应的server段,通过反向代理模块,请求www.test.com,并把用户的请求HTTP包转发给www.test.com的nginx。
www.test.com的nginx,通过nginx匹配(通$host test2.test.com 匹配server段) 后,通过反向代理模块,请求tomcat:8080,并把用户的请求HTTP包转发给tomcat:8080处理。
tomcat:8080的网站程序,通过$host进行URL地址端口的取值,并构建对应资源URL地址(无端口值时,默认设置80)。由于test2.test.com与www.test.com使用的是默认80端口;proxy_set_header Host $host;用户http请求包头,可以不传送端口值;否则,一定要传送端口值(proxy_set_header Host $http_host;或 proxy_set_header Host $host:$server_por)。
响应包头处理过程:
tomcat:8080处理用户HTTP请求包后,返回HTTP响应包,给www.test.com的nginx;它们之间通过tcp链接通讯。
然后,www.test.com的nginx,把HTTP响应包,返回给test1.test.com的nginx;它们之间通过tcp链接通讯(先前请求时,建立的TCP链接通道)。
然后,test1.test.com的nginx,把HTTP响应包,返回给test2.test.com的nginx;它们之间通过tcp链接通讯(先前请求时,建立的TCP链接通道)。
最后,test2.test.com的nginx,把HTTP响应包,返回给用户请求HTTP的客户端;它们之间通过tcp链接通讯(先前请求时,建立的TCP链接通道)。
How nginx processes a request
http://nginx.org/en/docs/http/request_processing.html