0. 反向代理和正向代理
先上图:
正向代理是针对client的,client发出的请求会经过代理服务器,然后到达外面的internet,通过这样来交流.
反向代理是针对server的,当代理服务器获取到请求时,根据配置再分发给相应的server来处理.
负载均衡就是一种反向代理
1. 反向代理实例
代理的是Node.js服务器:
http {
upstream node_app {
server 127.0.0.1:3000; # 具体的地址
}
server {
listen *:80;
root /path/to/application/public; # 根目录
location / { # 请求入口
try_files $uri $uri/index.html @node; # 从左到右try
}
location @node { # named location
proxy_pass http://node_app; # 传递到node_app
}
}
}
这个是nginx的配置,通过这个配置,nginx代理服务器运行后,接收到请求后会通过判断进入127.0.0.1:3000
这个端口,而这个端口应该是node.js服务器监听的端口,这样就代理过来了.
2. 自定义错误页面
使用error_page
指令:
server {
listen *:80;
root /path/to/application/public;
location / {
error_page 404 /404.html; # 自定义 404页面
error_page 500 502 503 504 /50x.html; # 自定义50x页面
try_files $uri $uri/index.html @rails;
}
location @rails {
proxy_pass http://rails_app;
}
}
error_page
还可以做其他的:
location / {
error_page 500 =200 /index.html; # 改变状态码
error_page 500 http://www.google.com; # 转向外部的网站
error_page 404 = @fallback; # 转向内部的@fallback
}
location @fallback {
proxy_pass http://different_backend;
}
3. 添加header
反向代理的机制是重新打开一个新的连接到后端服务器,并且这个连接包含客户端请求数据.
新的连接只带数据不带header(协议,域名等).
3.1 添加请求协议
下面使用proxy_set_header
指令和$scheme
变量来设置:
server {
listen *:80;
root /path/to/application/public;
location / {
try_files $uri $uri/index.html @rails;
}
location @rails {
proxy_set_header X-Forwarded-Proto $scheme; # $scheme变量包含的是客户端请求的协议http或https这些.
proxy_pass http://rails_app;
}
}
proxy_set_header
指令需要跟一个header,这个通常用X-Forwarded-Proto
来表示,具体的我也不清楚.......
使用proxy_set_header
之后将会将Host header
设置到$proxy_host
这个变量里面,然后它会把值传递到$proxy_pass
.
还可以重写$host
:
proxy_set_header Host $host;
3.2 获取真实IP
有这样一个问题: 一个客户端(203.0.113.1)发了一个请求到你的代理服务器(192.0.2.9),然后你的代理服务器将请求转发到后端服务器,那后端服务器中解析到的客户端ip是什么呢?
答案:192.0.2.9.因为后端服务器服务器接收到的是代理服务器发出的请求。
后端服务器要获取客户端真实ip,首先要打开RealIP
模块:--with-http_realip_module
.(默认打开的).然后在配置中用real_ip_header
指令设置header(默认X-REAL-IP
):
http {
real_ip_header X-Real-IP;
server {
...
}
}
- 当
RealIP
模块安装后是这个指令默认是打开的,但是最好还是在配置文件打开.- 可以直接这样设置
proxy_set_header X-Real-IP $remote_addr;
.
还可以使用set_real_ip_from
指令来设置信任的ip来源,同理可以设置CIDR
来屏蔽:
http {
real_ip_header X-Real-IP;
set_real_ip_from 203.0.113.1;
set_real_ip_from 203.0.113.1;
set_real_ip_from 203.0.113.2;
set_real_ip_from 203.0.113.0/24;
server {
...
}
}