Nginx如何根据前缀路径转发到不同的Flask服务
目录
- 开端
- 解决一(设置SCRIPT_NAME)
- 解决二(设置头部X-Forwarded-Prefix再用ProxyFix调整WSGI环境)
- 两种解决的区别
- nginx proxy_pass配置的区别
- 为什么需要这样处理
- 总结
开端
想通过不同的前缀路径经过nginx转发到不同的服务上,比如 /user/转发到用户服务,/other/转发到其他服务。
首先配置nginx的location根据前缀匹配。
server {
listen 80;
server_name localhost;
location /user/ {
proxy_pass http://127.0.0.1:5000; # 用户服务
}
location /other/ {
proxy_pass http://127.0.0.1:5001; # 其他服务
}
}
这样访问http://127.0.0.1:5000/user/xxx/就会转发到用户服务,访问http://127.0.0.1:5000/other/xxx/就会转发到其他服务。
这样就会有一个问题,flask application并不知道有前缀,所以使用url_for构造url的时候并不会自己添加前缀,要构造出正确带前缀的url就需要把前缀加入到WSGI环境中的SCRIPT_NAME去。
解决一(设置SCRIPT_NAME)
gunicorn文档上:

可以把SCRIPT_NAME设置到环境变量中或者HTTP header中。
通过docker部署设置SCRIPT_NAME在环境变量中,可以在docker-compose.yml中加入
environment: - SCRIPT_NAME=/user/
或者把SCRIPT_NAME设置在header中可以在nginx配置中加上
proxy_set_header SCRIPT_NAME /user/;
gunicorn.wsgi处理请求的时候是这样处理PATH_INFO和SCRIPT_NAME的:

解决二(设置头部X-Forwarded-Prefix再用ProxyFix调整WSGI环境)
同样的也可以ProxyFix中间件来调整WSGI环境,设置SCRIPT_NAME。
来自werkzeug ProxyFix文档:

通过nginx设置头部信息X-Forwarded-Prefix:
proxy_set_header X-Forwarded-Prefix /user/;
使用ProxyFix:
from werkzeug.middleware.proxy_fix import ProxyFix app = ProxyFix(app, x_prefix=1)
还需要把nginx的proxy_pass修改下:
server {
listen 80;
server_name example.com;
location /user/ {
proxy_pass http://127.0.0.1:5000/; # 用户服务
}
location /other/ {
proxy_pass http://127.0.0.1:5001/; # 其他服务
}
}
两种解决的区别
nginx proxy_pass配置的区别
区别在于nginx的proxy_pass中结尾是否带/。
如果proxy_pass不带uri,就是不带/,则请求会原封不动的转发给下一个服务。
如果proxy_pass带uri,则匹配的uri部分将会被修改为该proxy_pass中的uri。
为什么需要这样处理
以我的理解是这样的,请求进来通过gunicorn处理请求,gunicorn.wsgi中会根据SCRIPT_NAME来制定PATH_INFO,所以当解决一带着SCRIPT_NAME=/user/,PATH_INFO=/user/xxx/经过处理后PATH_INFO会变成/xxx/。
而解决二中当gunicorn.wsgi处理请求时ProxyFix还没对WSGI环境进行处理,所以SCRIPT_NAME是为空的,PATH_INFO则会一直是带着SCRIPT_NAME前缀为/user/xxx/,是不能正确匹配到route的,所以把nginx proxy_pass改为uri形式使PATH_INFO能正确匹配。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。
您可能感兴趣的文章
- 12-20Kubernetes中使用临时容器进行故障排查的方法
- 12-20Nginx设置HTTPS的方法步骤
- 12-20二进制方式安装 Kubernetes1.18.3版本实现脚本
- 12-20Nginx工作模式及代理配置的使用细节
- 12-20ZooKeeper分布式协调服务设计核心概念及安装配置
- 12-20Kubernetes部署可视化地图的十个步骤
- 12-20关于docker清理Overlay2占用磁盘空间的问题(亲测有效)
- 12-20Docker compose配置文件写法及命令使用示例
- 12-20openwrt安装docker并启动的操作方法
- 12-20云原生Kubernetes初始化容器Init使用教程


阅读排行
推荐教程
- 12-07一文教你怎么选择Tomcat对应的JDK版本
- 12-07新版Eclipse集成Tomcat时找不到server选项的解决方法
- 12-06IIS7 应用程序池自动回收关闭的解决方案
- 12-05Windows Server 2019安装VMware
- 12-05Windows服务器默认IE浏览器无法下载文件的解决方法
- 12-05Docker安装Jenkins全过程
- 12-19Zabbix SAML SSO 登录绕过漏洞的操作流程
- 12-15Docker-Compose搭建Spark集群的实现方法
- 12-14Docker Desktop无法正常启动解决(failed to start...)
- 12-14k8s 与docker空间使用分析与清理方法





