反向代理
反向代理是nginx被使用的比较多的功能,nginx接收前端发送来的请求,根据所指定的不同的匹配规则,将请求转发到具体的服务器(组)去进行处理。
反向代理的设置通常使用proxy_pass指令,它支持多种格式,语法结构为:
proxy_pass URL;
URL是指定的用来接收处理请求的服务器地址,支持域名方式、IP(:PORT)方式以及unix套接字方式。
如果被代理服务器是一组服务器,则可以使用upstream来配置服务器组。
upstream my_servers1
{
server www.jjj.com;
server 10.0.0.1;
server 10.0.0.2:8090;
}
来看一个简单的配置:
upstream myaliyun {
server 45.93.23.19;
server 45.93.23.20;
}
server {
listen 9999;
location / {
proxy_pass http://myaliyun;
}
}
这是我本地虚拟机上的一套配置,监听了9999端口,将所有请求转发到myaliyun服务器组,这个服务器组包含了19/20两台服务器,因为没有指定方式,默认就会使用轮询方式分派请求。
所以,当执行请求http://10.0.0.1:9999/a.php时,请求被转发到19(或20)上http://45.93.23.19/a.php。
如果被代理的服务器有端口限制的话,在配置中需要指明,例如19服务器使用了1070端口:
server {
listen 9999;
location / {
proxy_pass http://45.93.23.19:1070;
}
}
这样在请求http://10.0.0.1:9999/a.php时,请求就会被转发到http://45.93.23.19:1070/a.php,有端口限制却未进行设置就会导致错误。
proxy_pass指令中的URL变量如何设置,对最后请求转发的结果有很大的影响。上面的例子中proxy_pass的URL参数都没有包含URI,所以请求是直接替换的URL地址部份,而URI部份参数并没有产生变化。
看下面这个例子,proxy_pass的URL参数包含了URI的情况:
server {
listen 9999;
location / {
proxy_pass http://45.93.23.19:1070/Api/;
}
}
server {
listen 9988;
location /server/ {
proxy_pass http://45.93.23.19:1070/Api/;
}
}
1、请求http://10.0.0.1:9999时,请求转发到的是http://45.93.23.19:1070/Api/index.html;
2、请求http://10.0.0.1:9988/server时,请求转发到的是http://45.93.23.19:1070/Api/index.html;
3、请求http://10.0.0.1:9988/server/a.php时,请求转发到http://45.93.23.19:1070/Api/a.php;
区别是什么?当proxy_pass的URL参数中包含了URI时,location匹配的部份会整个的被proxy_pass的URL参数给替换掉,URI就会发生变化。如果不希望请求的URI发生变化,那就不要指定proxy_pass的URL参数的URI。
还有一个proxy_pass的URL参数末尾是否加斜杠”/”的问题,如下的这种形式:
server {
listen 1122;
location /server/ {
#配置1
#proxy_pass http://45.93.23.19:1070;
#配置2
#proxy_pass http://45.93.23.19:1070/;
}
}
当放开配置1的注释使配置1生效时,访问http://10.0.0.1:1122/server/a.php,就会被转发到http://45.93.23.19:1070/server/a.php,整个URI是被完全转发的。
当放开配置2的注释使配置2生效时,访问http://10.0.0.1:1122/server/a.php,就会被转发到http://45.93.23.19:1070/a.php,URI被改变了。配置2末尾的”/”也相当于URI,它替换掉了/server/。
通常,被代理服务器接收到的请求头信息,都是nginx代理服务器的信息,如果希望得到真实的前端请求头信息,可以在location块中添加以下配置:
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
负载均衡
负载均衡和前面的反向代理是相关联的,主要用到的就是proxy_pass和upstream指令,通过upstream指令指定一个服务器组,以及服务器组内成员的负载分配方式,然后通过proxy_pass将请求转发到upstream指定的服务器组,由指定的负载分配方式来选择出1个接收处理请求的服务器实体。
负载分配方式默认为轮询方式,也可以选择加权轮询、 ip hash、url hash等其它方式。
upstream my_balance_servers
{
server 10.0.0.1:9999;
server 10.0.0.2:9999;
#server 10.0.0.3:9999 weight=2;
#weight表示加权值,不设置则默认为1,都不设置则表示使用一般轮询规则
#ip hash; #设置负载分配方式为ip hash
}
可以对特定的请求进行负载分担,例如有一组服务器提供html image浏览,另有一组服务器提供api接口调用,就可以分别指定它们的负载。
upstream image_balance_servers
{
server 10.0.0.1;
server 10.0.0.2;
server 10.0.0.3;
ip hash;
}
upstream api_balance_servers
{
server 10.0.0.10;
server 10.0.0.11;
}
server
{
listen 80;
……
location /image/ {
proxy_pass http://image_balance_servers;
}
location /api/ {
proxy_pass http://api_balance_servers;
}
}
这样,在调用http://ip:port/image/aa时,请求会被转发到image_balance_servers组中,使用ip hash规则来挑选出接收处理请求的服务器。
在调用http://ip:port/api/bbq时,请求会被转发到api_balance_servers服务器组中,使用一般轮询方式挑选出接收处理请求的服务器。