分享好友 系统运维首页 频道列表

nginx 之 proxy_pass的使用

Nginx教程  2023-02-13 17:380

使用注意事项

proxy_pass在nginx中作代理转发使用。如果在proxy_pass后面的url加/,表示绝对根路径;如果没有/,表示相对路径,把匹配的路径部分也给代理走。

假设下面四种情况分别用 http://192.168.1.1/proxy/test.html 进行访问。

第一种:
location /proxy/ {
proxy_pass http://127.0.0.1/;
}
代理到URL:http://127.0.0.1/test.html

第二种(相对于第一种,最后少一个 / )
location /proxy/ {
proxy_pass http://127.0.0.1;
}
代理到URL:http://127.0.0.1/proxy/test.html

第三种:
location /proxy/ {
proxy_pass http://127.0.0.1/aaa/;
}
代理到URL:http://127.0.0.1/aaa/test.html

第四种(相对于第三种,最后少一个 / )
location /proxy/ {
proxy_pass http://127.0.0.1/aaa;
}
代理到URL:http://127.0.0.1/aaatest.html

两个proxy_pass的关系和区别

nginx中有两个模块都有proxy_pass指令。分别对应server和location中。

  • ngx_http_proxy_moduleproxy_pass

语法: proxy_pass URL;场景: location, if in location, limit_except,说明: 设置后端代理服务器的协议(protocol)和地址(address),以及location中可以匹配的一个可选的URI。协议可以是"http"或"https"。地址可以是一个域名或ip地址和端口,或者一个 unix-domain socket 路径。 详见官方文档: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_passURI的匹配,本文第四部分重点讨论。

  • ngx_stream_proxy_moduleproxy_pass

语法: proxy_pass address;场景: server,说明: 设置后端代理服务器的地址。这个地址(address)可以是一个域名或ip地址和端口,或者一个 unix-domain socket路径。 详见官方文档: http://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_pass

在两个模块中,两个proxy_pass都是用来做后端代理的指令。
ngx_stream_proxy_module模块的proxy_pass指令只能在server段使用使用, 只需要提供域名或ip地址和端口。可以理解为端口转发,可以是tcp端口,也可以是udp端口。
ngx_http_proxy_module模块的proxy_pass指令需要在location段,location中的if段,limit_except段中使用,处理需要提供域名或ip地址和端口外,还需要提供协议,如"http"或"https",还有一个可选的uri可以配置。

proxy_pass的具体用法

ngx_stream_proxy_module模块的proxy_pass指令

server {
    listen 127.0.0.1:12345;
    proxy_pass 127.0.0.1:8080;
}
 
server {
    listen 12345;
    proxy_connect_timeout 1s;
    proxy_timeout 1m;
    proxy_pass example.com:12345;
}
 
server {
    listen 53 udp;
    proxy_responses 1;
    proxy_timeout 20s;
    proxy_pass dns.example.com:53;
}
 
server {
    listen [::1]:12345;
    proxy_pass unix:/tmp/stream.socket;
}

ngx_http_proxy_module模块的proxy_pass指令

server {
    listen      80;
    server_name www.test.com;
 
    # 正常代理,不修改后端url的
    location /some/path/ {
        proxy_pass http://127.0.0.1;
    }
 
    # 修改后端url地址的代理(本例后端地址中,最后带了一个斜线)
    location /testb {
        proxy_pass http://www.other.com:8801/;
    }
 
    # 使用 if in location
    location /google {
        if ( $geoip_country_code ~ (RU|CN) ) {
            proxy_pass http://www.google.hk;
        }
    }
 
    location /yongfu/ {
        # 没有匹配 limit_except 的,代理到 unix:/tmp/backend.socket:/uri/
        proxy_pass http://unix:/tmp/backend.socket:/uri/;;
 
        # 匹配到请求方法为: PUT or DELETE, 代理到9080
        limit_except PUT DELETE {
            proxy_pass http://127.0.0.1:9080;
        }
    }
 
}

proxy_pass后,后端服务器的url(request_uri)情况分析

server {
    listen      80;
    server_name www.test.com;
 
    # 情形A
    # 访问 http://www.test.com/testa/aaaa
    # 后端的request_uri为: /testa/aaaa
    location ^~ /testa/ {
        proxy_pass http://127.0.0.1:8801;
    }
    
    # 情形B
    # 访问 http://www.test.com/testb/bbbb
    # 后端的request_uri为: /bbbb
    location ^~ /testb/ {
        proxy_pass http://127.0.0.1:8801/;
    }
 
    # 情形C
    # 下面这段location是正确的
    location ~ /testc {
        proxy_pass http://127.0.0.1:8801;
    }
 
    # 情形D
    # 下面这段location是错误的
    #
    # nginx -t 时,会报如下错误: 
    #
    # nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular 
    # expression, or inside named location, or inside "if" statement, or inside 
    # "limit_except" block in /opt/app/nginx/conf/vhost/test.conf:17
    # 
    # 当location为正则表达式时,proxy_pass 不能包含URI部分。本例中包含了"/"
    location ~ /testd {
        proxy_pass http://127.0.0.1:8801/;   # 记住,location为正则表达式时,不能这样写!!!
    }
 
    # 情形E
    # 访问 http://www.test.com/ccc/bbbb
    # 后端的request_uri为: /aaa/ccc/bbbb
    location /ccc/ {
        proxy_pass http://127.0.0.1:8801/aaa$request_uri;
    }
 
    # 情形F
    # 访问 http://www.test.com/namea/ddd
    # 后端的request_uri为: /yongfu?namea=ddd
    location /namea/ {
        rewrite    /namea/([^/]+) /yongfu?namea=$1 break;
        proxy_pass http://127.0.0.1:8801;
    }
 
    # 情形G
    # 访问 http://www.test.com/nameb/eee
    # 后端的request_uri为: /yongfu?nameb=eee
    location /nameb/ {
        rewrite    /nameb/([^/]+) /yongfu?nameb=$1 break;
        proxy_pass http://127.0.0.1:8801/;
    }
 
    access_log /data/logs/www/www.test.com.log;
}
 
server {
    listen      8801;
    server_name www.test.com;
    
    root        /data/www/test;
    index       index.php index.html;
 
    rewrite ^(.*)$ /test.php?u=$1 last;
 
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass unix:/tmp/php-cgi.sock;
        fastcgi_index index.php;
        include fastcgi.conf;
    }
 
    access_log /data/logs/www/www.test.com.8801.log;
}

文件: /data/www/test/test.php

<?php
echo '$_SERVER[REQUEST_URI]:' . $_SERVER['REQUEST_URI'];

通过查看 $_SERVER['REQUEST_URI'] 的值,我们可以看到每次请求的后端的request_uri的值,进行验证。

小结

  • proxy_pass后带一个URI,可以是斜杠(/)也可以是其他uri,对后端request_uri变量的影响。
  • 当location为正则表达式时,proxy_pass不能包含URI部分。
  • 可以通过变量($request_uri, 也可以是其他变量),对后端的request_uri进行改写。
  • 通过rewrite配合break标志,对url进行改写,并改写后端的request_uri。需要注意,proxy_pass地址的URI部分在情形G中无效,不管如何设置,都会被忽略。
参考:https://www.jianshu.com/p/b010c9302cd0,作者:金星show

 

查看更多关于【Nginx教程】的文章

展开全文
相关推荐
反对 0
举报 0
评论 0
图文资讯
热门推荐
优选好物
更多热点专题
更多推荐文章
Nginx端口占用问题
错误信息:nginx: [emerg] listen() to 0.0.0.0:80, backlog 511 failed (98: Address already in use)主要是端口被占用,通过如下命令,可以查看该端口被那个应用占用:sudo netstat -ntpl 然后kill -9 PID将其杀死关闭即可解决

0评论2023-02-13565

Linux使用nginx反向代理。可实现域名指向特定端口
在配置80指向域名的时候出现端口占用,使用kill -9无法杀死端口,应使用下面的命令来杀死进程killall -9 nginx(使用完本命令需要再把配置过的配置文件重新启动。命令写在了PS下面)后在root权限下的nginx的sbin下使用./nginx -t(命令重启nginx并检查是否有语

0评论2023-02-13636

装tomcat和nginx心得
开机启动tomcat1:在/etc/rc.d/init.d目录下生成一个文件tomcat80802:在文件里添加如下内#!/bin/bash#2345 linux运行级别#10开机启动优先级,数值越大越排在前面,最大值100#90关机优先级#chkconfig:2345 10 90#description: tomcat8080 start....start(){ec

0评论2023-02-13333

用Nginx代理请求,处理前后端跨域 用nginx代理请求,处理前后端跨域文件
  自从前端spa框架出现后,都是前后端分离开发了。我们在开发的时候难免会遇到跨域的问题。跨域这种问题解决的方法基本都是在服务端实现的。以java为例,我知道的有3种方法处理跨域:  1.使用 @CrossOrigin 注解对每一个接口进行跨域处理,缺点是比较麻烦

0评论2023-02-13771

手动上传图片到nginx下可访问,程序上传后访问图片报403
1. 首先查看文件权限2. 初步确定是服务器权限问题2.1 解决方案一:更改文件权限2.2 解决方案二:修改nginx运行用户 1. 首先查看文件权限#指令如下ls -l2. 初步确定是服务器权限问题403 forbidden错误是禁止读取访问,也就是说服务器理解了请求,但是不允许访问

0评论2023-02-13745

check nginx配置文件错误:[emerg]: getpwnam(“nginx”) failed
 1、错误提示:[root@server include]# /application/nginx/sbin/nginx -t -c /applications/nginx/nginx/nginx.confnginx: [emerg] getpwnam("nginx") failed in /applications/nginx/nginx/nginx.conf:2nginx: configuration file /application/nginx/ngin

0评论2023-02-13620

Nginx 499的问题 PHP 异步 HTTP 与 NGINX 499
PHP 异步 HTTP在 PHP 代码中提交异步 HTTP 请求比较常用的方式是通过 fsockopen/fwrite/fclose 来实现,请参考如下代码。function post($host, $path, $port, $data) {$post = http_build_query($data);$len = strlen($post);$fp = fsockopen($host, $port,

0评论2023-02-13458

nginx FastCGI模块(FastCGI)配置
http://www.howtocn.org/nginx:nginx%E6%A8%A1%E5%9D%97%E5%8F%82%E8%80%83%E6%89%8B%E5%86%8C%E4%B8%AD%E6%96%87%E7%89%88:standardhttpmodules:fastcginginx官方文档:http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html 摘要这个模块允许nginx

0评论2023-02-10486

nginx+tomcat反向代理下使用tomcat-redis-session-manager进行session共享中值得注意的一个问题
公司目前项目使用nginx反向代理+多个tomcat进行负载均衡,之前使用ip_hash策略进行session控制。近期有考虑不再使用ip_hash策略,所以需要进行session共享。根据项目实际情况,拟考虑使用开发配置比较简单,应用比较广泛的tomcat-redis-session-manager方式进

0评论2023-02-10303

nginx报错:./configure: error: C compiler cc is not found, gcc 是已经安装了的
源码安装nginx报错,找不到gcc,但是实际上gcc是存在的,如下:# ./configure checking for OS + Linux 3.10.0-957.el7.x86_64 x86_64checking for C compiler ... not found./configure: error: C compiler cc is not found#  尝试找寻gcc# whereis gccgcc: /

0评论2023-02-10667

更多推荐