Skip to content

Menu
Menu

配置反向代理

Posted on 2022年7月3日2022年7月5日 by zhezimi

什么是反向代理?

反向代理(Reverse Proxy)是指以代理服务器来接受Internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给Internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。

应用场景

代理通常用于在多个服务器之间分配负载,无缝显示来自不同网站的内容,或者通过HTTP之外的协议将处理请求传递给应用程序服务器。

当NGINX代理请求时,它会将请求发送到指定的代理服务器,获取响应并将其发送回客户端。

可以使用指定的协议将请求代理到HTTP服务器(另一个NGINX服务器或任何其他服务器)或非HTTP服务器(可以运行使用特定框架开发的应用程序,例如PHP或Python)。 支持的协议包括FastCGI,uwsgi,SCGI和memcached。

如何配置

要将请求传递给HTTP代理服务器,请在location内指定proxy_pass指令。 例如:

location /some/path/ {
    proxy_pass http://www.example.com/link/;
}

此示例配置导致将在此location处理的所有请求传递到指定地址的代理服务器。该地址可以指定为域名或IP地址。 地址还可能包含一个端口。

请注意,在上面的第一个示例中,代理服务器的地址后跟URI/link/。如果URI与地址一起指定,则它将替换与location参数匹配的请求URI部分。

例如,此处带有/some/path/page.html URI的请求将代理到http://www.example.com/link/page.html。 如果指定的地址没有URI,或者无法确定要替换的URI部分,则传递完整的请求URI。

要将请求传递给非HTTP代理服务器,应使用相应的**_pass指令:

  • fastcgi_pass将请求传递给FastCGI服务器
  • uwsgi_pass将请求传递给uwsgi服务器
  • scgi_pass 将请求传递给SCGI服务器
  • memcached_pass将请求传递给FastCGI服务器

proxy_pass指令也可以指向服务器的命名组。 在这种情况下,根据指定的方法在组中的服务器之间分配请求。

传递请求头部

默认情况下,NGINX在代理请求中重新定义两个header字段“Host”和“Connection”,并删除其值为空字符串的header字段。 “Host”设置为$ proxy_host变量,“Connection”设置为close。

要更改这些设置,以及修改其他header字段,请使用proxy_set_header指令。

可以在某个location或更高位置指定此指令。它也可以在特定的server 上下文或 http 块中指定。

例如:

location /some/path/ {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_pass http://localhost:8000;
}

在此配置中,“Host”字段设置为$host变量。

为了防止header字段被传递到代理服务器,将其设置为空字符串,如下所示:

location /some/path/ {
    proxy_set_header Accept-Encoding “”;
    proxy_pass http://localhost:8000;
}

配置缓冲

默认情况下,NGINX缓冲来自代理服务器的响应。响应存储在内部缓冲区中,直到接收到整个响应后才发送给客户端。

缓冲有助于优化慢客户端的性能,如果响应从NGINX同步传递到客户端,则会浪费代理服务器时间。但是,当启用缓冲时,NGINX允许代理服务器快速处理响应,而NGINX将响应存储的时间与客户端下载它们所需的时间相同。

负责启用和禁用缓冲的指令是proxy_buffering。默认情况下,它设置为on并启用缓冲。

proxy_buffers指令控制为请求分配的缓冲区的大小和数量。来自代理服务器的响应的第一部分存储在单独的缓冲区中,其大小使用proxy_buffer_size指令设置。这部分通常包含一个相对较小的响应头,可以使其小于响应其余部分的缓冲区。

在以下示例中,增加了默认缓冲区数,并使响应第一部分的缓冲区大小小于默认值。

location /some/path/ {   
    proxy_buffering off;   
    proxy_pass http://localhost:8000;
}

如果禁用缓冲,则响应将在从代理服务器接收响应时同步发送到客户端。对于需要尽快开始接收响应的快速交互式客户端,此行为可能是理想的。

要在特定位置禁用缓冲,使用off参数将proxy_buffering指令放置在location 中,如下所示:

location /some/path/ {   
    proxy_buffering off;   
    proxy_pass http://localhost:8000;
}

在这种情况下,NGINX仅使用proxy_buffer_size配置的缓冲区来存储响应的当前部分

如果代理服务器具有多个网络接口,有时您可能需要选择特定的源IP地址以连接到代理服务器或上游服务器。

如果将NGINX之后的代理服务器配置为接受来自特定IP网络或IP地址范围的连接,这可能很有用。

指定proxy_bind指令和必要的网络接口的IP地址:

location /app1/ {   
proxy_bind 127.0.0.1;
proxy_pass http://example.com/app1/;
}
location /app2/ {
proxy_bind 127.0.0.2;
proxy_pass http://example.com/app2/;
}

IP地址也可以用变量指定。例如,$server_addr变量传递接受请求的网络接口的IP地址:

location /app3/ {   
proxy_bind $server_addr;
proxy_pass http://example.com/app3/;
}

开始案例

front配置

server {
listen 80;
server_name test.front.com;

access_log /var/log/front_access.log;
error_log /var/log/front_error.log;

location /back1/api/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://test.back1.com:8081/api/;
}

location /back2 {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://test.back2.com:8082/;

}

location /back3 {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://test.back3.com:8083;
}
}

back1 back2 back3配置基本相同,只要把配置文件中的back1改为back2或者back3,以及把8081端口改为8082,8083就可以了。

server {
    listen 8081;
    server_name test.back1.com;
    index index.html index.htm index.php;
    root  /www/back1;

    location / {
        try_files $uri @rewriteapp;
    }

    location @rewriteapp {
        rewrite ^(.*)$ /index.php/$1 last;
    }

    access_log    /var/log/back1_access.log;
    error_log     /var/log/back1_error.log;

    location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc|mp3|swf|xlsx)$ {
        expires 1M;
        access_log off;
        add_header Cache-Control “public”;
   }

   location ~* \.(?:css|js|swf|xlsx)$ {
        expires 1y;
        access_log off;
        add_header Cache-Control “public”;
    }

    location ~ ^/.*\.php(/|$) {
        fastcgi_pass  127.0.0.1:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

}

然后我们在本地的/etc/host里面加上四个域名

127.0.0.1 test.front.com

127.0.0.1 test.back1.com

127.0.0.1 test.back2.com

127.0.0.1 test.back3.com

然后重启一下nginx。

接着我们在back1,back2,back3下面都创建一个index.php

$ cat index.php

<?php
echo 'server_name=' . ($_SERVER['SERVER_NAME']) . PHP_EOL;
echo 'request_uri=' . ($_SERVER['REQUEST_URI']);

然后我们访问一下

大家可能看到了,三个访问显示的request_uri都不一样,那我们再看一眼我们的配置文件

我们可以看到第一个location,这个的配置的意思是说将对应链接的参数中的/back1/api/替换为api/ http://test.front.com/back1/api/get/goods/100  参数为/back1/api/get/goods/100替换一下就成了/api/get/goods/100

第二个location的意思是指将/back2替换成/。http://test.front.com/back2/api/get/goods/100参数为/back2/api/get/goods/100 替换为/ 那就是//api/get/goods/100

第三个location的意思是不做任何替换,直接将对应链接的参数全部拿过来,那就是/back3/api/get/goods/100

注意:     

我们有时候配置代理服务器的时候一定要注意proxy_pass后面的/。像后面的back3情况,很可能/back3/api/get/goods/100是请求失败的,正确的请求应该是/api/get/goods/100。

参考链接:

https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/#intro

http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header

相关文章

  • rewrite讲解

  • 配置http负载均衡

发表评论 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注

近期文章

  • 排查网络故障常用命令
  • PHP-FPM异常问题
  • RabbitMQ 1:介绍
  • 观察者模式
  • 装饰者模式

近期评论

没有评论可显示。

分类

  • cdn
  • css
  • docker
  • git
  • http
  • javascript
  • linux
  • mysql
  • nginx
  • php
  • RabbitMQ
  • 代码规范
  • 性能
  • 正则表达式
  • 网络协议
  • 设计模式
© 2025 | Powered by Minimalist Blog WordPress Theme