Flask结合gunicorn和nginx反向代理的生产环境部署及踩坑记录

news2024/10/7 6:46:15

前言

之前自己写的flask使用gunicorn上线生产环境没有什么问题,但是最近搭建了一个现成的flask项目,当使用python直接运行时不会有问题,而使用gunicorn时则会出现一些问题。


部署过程

运行测试

这里使用pyenv创建了一个虚拟环境,并安装好依赖

pyenv virtualenv 3.9.6 freegpt
pyenv activate freegpt
pip install -r requirements.txt

下面是入口函数run.py

from server.app import app
from server.website import Website
from server.backend import Backend_Api
from json import load


if __name__ == '__main__':
    # Load configuration from config.json
    config = load(open('config.json', 'r'))
    site_config = config['site_config']
    # Set up the website routes
    site = Website(app)
    for route in site.routes:
        app.add_url_rule(
            route,
            view_func=site.routes[route]['function'],
            methods=site.routes[route]['methods'],
        )

    # Set up the backend API routes
    backend_api = Backend_Api(app, config)
    for route in backend_api.routes:
        app.add_url_rule(
            route,
            view_func=backend_api.routes[route]['function'],
            methods=backend_api.routes[route]['methods'],
        )
    # Run the Flask server
    print(f"Running on port {site_config['port']}")
    app.run(**site_config)
    print(f"Closing port {site_config['port']}")

其中site_config.json文件如下:

{
        "site_config": {
                "host": "127.0.0.1",
                "port": 1234,
                "debug": false
        },
        "use_auto_proxy": false
}

意思是,运行flask服务于127.0.0.1:1234,只运行本地访问,后期我们需要搭建Nginx进行反向代理。

我们先使用python直接运行测试一下看能否跑起来以及能否正常访问。

python run.py

image-20230714004534660

我们在服务器使用curl进行请求

curl 127.0.0.1:1234

image-20230714004621346

数据返回正常,说明可以正常访问。


gunicorn搭建

Gunicorn是一个WSGI HTTP Server,是针对Python的、在Unix系统上运行的、用来解析HTTP请求的网关服务。
它的特点是:能和大多数的Python web框架兼容;使用简单;轻量级的资源消耗;高性能。

首先在当前虚拟环境下安装gunicorn

pip install gunicorn

然后我们使用gunicorn将flask项目跑起来,并且仅对本机开放,端口4444

gunicorn run:app -b 127.0.0.1:4444 --access-logfile access.log --error-logfile error.log &

使用ps命令可以看到当前已经成功在后台运行起来了

ps aux | grep gunicorn

image-20230714005029807

踩坑

但是此时当我们再次使用curl访问127.0.0.1:4444时:

image-20230714005121785

出现了404的错误。

我们查看gunicorn生成的日志文件:

# access.log
127.0.0.1 - - [13/Jul/2023:12:51:11 -0400] "GET / HTTP/1.1" 404 207 "-" "curl/7.76.1"

可以看到成功的请求到了我们的wsgi server,但是返回了404。在外网论坛上摸索了一番,问题出在了run.py上。

run.py文件中的所有代码都是写在if __name__ == "__main__":之下的,这在python语法中代表着主函数入口。

  • 当使用Python直接运行脚本时(例如:python run.py),if __name__ == '__main__'条件下的代码块会被执行,包括app.run()。这将启动Flask服务器,并让应用程序开始监听指定的主机和端口。
  • 当使用Gunicorn运行应用程序时(例如:gunicorn --bind 127.0.0.1:4444 run:app),if __name__ == '__main__'条件下的代码块不会被执行。因为Gunicorn实际上是将你的代码作为一个模块导入,而不是直接运行该代码。在这种情况下,Gunicorn会在内部处理Flask服务器的启动逻辑,并监听指定的主机和端口。也就因此自己在app.run(**kwargs)中设定的hostportdebug等参数也就失效了。

因此,无论是使用Python直接运行还是使用Gunicorn运行应用程序,app.run()只会在Python直接运行脚本时执行。而在使用Gunicorn运行时,if __name__ == '__main__'条件下的代码块将被跳过,包括app.run()。这是因为Gunicorn已经处理了服务器的启动逻辑。

因此,if __name__ == '__main__'条件的目的是为了确保在直接运行脚本时才执行特定的代码块,而在被导入为模块时跳过这些代码块。这样可以确保在使用Gunicorn启动应用程序时不会重复启动Flask服务器,并避免出现意外行为。


解决方案

既然已经知道了错误的逻辑,那么解决方法就很简单了,只要把除了app.run()的其他代码全部移出if __name__ == "__main__"即可。修改后的run.py如下:

from server.app import app
from server.website import Website
from server.backend import Backend_Api
from json import load

 # Load configuration from config.json
config = load(open('config.json', 'r'))
site_config = config['site_config']
# Set up the website routes
site = Website(app)
for route in site.routes:
    app.add_url_rule(
        route,
        view_func=site.routes[route]['function'],
        methods=site.routes[route]['methods'],
    )

# Set up the backend API routes
backend_api = Backend_Api(app, config)
for route in backend_api.routes:
    app.add_url_rule(
        route,
        view_func=backend_api.routes[route]['function'],
        methods=backend_api.routes[route]['methods'],
    )

if __name__ == '__main__':
    # Run the Flask server
    print(f"Running on port {site_config['port']}")
    app.run(**site_config)
    print(f"Closing port {site_config['port']}")

这样就可以保证python和gunicorn方式均可正常运行。

先kill掉之前正在运行的gunicorn,并重新启动

kill -9 1275864 1275865
gunicorn run:app -b 127.0.0.1:4444 --access-logfile access.log --error-logfile error.log &

可以看到现在请求127.0.0.1:4444已经正确响应了

image-20230714010629837


Nginx反向代理

目前搭建的服务只能服务器自己访问到,下面我们通过nginx反向代理将其映射到对外的80端口

安装配置nginx就不多说了,下面讲讲配置文件的写法。其实很简单

vim /etc/nginx/nginx.conf
# nginx.conf
...
server {
        listen          80;
        server_name     xxxxxxxx;		# 此处填绑定的域名

        location / {
                proxy_pass http://localhost:4444;
                proxy_set_header Host $host:$server_port;
                proxy_set_header X-Real-IP $remote_addr;
        }
    }
...

然后运行nginx即可

nginx -t
nginx

此时使用本机访问域名的80端口已可以正常访问了。

image-20230714011222108

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/751572.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android PackageManagerService源码分析和APK安装原理详解

前些天发现了一个蛮有意思的人工智能学习网站,8个字形容一下"通俗易懂,风趣幽默",感觉非常有意思,忍不住分享一下给大家。 👉点击跳转到教程 一、PackageManagerService简称PMS:PackageManagerService是Android系统中核…

城市餐饮油烟的监测与治理

摘要:为控制餐饮油烟污染,改善城市大气污染和生态环境,针对城市餐饮油烟污染现状,提出相应的治理政策。加快餐饮油烟污染立法进度,推进相关法律法规修订,加大油烟污染执法力度;维护清洗油烟净化…

windows安装使用 tesseract-ocr

OCR(Optical character recognition,光学字符识别)是一种将图像中的手写字或者印刷文本转换为机器编码文本的技术。 tesseract-ocr 是由Google开发,支持100多种语言 文档 tessdoc: https://tesseract-ocr.github.io…

3Ds max创建闪烁的星星效果

在这个简单的教程中,您将学习如何通过几个步骤创建闪烁的星星效果。 推荐: NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 步骤-1 在顶视图中创建球体 步骤-2 应用星形材料。 步骤-3 复制球体并稍微调整其大小(两个球体必须完全相同&…

Ubuntu 的安装及其设置

文章目录 安装 Ubuntu屏幕分辨率设置修改软件源服务器锁屏时间设置设置 dash跨系统拖拽复制文件的设置 安装 Ubuntu 首先安装 VMware 虚拟机,虚拟机的安装比较简单,一步步点击Next即可完成安装。 安装完成后启动虚拟机,点击创建新的虚拟机。…

modelscope本地模型使用教程

阿里魔塔社区modelscope(https://modelscope.cn/home) 如果使用过模型,那么模型文件默认缓存地址:C:\Users\Administrator.cache\modelscope\hub 魔塔社区本地使用: 1、安装python环境:使用miniconda&…

Apache Knox Gateway

简介: Knox是一个提供认证和访问集群中hadoop服务的单个端点服务。目标是为用户和操作者简化hadoop安全。knox运行为一个服务或者集群服务,并提供集中访问一个或者多个hadoop集群。通常网关的目标如下: 1、为hadoop rest api 提供外层的安全…

实战攻防之积极防御体系建设 | 中睿天下受邀参与诸子云沙龙

7月8日,中睿天下受邀参与由诸子云举办的“网络与数据安全”主题沙龙,中睿天下技术经理徐丹丹就《实战攻防之积极防御体系建设》这一主题进行了分享交流。 本次沙龙由南京分会会长宋士明主持,活动邀请到BASF、江苏省联社、华泰证券、宁证期货、…

微软浏览器连不上网络

针对微软浏览器连不上网络,但其他浏览器仍能连上网络 控制面板 -> 网络和Internet -> Internet 选项 -> 连接 -> 局域网设置 -> 取消代理服务器

理清ROS通信的一些细节

目标:掌握ros的python编程 基本教程:https://www.bilibili.com/video/BV1sU4y1z7mw/?spm_id_from333.788&vd_source32148098d54c83926572ec0bab6a3b1d terminator 快捷键需要自己去重新启用 ctrlshifte 横向分屏 ctrlshifto 纵向分屏 ctrlshiftw …

前端AES加密,后端解密,有效防止数据外泄

在工作中经常遇到密码明文传输这个问题,为了让密码安全些会让加密,现在有个比较方便的AES加密(前端密钥可能存在泄露风险,应该放到配置项中): 一、前端加密 1、首先引入前端需要用到的js:crypt…

CocoaPods私有库的创建

第一步:为了方便寻找,我先cd 桌面路径 /Users/xxx/Desktop 第二步 :创建私有库的名字 pod lib creat KMWaterMark 创建之后会有个文件夹,打开文件夹将自己的工具类放到classes文件夹里面,然后在在Example中打开自己的…

【通过迭代相位检索重建衍射图案和全息图中缺失信息】不完整衍射图案的迭代重建和缺失像素的恢复(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

【编译之美】【1. JS闭包问题】

什么是闭包 在 JavaScript 和 Python 等语言里,函数可以像数值一样使用,比如给变量赋值、作为参数传递给其他函数,作为函数返回值等等。比如下面这一段代码: var a 0;var fun1 function(){var b 0; // 函数内…

UE4/5c++基于BlueprintAsyncActionBase和FTickableGameObject的异步节点【多流程的创建、异步执行】

目录 简单的多流程制作 取消除流程外,原本的蓝图执行线【如果要进行异步执行可以不取消看效果】 结果 代码: 继承FTickableGameObject,时刻判断是否结束,来执行不同引脚 结果: 代码: 在之前笔者讲解…

数据结构(王道)——顺序表的基本操作(插入、删除)

顺序表之实现插入: 插入的基础实现: 更加有健壮性的插入 插入实现的时间复杂度分析: 顺序表之实现删除: 删除的实现 删除实现的时间复杂度分析: 总结:

Ubuntu18.04 系统安装 Docker

1、首先更新软件源: sudo apt-get updatesudo apt-get upgrade 2、安装Docker: sudo apt install docker -y 3、查看安装的Docker apt list docker 4、查看docker 进程 ps -ef|grep docker 5、查看docker 版本有问题 6、开启Docker服务 systemctl…

​LeetCode解法汇总931. 下降路径最小和

目录链接: 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目: https://github.com/September26/java-algorithms 原题链接:力扣 描述: 给你一个 n x n 的 方形 整数数组 matrix ,请你找出并返回通过 matr…

企业视角下的个人信息保护影响评估具体实施

个人信息保护影响评估(PIA)是指企业对个人信息的收集、存储、使用、加工、传输、提供、公开、删除等贯穿数据全生命周期活动的检验,判断活动合规程度、保护措施的有效程度以及对个人信息主体合法权益造成损害的风险。个人信息保护影响评估旨在…

力扣 55. 跳跃游戏

题目来源:https://leetcode.cn/problems/jump-game/description/ C题解(来源代码随想录):不断更新可覆盖范围,能达到最后一个元素即返回true,否则返回false。 class Solution { public:bool canJump(vecto…