部署flask应用的全部流程和相关配置

2023-05-2619:42:59后端程序开发Comments1,459 views字数 4501阅读模式

Python Web 部署结构文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

对于生产环境,部署Python Web应用基本都要用到 Web server 和WSGI server。那它们之间是如何联系的呢?如下图所示:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

部署flask应用的全部流程和相关配置文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

这里Web Server用于接受客户端的http请求,然后返回处理后的结果。对于Python Web应用目前主流的是Nginx, 其占有内存少,并发能力强,在同类型的网页服务器中表现较好。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

WSGI全称是Python Web Server Gateway Interface,用来连接Web服务器和Python Web开发框架。目前常用的有uWSGI, gunicorn。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

Web应用大都基于框架完成,对于python,主流框架有Django, Flask, Tornado,主要用于业务层逻辑的实现,并不关注http层的具体内容。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

对于部署Flask应用,比较推荐的方式是:Nginx + Gunicorn + Flask, 下面具体介绍。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

Gunicorn文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

Gunicorn是一个被广泛使用的高性能的Python WSGI HTTP服务器,只支持UNIX环境。Gunicorn采用pre-fork worker模式,能够与各种wsgi web框架协作。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

那为何需要gunicorn呢?首先,如果使用Flask自带的WSGI, 由于是单进程运行,其处理请求的能力有限,一般作为测试使用。而gunicorn也支持WSGI服务,同时由于pre-fork worker的工作模式,启动后会fork出指定数量的应用进程,多进程处理请求的数量肯定比单进程多。另外gunicorn接受nginx转发的http请求,收到处理后的响应后转发给nginx。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

1) 安装文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

pip install gunicorn  # 安装最新版本pip install gunicorn==19.9.0  # 安装指定版本
# 如果异步,需要安装对应模块pip install eventlet  # 使用eventlet工作模式pip install gevent  # gevent工作模式

2) 运行gunicorn文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

gunicorn [options] main_app:app

main_app是flask应用主模块main_app.py,app是应用实例名称, 需要和代码里的app实例命名一致。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

options是参数,常用的有:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

  • -k/--worker-class: 指定工作模式,可选参数:
sync:同步模式(默认)
eventlet: 协程异步,需要安装eventlet
gevent: 协程异步,需要安装gevent
tornado: 利用python Tornado框架实现,需要安装tornado
gthread: 线程工作模式,利用线程池管理连接,需要安装gthread. Gunicorn允许每个worker拥有多个线程。在这种场景下,Python 应用程序每个worker都会加载一次,同一个worker生成的每个线程共享内存空间。
  • -w/--workers:指定应用进程数量, 默认为1
  • -b/--bind: 指定客户端地址,格式 HOST:PORT, 如 -b 127.0.0.1:8000
  • -t/--threads: 每个进程处理请求的线程数,默认每个worker 一个线程,指定threads工作模式自动变成gthread模式;
  • --worker-connections: 工作线程连接数,默认1000,仅在eventlet, gevent工作模式下有效
  • -t/--timeout 超时限制,默认是30秒,工作进程在超过设置的超时时间内没有响应将会被杀死并重启。
  • --reload=True, 当代码变动时重启gunicorn
  • -D,--daemon: 以后台进程的方式运行gunicorn
  • --log-level:指定日志输出等级
  • --access-logfile: 访问日志输出文件
  • --error-logfile: 错误日志输出文件

注意:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

a. 参数格式:-p value,--params=value文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

b. 工作模式指定为gevent或者evenlet时,threads参数无效文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

常用启动命令,下面main为应用入口模块main.py的名称文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

# 指定worker数量gunicorn -w 5 -b 127.0.0.1:8080 main:app
# 设置线程gunicorn -w 5 -t 2 -b 127.0.0.1:8080 main:app
# 设置异步工作模式gunicorn --worker-class=gevent \         --worker-connections=1000 \         -w 3 main:app

3)工作模式选择文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

  • gunicorn默认是同步模式。该模式下,每个worker进程一次只处理一个请求,处理完成了才能处理下一个,在高并发场景,非常消耗CPU和内存。
  • 异步有gevent和evenlet两种模式,异步模式一个worker进程可以同时处理多个请求,不会block其他请求。
  • 如果没有阻塞响应的话,使用同步worker,如果阻塞比较多的话选用异步的模式;worker的数量推荐使用(2*CPU)+1。

4) 结束进程文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

首先使用:ps -ef | grep gunicorn 命令找出gunicorn的主进程ID文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

然后执行:kill -9 主进程ID,当主进程被Kill, 其他子进程也会自动结束,可以稍后再次执行查找命令确认。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

Nginx部署
文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

Nginx是一款轻量级的Web 服务器/反向代理服务器,其用途主要是:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

  • 做反向代理,客户端请求Nginx,Nginx请求应用服务器,然后将结果返回给客户端
  • 作负载均衡,将大量用户请求分配给多台机器处理
  • 动静分离,静态请求直接从 nginx 服务器所设定的根路径去取对应的资源,动态请求则转发给后台处理
  • 做虚拟主机,将多个网站部署到一台服务器上

1)安装文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

apt install nginx  # ubuntuyum install nginx  # Centos

2)启动/停止Nginx文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

sudo nginx  # 启动sudo nginx -s reload  # 热启动
sudo nginx -s stop  # 停止sudo pkill -9 nginx  # 强制停止

3)查看nginx运行状态文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

运行:systemctl status nginx,如下图为running状态:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

部署flask应用的全部流程和相关配置文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

4)Nginx配置文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

以Ubuntu20.04为例,nginx配置在目录/etc/nginx下,如下图:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

部署flask应用的全部流程和相关配置文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

sites-available为有效站点配置,默认有一个default配置;文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

sites-enabled是当前使用的站点配置,实际里面是软连接,指向sites-available里的配置。下面举例演示如何配置。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

首先,在site-available目录下,拷贝default为flask_demo,然后修改flask_demo配置,如下图:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

server {        listen 9000 default_server;        listen [::]:9000 default_server;
        root /var/www/html;        index index.html index.htm index.nginx-debian.html;
        server_name _;
        location / {                proxy_pass http://127.0.0.1:9001;        }

一个server配置对应一个站点,这里nginx做反向代理,9000是Nginx的端口,proxy_pass是gunicorn服务的绑定地址和端口。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

然后进入到sites-enabled目录创建配置软连接:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

sudo ln -s /etc/nginx/sites-available/flask_demo flask_demo

下面测试一个简单的flask应用:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

模块名称app.py, 内容如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

from flask import Flask
app = Flask(__name__)

@app.route('/')def index():    return "Testing Flask App Deployment"

启动gunicorn:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

gunicorn -w 5 -b 127.0.0.1:9001 app:app

在浏览器搜索目标地址,这里192.168.56.106是当前测试虚拟机的IP地址,9000是刚才配置的Nginx端口,内容如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

部署flask应用的全部流程和相关配置文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

5)配置负载均衡文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

为了分散单台服务器的访问压力或者将业务拆分为微服务,一般采用服务器集群的部署方式。但是如果一个服务器对应一个域名,外部访问肯定不方便,怎么办呢?Nginx负载均衡就可以解决这个问题,如下图为负载均衡结构示意图:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

部署flask应用的全部流程和相关配置文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

将不同的服务器地址添加到Nginx服务器的配置中,然后做反向代理。对于外部用户,是感知不到后端多个服务器的,访问的域名并没有改变。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

另外,负载均衡还可以用于配置主从服务器,当主机出现故障,nginx会将请求发送给备份服务器处理。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

下面是实现负载均衡的一个简单示例:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

注:由于资源有限,还是在单机上测试,实际每个应用部署在单独的虚拟机或者docker中文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

  • 首先拷贝两份flask应用, 重命名并修改app.py文件的URL地址和返回信息,以方便对比;
  • 用gunicorn分别启动这两个新增应用,地址还是127.0.0.1,端口分别用9002, 9003;
  • 打开配置文件:sudo vim /etc/nginx/sites-available/flask_demo
  • 将应用服务的地址添加到 "upstream domain"配置项,并修改location中的proxy_pass内容, 如下代码所示:
upstream domain {    server localhost:9001;    server localhost:9002;    server localhost:9003;}
server {        listen 9000 default_server;        listen [::]:9000 default_server;                # 此处省略原注释配置项若干行        root /var/www/html;
        # Add index.php to the list if you are using PHP        index index.html index.htm index.nginx-debian.html;
        server_name _;
        location / {                proxy_pass http://domain;                proxy_set_header Host $host:$server_port;        }
  • 保存无误后执行:sudo nginx -s reload,然后在浏览器测试不同服务的URL,结果如下:

测试根路径:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

部署flask应用的全部流程和相关配置文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

测试 /app1:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

部署flask应用的全部流程和相关配置文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

测试 /app2:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

部署flask应用的全部流程和相关配置文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

从内容来看,地址端口都没有变,不同的URL代表不同的服务;反应在后端,实际访问的是不同服务器上的应用,也就实现了负载均衡。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

总结文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

通过上面的内容和示例,我们知道了部署flask应用的全部流程和相关配置。而实际项目中,配置要更加复杂,这里只是入门分享。如果要深入掌握原理,建议查看官方文档或其他专题内容...文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/42713.html

  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/bc/42713.html

Comment

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定