Gevent
Gevent 是一个基于协同程序的 Python 网络库,使用 greenlet 来在 libevent 的事件循环上提供高层的同步 API
from gevent.wsgi import WSGIServer
from yourapplication import app
http_server = WSGIServer(('', 5000), app)
http_server.serve_forever()
uWSGI
uWSGI 也是部署 Flask 的途径之一,类似的部署途径还有 nginx 、 lighttpd 和 cherokee 。其他部署途径的信息参见 FastCGI 和 独立 WSGI 容器 。使用 uWSGI 协议来部署 WSGI 应用的先决条件是 需要一个 uWSGI 服务器。 uWSGI 既是一个协议也是一个服务器。如果作为一个服务器, 它可以服务于 uWSGI 、 FastCGI 和 HTTP 协议。
最流行的 uWSGI 服务器是 uwsgi ,本文将使用它来举例,请先安装它。
注意:
请务必把 app.run()
放在 if __name__ == '__main__':
内部或者放在单独 的文件中,这样可以保证它不会被调用。因为,每调用一次就会开启一个本地 WSGI 服务器。当我们使用 uWSGI 部署应用时,不需要使用本地服务器。
使用 uwsgi 启动你的应用¶
uwsgi 是基于 python 模块中的 WSGI 调用的。假设 Flask 应用名称为 myapp.py , 可以使用以下命令:
$ uwsgi -s /tmp/uwsgi.sock --module myapp --callable ap
或者这个命令也行:
$ uwsgi -s /tmp/uwsgi.sock -w myapp:app
考虑到gunicorn能实现并发操作,就选用gunicorn作为项目的服务器,然后因为Linux会今至绑定1024以下的端口,所以部署的时候使用到Nginx进行代理转发
gunicorn的安装与使用
安装方式可使用pip安装
pip3 install gunicorn gevent
安装之后如果运行gunicorn 命令
出现 common not found
,则将pip3的包路径添加到环境变量中
➜ pip3 show gunicorn
Name: gunicorn
Version: 20.0.4
Summary: WSGI HTTP Server for UNIX
Home-page: http://gunicorn.org
Author: Benoit Chesneau
Author-email: benoitc@e-engura.com
License: MIT
Location: /home/lincx/.local/lib/python3.8/site-packages
Requires: setuptools
Required-by:
➜ vim ~/.bashrc
在bashrc文件末尾添加
export PATH=$PATH:/home/lincx/.local/bin
此处根据你的机器显示的路径修改将/lib/xxx更换成/bin
运行命令
简单地,gunicorn可以通过gunicorn -w 4 -b 127.0.0.1:4000 run:app
启动一个Flask应用。其中,
-w 4
是指预定义的工作进程数为4,
-b 127.0.0.1:4000
指绑定地址和端口
- run是flask的启动python文件,app则是flask应用程序实例
通过gunicorn -h
可以看到gunicorn的所有配置项,通常部署项目会写一个配置文件进行配置,如下,gunicorn.conf.py为一个配置文件,内容为
# gunicorn.conf.py
workers = 5
worker_class = "gevent"
bind = "0.0.0.0:8087"
运行项目命令
➜ gunicorn app:app -c gunicorn.conf.py
接下来,
将项目打包成镜像
在这里,我踩了一个坑,为了追求镜像的简洁,我当初想到的方案是,使用Alpine作为基础镜像,然后在这个基础上边配置python3 环境,再将flask项目copy 到镜像中,运行
想法是美好的,现实是残酷的。Alpine 不支持Matplotlib、Numpy、Pandas这类数据科学计算相关的库安装,编译的时候会报错,起初我以为是python版本的原因,所以尝试配置了各种版本的python,但是结果都差不多,折腾了好久
这是怎么搞的?如果你仔细看上面基于Ubuntu的构建,你会发现它下载三方库的安装包是matplotlib-3.1.2-cp38-cp38-manylinux1_x86_64.whl,这是一个预编译的二进制安装包。而Alpine则只能下载源代码(matplotlib-3.1.2.tar.gz)的压缩包,这就是Alpine的致命问题:标准的Linux安装包在Alpine Linux上根本无法使用。
大多数Linux发行版都使用GNU版本的标准C库(glibc),几乎所有基于C语言的脚本语言都需要这个库,包括Python。但Alpine Linux使用的是musl,那些二进制安装包是针对glibc编译的,因此Alpine禁用了Linux安装包支持。现在大多数Python包都在PyPI上包含了二进制安装包,大大加快了安装时间。但是如果你使用的是Alpine Linux,你需要编译你使用的每一个Python包中的所有C源码。
解决方案
将基础镜像换成ubuntu,在本地环境,如果你只是想“玩一玩”,那么基础镜像选择Alpine无可厚非,但是如果你想要将你的python应用部署到生产环境时,特别是部署分布式系统需要多次编译的场景下,选择老牌的Ubuntu显然更加的明智。
制作python环境的ubuntu镜像
为了提高这个镜像的重用性,方便以后部署python相关的项目,我先制作了一个配置好python环境的ubuntu镜像
- 首先编写dockerfile
FROM ubuntu:20.04
# This hack is widely applied to avoid python printing issues in docker containers.
# See: https://github.com/Docker-Hub-frolvlad/docker-alpine-python3/pull/13
ENV PYTHONUNBUFFERED=1
RUN apt-get update -y && \
apt-get install -y python3-pip python3-dev
运行构建镜像命令 docker build -t ubuntu-flask:1.0 .
命令说明:
build : docker创建镜像的命令
-t ,-tag: 镜像的名字及标签,通常 name:tag 或者 name 格式;可以在一次构建中为一个镜像设置多个标签。
ubuntu-flask:1.0 :镜像名字以及版本号
注意要加上.
运行docker images
可看到容器创建成功
基于ubuntu_flask镜像创建项目的镜像
1、首先,cd进入项目目录,将项目中用到的模块,导出至requirements.txt文件中
pip3 freeze > requirements.txt
2、在当前目录下编写dockerfile
FROM ubuntu_flask:1.0
RUN sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list#更换apt下载源
RUN sed -i s@/security.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list#更换apt下载源
#将当前文件夹下面的requirements.txt复制到容器中
COPY ./requirements.txt /requirements.txt
#根目录为工作目录
WORKDIR /
#安装依赖
RUN pip3 install -r requirements.txt
#将当前目录下的文件拷贝至容器根目录
COPY . /
#执行命令
CMD ["gunicorn", "app:app", "-c", "./gunicorn.conf.py"]
3、创建镜像
docker build -t ubun-flask-st .
4、运行容器
docker run -d -p 8087:8087 --name stapp ubun-flask-st:latest
5、测试结果
6、成功!
7、打包镜像,发布到阿里云镜像站或者腾讯云镜像站
➜ sudo docker login --username=xxxxxx registry.cn-shenzhen.aliyuncs.com
[sudo] password for lincx:
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
➜ sudo docker tag [镜像id] registry.cn-shenzhen.aliyuncs.com/xxxxx/stapp:1.0
➜ sudo docker push registry.cn-shenzhen.aliyuncs.com/xxxx/stapp:1.0
8、到此,本地工作结束
腾讯云服务器部署
前提条件:安装了docker
登录服务器
到这里,工作就很简单了,只需要几个操作
1、登录阿里镜像站
➜ sudo docker login --username=xxxxxx registry.cn-shenzhen.aliyuncs.com
[sudo] password for lincx:
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
2、拉取项目镜像
sudo docker push registry.cn-shenzhen.aliyuncs.com/xxxx/stapp:1.0
3、运行容器
docker run -d -p 8087:8087 --name stapp ubun-flask-st:latest
4、使用nginx做反向代理,这里我也是用docker搭配nginx做的,详情请看[这篇文章](https://lincx_py.gitee.io/2020/12/13/deploy/)
5、在第4步基础上,编辑nginx的conf文件,添加下面内容至server{}
中
location /st/ {
#proxy_set_header X-Real-IP $remote_addr;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_set_header Host $http_host;
#proxy_set_header X-Nginx-Proxy true;
#proxy_set_header Connection "";
#proxy_pass http://xxxxxx:8087/;#这里填服务器的ip
}
6、测试结果:
成功!!!!
小白第一次部署,有不足之处请海涵