Nginx根据前缀路径转发到不同的Flask服务

Nginx根据前缀路径转发到不同的Flask服务

开端

想通过不同的前缀路径经过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的:
[image:C2C96374-C80C-4B40-98DF-E9643C2CCCC0-11682-0000145CE6EBB095/F7AC5EA2-D665-459B-B039-C6D04845D223.png]

解决二(设置头部X-Forwarded-Prefix再用ProxyFix调整WSGI环境)

同样的也可以ProxyFix中间件来调整WSGI环境,设置SCRIPT_NAME。
来自werkzeug ProxyFix文档:
[image:76E1ACEC-E86A-43E6-9A50-BAF88778F154-11682-0000148A1A34580F/4DAA8BB8-63CB-4C4D-AB25-99AB36F9ECB7.png]
通过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能正确匹配。

参考链接

nginx proxy_pass配置:
https://www.v2ex.com/t/650344
https://www.cnblogs.com/woshimrf/p/nginx-proxy-rewrite-url.html
Werkzeug文档中的ProxyFix:X-Forwarded-For Proxy Fix — Werkzeug Documentation (2.0.x)
gunicorn文档:https://docs.gunicorn.org/en/stable/faq.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值