作者| 李煜峰| F5 研发实习生
F5
概述
反向代理是指使用代理服务器来接受客户端的请求,然后转发给内网上游web服务器集群,之后再将上游web服务器的响应转发给客户端。在这个过程中,代理服务器对于客户端来说就相当于 web 服务器,上游web服务器对客户端来说是透明的。具体处理流程如图1 所示。
图1 Nginx反向代理服务器处理客户端请求流程
Nginx 虽然本身支持高并发,而且性能很强劲,但是处理复杂的业务逻辑并不是它的强项。这时会将 Nginx 用作反向代理服务器去接收高并发的请求,然后将请求转发给 Apache 等 Web 服务器去处理。那么如何使用 Nginx 反向代理这一功能呢,下面我们将介绍一些基本的配置方法。
F5
proxy_pass
首先是 Nginx 反向代理的最基本的配置项proxy_pass。
语法:proxy_pass URL;
默认值:无
配置块:location, if in location, limit_except
proxy_pass配置项可以将用户的请求转发给 URL 指定的服务器,其形式有以下几种:
1.IP或主机名+端口号
proxy_pass :8001/uri/;
2.https
proxy_pass :8001/uri/;
3.UNIX 句柄
proxy_pass :/tmp/backend.socket:/uri/;(官方写法,尚待验证)
4.upstream
upstream 和前几个用法都不相同,它是定义一个服务器组,然后Nginx 代理服务器根据默认或指定的负载均衡算法来选择其中之一进行转发。
用法:
upstream my_upstream { server localhost:8001; server localhost:8002; } server { location / { proxy_pass ; } }
如果要指定 URI,则可写成如下格式:
proxy_pass /uri/;
upstream默认负载均衡算法是轮询,除此之外还有根据权重进行轮询的weight,根据用户 IP 哈希选择服务器的 ip_hash等算法。
更加详细的用法可以参考官方文档
#upstream
F5
proxy_pass 地址末尾斜杠的影响
在 Nginx 的配置过程中,地址末尾的斜杠的有时会让人摸不着头脑,但实际上真正造成 proxy_pass代理规则不同的是末尾有无 uri,而不是有无斜杠。也就是说 proxy_pass可以分为两种情况:一种是只有ip+port,比如:8080;另一种是除了 ip+port外,还有资源标识符uri,包括单一的一个斜杠,比如 localhost:8000/ 和localhost:8000/test 都属于这种情况。
图2 proxy_pass的两种形式
下面我们将通过 8 个小例子详细分析一下 proxy_pass 的这两种形式。
在看例子之前,要明确的一点是location 默认的匹配规则是前缀匹配,和^~类似,但是它的优先级在正则表达式之后。
1. proxy_pass的url只有ip+port,此时将保留 location 中的 uri
比如:
location /proxy1 { proxy_pass :8001; }
当访问/proxy1/my_web/ ,将被代理为 :8001/proxy1/my_web/。其最终代理url 生成规则为:proxy_pass的url + 访问地址的 uri,也就是 :8001 + /proxy1/my_web/ 。
location /proxy2/ { proxy_pass :8001; }
/proxy2/my_web/ -> :8001/proxy2/my_web/,这种情况最终代理url是由:8001 + /proxy2/my_web/ 组装而成,效果和上一个例子相同。
2. proxy_pass 的url末尾带 uri,匹配到的location中的uri会被去除掉
location /proxy3 { proxy_pass :8001/; }
/proxy3/my_web/ -> :8001//my_web/,:8001/ + /my_web/,根据构造规则,端口号后产生两个斜杠,但此时是依然能正确访问的。
location /proxy4/ { proxy_pass :8001/; }
/proxy4/my_web/ -> :8001/my_web/,:8001/ + my_web/ 。
location /proxy5 { proxy_pass :8001/test; }
/proxy5/my_web/ -> :8001/test/my_web/,:8001/test + /my_web/ 。location /proxy6/ { proxy_pass :8001/test; }
/proxy6/my_web/ -> :8001/testmy_web/,:8001/test + my_web/,此情况容易产生 404错误,需要注意。
location /proxy7 { proxy_pass :8001/test/; }
/proxy7/my_web/ -> :8001/test//my_web/,:8001/test/ + /my_web/,此时类似例3 产生了两个斜杠。
location /proxy8/ { proxy_pass :8001/test/; }
/proxy8/my_web/ -> :8001/test/my_web/,:8001/test/ + my_web/
总的来说,当 proxy_pass 的url末尾带 uri 时,会先将访问网址的uri去掉 location 匹配的部分,然后拼装在 proxy_pass的 url 后面;当proxy_pass的 url 末尾不带uri时,会将访问网址的 uri 直接拼装在 proxy_pass的 url 后面。
刚开始在配置 proxy_pass时,被斜杠搞的晕头转向,一度觉得这是个玄学配置项。后来查看了一些资料和文档,反复做了一些实验之后,发现还是有迹可循的,这样一下子就清晰了。
F5
重定向和proxy_redirect
当上游 web服务器返回的是重定向(HTTP 状态码为 301 或 302)或刷新请求时,proxy_redirect可以修改其 HTTP 头部的location 或者 refresh 字段来满足我们的需要。
语法:
proxy_redirect default;
proxy_redirect off;
proxy_redirect redirect replacement;
默认:proxy_redirect default;
配置块:http, server, location
图3 Nginx配置项proxy_redirect处理过程
比如proxy_redirect配置为proxy_redirect :8000/two/ ;
Location: :8000/two/some/uri/ 将被修改为 Location: some/uri/”
当使用默认配置时,会根据当前location配置项和 proxy_pass 的配置重组来修改 location 的值。以下两种形式是等效的。
location /one/ { proxy_pass :port/two/; proxy_redirect default; } location /one/ { proxy_pass :port/two/; proxy_redirect :port/two/ /one/;; }
Nginx 资源缺失时的重定向:
当Nginx 服务器接收到的url 为 :port/my_web时,会先在html目录下寻找my_web文件,如果没有 my_web文件但是有名为my_web的目录,则会返回 301 重定向状态码,并且设置响应头字段 location 的值为 host_ip:server_port/my_web/ 。如果此时我们在 nginx 和服务器之间做了端口映射,那么 location 中的端口号对客户端来说是无效的,就会造成客户端无法访问重定向后的网址。此时则可以使用 proxy_redirect来修改 location 的内容。
下面我们来实验一下这个过程。
实验环境是centos容器,宿主机的 ip 为10.250.16.146,端口映射关系为 8080:80。
配置代码:
server {
listen 80;
server_name localhost;
location /proxy/ {
proxy_pass :8001/;
proxy_redirect off;
#proxy_redirect default;
#proxy_redirect :8001/ /proxy/;
#proxy_redirect :8001/ ; #使用 nginx 变量$http_port来获取请求HTTP的ip 和端口号
}
location / {
}
}
server {
listen 8001;
server_name 10.250.16.146:8080;
location / {
}
}
▲可上下滑动查看全部内容
如代码所示,我们实验了四种 proxy_redirect配置,其实验结果如下:
1. proxy_redirect off;
2. proxy_redirect default;
3. proxy_redirect :8001/ /proxy/;
4.proxy_redirect :8001/ ;
其中第四种能够达到我们的效果,第二和第三种效果是相同的。
F5
其他反向代理相关命令
除了上述命令外,proxy 模块还有其他一些命令可以使用。如修改协议名的proxy_method,隐藏 HTTP头部字段的proxy_hide_deader,显示 HTTP 头部字段的 proxy_pass_header等命令。更加详细的内容可以在官方文档 http/ngx_http_proxy_module.html 中查看。
F5
参考
《深入理解 Nginx:模块开发与架构解析》
阅读更多好文
请关注F5社区
加入F5社区关注“F5社区”,注册成为社员,随时参加meet up活动,代码共享,讨论,答疑等。只要你有想法,有创造,那么就快来大展身手吧,让我们在社区里尽情分享,交流,吐槽和互动,在这个自由的国度里,发现闪亮的自己。让我们一起来见证“一群有才能的人在一起做有梦想的事”。
扫码关注
注册社员
构建云原生场景下的现代应用实践
扫描下方二维码,快来报名吧!4月25日(周六,下午2-5点)从容器基础到规模化使用进阶培训
扫描下方二维码,快来报名吧。
19:30-21:30(每周一晚)F5+Rapid7线上直播: 企业主动对抗型安全建设及实践分享
扫描下方二维码,快来报名吧!4月17日(下午2-3点)“应用服务技术中台”系列线上研讨会
扫描下方二维码,快来报名吧。《2020年应用服务现状报告(亚太版)》完整版下载
扫描下方二维码,快来下载吧。
为企业免费提供远程解决方案
F5在疫情期间为广大企业用户免费提供基于虚拟化产品的系列远程解决方案:
1.企业远程办公服务
2.故障硬件远程软备件替换
3.紧急情况快速远程扩容
4.安全攻击事件快速远程防范
并特别通过F5原厂及F5授权服务中心为湖北省及全国医院客户直接提供7x24小时远端技术支持服务,同时F5授权培训中心也将提供在线安装、技术指导培训服务。
申请流程:
您可以与您所在地的F5销售或技术人员联系;或者致电F5 市场热线电话; 或者发送邮件至 [email protected] 。
也可扫描下方二维码在线提交需求。
你还不能错过:
你还不能错过:
你还不能错过:
F5宣布将收购安全公司Shape,强化应用安全
F5收购NginX
F5宣布推出首个SaaS产品
F5银行业案例集锦
F5部署红宝书(3部)
实录: F5多云环境应用的智能编排与运维
7层DDoS攻击实例
应用服务自动化
智慧医疗下的“IT应用”网络研讨会
NGINX相关:
问答、课件及录像地址:NGINX从入门到精通进阶系列培训
F5社区好文推荐:多可用区双层负载下,如何借助F5避免局部NGINX后业务实例过载
更多产品和方案:
SSL | SSL Orchestrator
F5 Advanced WAF(API安全-新一代WAF)
BIG-IP VE | BIG-IQ VE
Openshift-F5集成
F5大数据引擎
F5双活数据中心方案
IOT
F5 & SAP | F5 & AWS
F5 & Ansible
F5 & Kubernetes
F5解决k8s,openshift等PaaS平台对外暴露
F5 数字图书馆:
F5 API 安全网关
从传统ADC迈向Cloud Native ADC
F5 DevOps研习社作品集:
DevOps研习社:品质决定成败——漫谈非功能性需求
DevOps研习社:PaaS平台集成解决方案——F5实现K8S管理平面的高可用和安全
DevOps研习社:PaaS平台集成解决方案——F5实现K8S环境下应用自动发布
DevOps研习社:PaaS平台集成解决方案——F5实现K8S环境下应用蓝绿发布
DevOps研习社:PaaS平台集成解决方案——使用F5大数据引擎功能实现业务可视化
DevOps研习社:F5 连接NetOps/SecOps与DevOps——介绍篇
DevOps研习社:F5 连接NetOps/SecOps与DevOps(1)——数字化转型
DevOps研习社:F5 连接NetOps/SecOps与DevOps(2)——Infrastructure as Code
DevOps研习社:F5 连接NetOps/SecOps与DevOps(3)——Cloud Templates
DevOps研习社:F5 连接NetOps/SecOps与DevOps(4)——Declarative Onboarding
DevOps研习社:F5 连接NetOps/SecOps与DevOps(5)——Application Services 3 Extension
DevOps研习社:F5 连接NetOps/SecOps与DevOps(6)——Telemetry Streaming
请为我们专心制作和生产的内容“点好看”吧,让我们更加有动力,也让更多人看到哦:)