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能正确匹配。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Nginx如何配置根据路径转发详解

    目录 先谈理解: 1.nginx基本概念 2.常用命令以及配置文件 3.nginx配置实例之反向代理 4.nginx配置实例之负载均衡 5.nginx配置实例之动静分离 6.nginx配置高可用集群 Location规则 举例 总结 先谈理解: 1.反向代理:是nginx代理所有的服务器.而正向代理是vpn代理客户端!! 反向代理是配置 proxy_pass 可以只配置一个地址如 : proxy_pass http://127.0.0.1:8081; 也可以配置多个 2.那就是负载均衡 定义负载

  • Nginx根据url中的path动态转发到upstream的实现

    在Nginx中,有一些高级场景,需要根据url中的path参数,动态转发到不通的upstream 场景1 /svr1/xxxx?yyy 转发到 svr1:8080/xxxx?yyy /svr2/xxxx?yyy 转发到 svr2:8080/xxxx?yyy 配置如下: location ~* /(srv[1-9]+)/(.*)$ { allow all; proxy_pass http://$1/$2$is_args$args; proxy_set_header Host $host; prox

  • Nginx 根据URL带的参数转发的实现

    使用场景: 需要根据截取URL动态配置跳转路径,常见于访问内网不固定ip地址的文件图片, 请求地址:http://11.19.1.212:82/bimg4/32.52.62.42:222/DownLoadFile?filename=LOC:12/data/20180208/15/2e0ae54dfd752210083404deed15269c_222403 实际需要访问的内网地址:http://32.52.62.42:222/DownLoadFile?filename=LOC:12/data/2

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

    目录 开端 解决一(设置SCRIPT_NAME) 解决二(设置头部X-Forwarded-Prefix再用ProxyFix调整WSGI环境) 两种解决的区别 nginx proxy_pass配置的区别 为什么需要这样处理 总结 开端 想通过不同的前缀路径经过nginx转发到不同的服务上,比如 /user/转发到用户服务,/other/转发到其他服务. 首先配置nginx的location根据前缀匹配. server { listen 80; server_name localhost; loca

  • Nginx location 和 proxy_pass路径配置问题小结

    目录 一.Nginx location 基本配置 1.1.Nginx 配置文件 1.2 .Python 脚本 二.测试 2.1.测试 location 2.2.测试 location 2.3.测试三 location 2.4.location 不加 2.5.location 末尾 2.6. location 末尾 三.总结 本文是基于 location 的匹配末尾是否配置 / 和 proxy_pass 末尾是否配置 / ,进行测试,完全还原了整个测试过程.帮助了解具体的情况. 一.Nginx l

  • nginx如何指向本地路径及500错误解决方法

    正文 一个vite+vue3项目,想要部署到服务器上.项目build后的文件都在dist目录下,将这个目录拷贝到服务器上,然后在nginx里进行配置,如下: server { listen 3571; server_name localhost; location / { root /root/xxxx/dist/; try_files $uri $uri/ /index.html; } } 这样就可以通过服务器的公网ip+端口3571来访问这个vue项目了,如果想通过域名访问,则可以这样配置:

  • 详解proxy_pass根据path路径转发时的"/"问题记录

    在nginx中配置proxy_pass时,如果是按照^~匹配路径时,要注意proxy_pass后的url最后的/.当加上了/,相当于是绝对根路径,则nginx不会把location中匹配的路径部分代理走;如果没有/,则会把匹配的路径部分也给代理走. 比如下面设置: location ^~ /wangshibo/ { proxy_cache js_cache; proxy_set_header Host js.test.com; proxy_pass http://js.test.com/; }

  • nginx配置访问图片路径以及html静态页面的调取方法

    给大家讲一个快速配置nginx访问图片地址,以及访问html静态页面的配置. 1.实验环境 首先随便某个路径下创建相应的目录.如图下 2.在里面放自定义的html或者图片. 3.nginx配置 user root; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events {

  • 配置解决Nginx服务器中WordPress路径不自动加斜杠问题

    问题是这样的:我习惯在博客地址后面直接加"wp-admin"敲回车进入WordPress后台,但是进去以后发现不管我点任何一个管理子项,一律404(找不到页面),瞬间我就囧了,这是神马状况... 仔细看了一下管理子项的链接,发现他们全是类似"//www.jb51.net/blog/edit.php"这样的,关键就在于他们都少了"/wp-admin/"这条路径,路径都不对了,肯定404呗... 知道问题在哪就简单了,而且答案肯定还是在Nginx的重

  • 利用nginx解决跨域问题的方法(以flask为例)

    前言 我们单位的架构是在api和js之间架构一个中间层(python编写),以实现后端渲染,登录状态判定,跨域转发api等功能.但是这样一个中间会使前端工程师的工作量乘上两倍,原本js可以直接ajax请求api,但是我们不得不ajax请求中间层,中间层再请求api. 如图: 为了少敲代码,提高工作效率,我们当然希望将python中间层砍掉,但是如何解决以下三个问题,成为关键: 后端渲染 登录状态判定 跨域转发api 关于1,2我会在另外两篇博客中详细叙述,这篇文章主要解决3,也就是跨域问题.解决

  • Nginx域名转发使用场景代码实例

    场景1:因服务器限制,所以只对外开放了一个端口,但是需要请求不同的外网环境,所以在中转服务器上用nginx做了一次转发 实现: server { listen 8051; server_name localhost; location /license/ { proxy_pass http://xxx.xxx.xxx.xxx:8058/; } location / { proxy_pass http://xxx.xxx.xxx.xxx:8051/; } } 特别注意: 敲黑板:此处如果涉及到文件

  • 阿里云国际版使用Nginx作为HTTPS转发代理服务器的处理方法

    目录 HTTP/HTTPS 转发代理的分类 转发代理处理 HTTPS 流量时需要特殊处理 NGINX解决方案 HTTP 连接隧道 (L7 解决方案) 历史背景 ngx_http_proxy_connect_module 环境建设 应用场景 NGINX流(L4解决方案) 常见问题 ngx_stream_ssl_preread_module 环境建设 应用场景 常见问题 结论 NGINX最初被设计为反向代理服务器.但是,随着不断发展,NGINX也可以作为实现转发代理的选项之一.转发代理本身并不复杂,

随机推荐