文档章节

nginx之proxy_pass指令完全拆解

永福
 永福
发布于 2017/08/17 18:04
字数 1060
阅读 5841
收藏 265
点赞 12
评论 6

一、proxy_pass的nginx官方指南

nginx中有两个模块都有proxy_pass指令。

  • 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_pass
URI的匹配,本文第四部分重点讨论。
  • 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的关系和区别

在两个模块中,两个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的值,进行验证。

小结

情形A和情形B进行对比,可以知道proxy_pass后带一个URI,可以是斜杠(/)也可以是其他uri,对后端request_uri变量的影响。
情形D说明,当location为正则表达式时,proxy_pass不能包含URI部分。
情形E通过变量($request_uri, 也可以是其他变量),对后端的request_uri进行改写。
情形F和情形G通过rewrite配合break标志,对url进行改写,并改写后端的request_uri。需要注意,proxy_pass地址的URI部分在情形G中无效,不管如何设置,都会被忽略。

说明

本文永福原创,原文地址: https://my.oschina.net/foreverich/blog/1512304 永福原创,未经授权,不得转载!

© 著作权归作者所有

共有 人打赏支持
永福

永福

粉丝 28
博文 20
码字总数 21254
作品 0
长沙
技术主管
加载中

评论(6)

溪涧顽石
溪涧顽石
fuck good!收藏了~
O
OneToOne

引用来自“失去的青春”的评论

转走了

引用来自“BlueStragglers”的评论

怎么转的?只有收藏。
复制粘贴。操起键盘就是干:joy:
BlueStragglers
BlueStragglers

引用来自“失去的青春”的评论

转走了
怎么转的?只有收藏。
永福
永福

引用来自“灰灰”的评论

Nginx支持3层的NAT?而不局限于HTTP的转发
3层?应该说nginx即支持4层(ngx_stream_proxy_module模块)又支持7层代理,完整的http是请求就是7层的了。
灰灰
灰灰
Nginx支持3层的NAT?而不局限于HTTP的转发
oldDriverSS
oldDriverSS
转走了
Web内容缓存

1 介绍 当缓存被启用时,Nginx保存响应到磁盘缓存并每次请求相同的内容时不用代理请求使用它们响应客户端。 2 启用响应缓存 为了启用缓存,在http上下文设置proxycachepath指令。第一个强制参...

Leech
2016/08/05
28
0
Nginx反向代理

代理通常用于分发负载给多个服务器,从不同网站无缝显示内容,传递请求给能处理HTTP之外的应 用服务器。 1 传递请求给代理服务器 当Nginx代理请求时,它发送请求给一个特定的代理服务器,获取...

Leech
2016/08/04
100
0
Nginx接收PROXY协议

1 介绍 PROXY协议使Nginx接收客户端连接信息通过代理服务器和负载均衡器传入,例如HAproxy和亚马逊Elastic负载均衡器(SLB)。 通过PROXY协议传入的是客户端IP地址,代理服务器IP地址和端口号...

Leech
2016/08/08
103
0
nginx做反向代理proxy_pass,proxy_redirect的使用

今天用nginx作为trac的反代,发现一个问题,就是登入登出跳转的时候是白页,看了下网页相应内容,发现相应的location是空的。查了一下发现是只单纯用了proxypass,没有使用proxyredirect. 假...

adbug
2016/02/24
1K
0
配置Nginx前端Apache后端服务器

曾经对host2ez主机,它用的是nginx,但却能完美兼容apache感到很困惑,一番折腾后知道,原来只要由Nginx做前端处理静态文件,Apache做后端服务器即可,代价是可怜的内存又少了... 一、基础知...

hengfeng_su
2013/02/24
0
1
Nginx4大模块——proxy、headers、upstream、stream

   一:ngxhttpproxy_module 反向代理( reverse proxy) 方式是指用代理服务器来接受 Internet 上的连接请求, 然后将请求转发给内部网络中的上游服务器, 并将从上游服务器上得到的结果返...

yaohong
05/27
0
0
[译]NGINX Reverse Proxy

这篇文章介绍了一个代理服务器的基本配置。你将学习到如何通过不同的协议,从NGINX传递一个请求到一个代理服务器,修改传递到代理服务器的客户端的请求头,以及配置从代理服务器来的响应缓冲...

趁你还年轻233
06/26
0
0
nginx启动报错:nginx: [emerg] unknown directive "proxy_pass"

安装完 nginx-1.6.3 配置反向代理后 启动报: nginx: [emerg] unknown directive "proxy_pass" in /usr/local/nginx/conf/nginx.conf:47 安装时候命令如下: ./configure --prefix=/usr/loca......

yucan0827
2016/04/24
8.3K
1
nginx虚拟路径中proxy_pass对后端请求的影响

假设nginx中的配置是这样的: 那么,当用户请求http://x.x.x.x/subdir/other时,匹配到该区块,nginx反向代理到后端时会保留虚拟路径。nginx实际向后端发起的请求URL为http://y.y.y.y/subdir...

独指蜗牛
07/07
0
0
Nginx实现javaWeb项目动静分离

Nginx可以实现与Tomcat的耦合: 将静态页面请求交给Nginx,动态请求交给后端Tomcat处理。 将所有请求都交给后端的Tomcat服务器处理,同时利用Nginx自身的负载均衡功能进行多台Tomcat服务器的...

hello菜bird
2016/06/02
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

java集合元素的默认大小

当底层实现涉及到扩容时,容器或重新分配一段更大的连续内存(如果是离散分配则不需要重新分配,离散分配都是插入新元素时动态分配内存),要将容器原来的数据全部复制到新的内存上,这无疑使...

竹叶青出于蓝
6分钟前
1
0
Java快速开发平台,JEECG 3.7.7闪电版本发布,增加多套主流UI代码生成器模板

JEECG 3.7.7 闪电版本发布,提供5套主流UI代码生成器模板 导读 ⊙平台性能优化,速度闪电般提升 ⊙提供5套新的主流UI代码生成器模板(Bootstrap表单+BootstrapTable列表\ ElementUI列表表单)...

Jeecg
10分钟前
0
0
export 和 module.export 的区别

在浏览器端 js 里面,为了解决各模块变量冲突等问题,往往借助于 js 的闭包把左右模块相关的代码都包装在一个匿名函数里。而 Nodejs 编写模块相当的自由,开发者只需要关注 require,exports,...

孟飞阳
12分钟前
0
0
技术教育的兴起

技术教育的兴起 作者: 阮一峰 1、 有一年,我在台湾环岛旅行。 花莲的海边,我遇到一对台湾青年夫妻,带着女儿在海滩上玩。我们聊了起来。 当时,我还在高校当老师。他们问我,是否觉得台湾...

吕伯文
12分钟前
0
0
Linux服务器下的HTTP抓包分析

说到抓包分析,最简单的办法莫过于在客户端直接安装一个Wireshark或者Fiddler了,但是有时候由于客户端开发人员(可能是第三方)知识欠缺或者其它一些原因,无法顺利的在客户端进行抓包分析,...

mylxsw
17分钟前
0
0
mybatis3-javaapi

sqlSessionFactoryBuilder->sqlSessionFactory->sqlSession<-rowbound<-resultHandler myBatis uses a Java enumeration wrapper for transaction isolation levels, called TransactionIsol......

writeademo
20分钟前
0
0
Java NIO:浅析I/O模型

也许很多朋友在学习NIO的时候都会感觉有点吃力,对里面的很多概念都感觉不是那么明朗。在进入Java NIO编程之前,我们今天先来讨论一些比较基础的知识:I/O模型。下面本文先从同步和异步的概念...

yzbty23
20分钟前
0
0
了解iOS消息推送一文就够:史上最全iOS Push技术详解

本文作者:陈裕发, 腾讯系统测试工程师,由腾讯WeTest整理发表。 1、引言 开发iOS系统中的Push推送,通常有以下3种情况: 1)在线Push:比如QQ、微信等IM界面处于前台时,聊天消息和指令都会...

JackJiang-
22分钟前
0
0
Mysql汉子转拼音

update t_app_city SET CITY_NAME_BEGIN = ELT(INTERVAL(CONV(HEX(LEFT(CONVERT(CITY_NAME USING gbk),1)),16,10), 0xB0A1,0xB0C5,0xB2C1,0xB4EE,0xB6EA,0xB7A2,0xB8C1,0xB9FE,0xBBF7, 0xBFA......

尘叙缘
24分钟前
0
0
大数据构建智慧城市“新引擎”,加速推进新旧动能转换

——“大数据与智慧城市”技术交流分享会——济南站召开 7月13日,“大数据携手智慧城市,助力山东新旧动能转换”技术交流分享会——济南站在山东信息通信技术研究院会议室成功举办,此次会议...

左手的倒影
26分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部