1. 预期

最近陆续基于Nginx,完成了三个应用的部署:

  • 应用A:《在Ngnix上部署Flask应用》
  • 应用B:《PaddleOCR加载chinese_ocr_db_crnn_modile模型进行中英文混合预测(Http服务)实践》
  • 应用C:《php web server部署(PHP+Nginx+Redis+MySQL)》

理所当然冒出来一个想法就是把它们一并启起来,而且云服务器上除了http的80和https的443以外,不要增加更多的端口。预期的效果如下:

  1. 应用A和应用B都是我自己开发的Flask应用,共用443端口,通过不同的URL前缀实现区分
  2. 应用C是别的开发团队的PHP开源应用,使用80端口,不做改变
  3. 输入https://域名(或主机IP地址)根路径时,打开一个导航页面,3个链接指向上述三个应用

例如,输入带SSL的URL地址:https://127.0.0.1,打开这样一个导航页面:

点击“微信小应用服务”,即跳转到带SSL的URL地址:https://127.0.0.1/uu,打开应用A的页面:

点击“微信小应用服务”,即跳转到带SSL的URL地址:https://127.0.0.1/uu/ocr,打开应用B的页面:

点击“微信小应用服务”,即跳转到不带SSL的URL地址:http://127.0.0.1,打开应用C的页面:

2. 配置

虽然应用A和B实际上是同一个Flask应用,不过在A的系列页面中没有指向B的链接,所以可以认为在“应用层面”上是两个应用。不过不管是一个还是两个,并不影响本文的重点:

本文的重点是:上面的想法理论上非常简单,这正是Nginx反向代理的长项,只要在nginx.conf配置文件中设置多个location块,分别指向不同URL前缀就可以了。
ngnix.conf配置如图:

配置文件中添加了“add_header X-debug-message”,这样可以方便的在浏览器控制台看到我们走的是哪一条配置。如下图所示:

3. 问题

然而实际部署起来还是遇到了一些困难,主要是无论是应用A和应用B,只要 location 不指向 / ,就无法在Flask中定位出正确的路由。以应用B为例,Nginx传给后台Flask的URL是:https://127.0.0.1/uu/ocr,但是Flask中的路由无法处理多出来的/uu

# OCR测试
@webapp.route('/ocr', methods=['POST', 'GET'])
def ocr():basepath = os.path.dirname(__file__)  # 当前文件所在路径print(request.method)if request.method == 'POST':f = request.files['file']upload_path = os.path.join(basepath, 'static/uploads', secure_filename(f.filename))  # 注意:没有的文件夹要先创建f.save(upload_path)return redirect(url_for('profile.ocr_result', pic_name=f.filename))else:return render_template('ocr.html')

当然将所有路由标签都加上前缀也能算是一种“笨办法”,正道还是由Flask的BluePrint来解决。

4. 用BluePrint实现URL前缀功能

先给出一个最简单的bp例子程序:

# 使用蓝图建立统一路由前缀,便于nginx部署多应用
# 通常这句话写在routes.py中
bp = Blueprint('blueprint', __name__, url_prefix='/uu/vv', static_folder='', static_url_path='')# 用蓝图进行路由标记
@bp.route("/")
def index_page():return "This is website root"# 用蓝图进行路由标记
@bp.route("/about")
def about_page():return "This is a website about page"app = Flask(__name__)
# 应用注册蓝图
# 通常这句话写在__init__.py中
app.register_blueprint(bp)

上面这个简单的例子可以正常运行,但是在Flask的项目中,需要考虑到有SQLAlchemy的数据库模块,还有LoginManager用户登录模块,很容易引起循环import。所以在实际使用的时候,需要考虑将这些公共组件进行模块化处理。

5. 用BluePrint将程序中的公共组件模块化

对于 SQLAlchemy:
原本是在 __init__.py 中同时定义 db 并与 webapp 关联:webapp.SQLAlchemy(db)。但是这样会造成在 routes.py 中from app import db,同时又在 __init__.py 中from app.routes import bp,这样就造成了循环导入。
可以改为在 models.py 中定义db = SQLAlchemy(),在 __init__.py 中通过 db.init_app(webapp) 进行 db 与 webapp 关联。在 routes.py 和 __init__.py 中from app.models import db

对于 LoginManager:
原本是在 __init__.py 中同时定义 login 并与 webapp 关联:webapp.LoginManager(login)
可以改为在 models.py 中定义 login = LoginManager() ,在 __init__.py 中from app.models import login,并通过 login.init_app(webapp) 进行 login 与 webapp 关联。

6. url_for处理

在后台python代码,和html模板文件中的所有 url_for(function_name),全部需要改成 url_for(bp.function_name)

7. 静态资源处理

以为一切妥当以后,发现静态资源访问不了。查了Blueprint的构造函数,发现参数static_folder和static_url_path的缺省值都是None,改成空字符串’'后,又可以看到静态资源了。

所有的源码在这里,欢迎下载并提出宝贵意见 : - )

【参考资料】
《如何为所有Flask路由添加前缀?》
《python flask使用blueprint》
《flask+SQLAlchemy使用blueprint模块化》
《有关flask的static文件夹,如何设置在blueprint的根目录下呢》

Nginx反向代理多个应用时,通过BluePring使Flask支持二级路径(URL前缀)相关推荐

  1. Nginx反向代理 实现Web负载均衡

    实现负载均衡的方式有很多种,DNS.反向代理.LVS负载均衡器(软件实现).F5(负载均衡器,硬件,非常昂贵)这里我们只提到基于DNS,以及反向代理的方式来实现负载均衡Web服务       DNS服 ...

  2. 使用nginx反向代理发起跨域请求

    任务5:http://www.jnshu.com/task/2/45/detail//#1 页面文件放在github:https://github.com/Resalee/css_task/tree/ ...

  3. 分布式与微服务系列(三)、SpringBoot+Zookeeper集群+Nginx反向代理+Dubbo分布式托管(提供者、消费者)

    SpringBoot+Zookeeper集群+Nginx反向代理+Dubbo分布式托管(提供者.消费者) 一.软件架构和微服务需求 1.1.微服务需求 1.2.框架选择 1.3.集群分布(下面为此图实 ...

  4. Linux系统——Nginx反向代理与负载均衡

    集群 集群是指一组(若干个)相互独立的计算机,利用高速通信网路组成的一个较大的计算机服务系统,每个集群节点(即集群中的每台计算机)都是运用各自服务的独立服务器.这些服务器之间可以彼此通信,协同向用户提 ...

  5. Nginx反向代理与负载均衡应用实践

    本链接转载自:https://www.cnblogs.com/chensiqiqi/p/9162926.html 仅供自学使用. 1.1 集群简介 简单地说,集群就是指一组(若干个)相互独立的计算机, ...

  6. 相同Ip 不同端口配置Nginx反向代理Apache

    相同Ip  不同端口 配置Nginx反向代理Apache(就是Nginx跳转到Apache) 在linux 一经搭建好环境  先后安装了Nginx  和Apache 由于 默认端口都是:80 一般客户 ...

  7. Nginx反向代理的两种配置方式

    一.nginx反向代理简单配置 1.准备nginx环境 这篇文章的前提是已经配置好了NGINX,而且tomcat已经配置好了,而且能能够访问了. 反向代理不同端口(本案例均是单节点) 这里介绍一台ng ...

  8. Nginx反向代理——简单体验Nginx反向代理功能

    一.引言 从Nginx入门学习开始.到现在所讲的Nginx反向代理.我们的Nginx学习已经进入白热化状态,前面所学只是铺垫,真正在公司的业务场景中Nginx绝大数用来反向代理+负载均衡所用.相信大家 ...

  9. 正向代理和Nginx反向代理配置介绍

    正向代理和Nginx反向代理配置介绍 * Author QiuRiMangCao 秋日芒草* 正向代理(代理对象是pc) 是一个位于客户端(pc)和原始服务器(google.com)之间的服务器 场景 ...

最新文章

  1. mysql 单列转换为行,mysql行转换为列
  2. 的clear会清空内存吗_Python内存分配时有哪些不为你知的小秘密?
  3. 如何使用云效看板,让需求持续快速地流动和交付...
  4. Linux必会100个命令(八)ps、top、netstat
  5. TIPTOP实施基础资料收集计划表
  6. 车联网仿真测试解决方案
  7. R语言做生信分析系列(一)—— R软件简单安装
  8. 机器学习个人资料整理
  9. 22.【sinx幂级数求和】
  10. 如何去掉网格线及网格区域颜色
  11. Java Scanner的hasNext()方法
  12. 【LeetCode】1337. 矩阵中战斗力最弱的 K 行(C++)
  13. easyui+struts2:datagrid无法不能得到数据
  14. 开发那点事(十五)微信小程序webView首次进入白屏优化方案
  15. 2021年9月电子学会Python等级考试试卷(一级)考题解析
  16. 第四篇 EAS系统项目框架搭建
  17. 信号完整性专题【3】——有哪些功能和方案专攻高速设计布局布线?【转载】
  18. 【美团杯2020】字符串处理:查查查乐乐
  19. 分布式链路追踪SkyWalking进阶实战之RPC上报和WebHook通知(三)
  20. 计算机图像图形研究目的,计算机图形图像技术探究论文

热门文章

  1. php检测函数是否存在函数 function_exists
  2. 哈希表的实现(取余法)
  3. avcodec_decode_video2 第三个参数 got_picture_ptr 的含义
  4. 写在Silverlight 5发布前 - 盘点2010年Silverlight开发书籍
  5. OpenCV 绘制几何图形
  6. 使用Lombok优化代码
  7. anki 插入表格_anki|建造师选择题制作的方法
  8. Github上最受关注的前端大牛,快来膜拜吧!
  9. Linux 环境安装 Node、nginx、docker、vsftpd、gitlab
  10. 一文了解c/c++、java、JavaScript、php、Python的用途