需求:
1.将lark的通知方式API重新封装成更接近需求的API
2.对接口API提供请求服务
选择的实现方式:
1.编写相关函数,主要是以请求lark的api为主体实现的
2.选择flask编写API
3.使用gunicorn + gevent启动flask服务
4.将服务封装到docker镜像中
本文重点:
1.如何快速创建简单的flask项目
2.如何使用gunicorn启动flask服务
3.docker封装运行相关细节
本段转载自:Flask + Docker 无脑部署新手教程,也是对我帮助最大的一篇博客,言简意赅,推荐阅读。
由于不涉及数据库相关,我们可以直接在根目录下添加一个app.py文件:
# ./app.py
from gevent import monkey
monkey.patch_all()
from flask import Flask
from flask_cors import CORS
from lark_api import lark_api
# 创建Flask对象
app = Flask(__name__,
template_folder="public",
static_folder="public",
static_url_path="/")
# 将在其他文件 lark_api.py 声明的蓝图 lark_api 在 app 上进行注册
app.register_blueprint(lark_api)
# 跨域请求
CORS(app, supports_credentials=True, origins="*")
# 这里是为了方便后续测试服务是否跑起来
@app.route('/')
def HelloDockerFlask():
return 'Hello Docker Flask!'
if __name__ == "__main__":
app.run(debug=True)
lark_api.py中蓝图的注册方式和api的声明实现,这里只是简单举个例子:
from flask import Blueprint
# 创建蓝图对象
lark_api = Blueprint("lark_api", __name__)
# API声明:分别是自定的url和请求方式
@lark_api.route("/api/lark/card_message", methods=["POST"])
def card_message():
## TODO
切到根目录下,终端运行以下指令,就可以运行flask自带的web服务了
python app.py
可以看到成功启动服务,但是flask自带的web服务比较弱,关闭终端或者超过时延,服务就会被关闭,因此只适合开发测试,不适合生产部署,因此我们后面使用gunicorn启动flask服务。
通过pip可以快速安装
pip install gunicorn gevent
PS:需要注意的是,目前gunicorn只能运行在linux环境中,不支持windows平台。
我们在根目录下新建gunicorn.conf.py文件
# ./gunicorn.conf.py
workers = 5 # 定义同时开启的处理请求的进程数量,根据网站流量适当调整
worker_class = "gevent" # 采用gevent库,支持异步处理请求,提高吞吐量
bind = "0.0.0.0:3000" # 设置端口,这里注意要设置成0.0.0.0,如果设置为127.0.0.1的话就只能本地访问服务了
创建好gunicorn.conf.py后,我们就可以通过gunicorn启动flask服务了
gunicorn app:app -c gunicorn.conf.py
第一个app表示app.py文件;第二个app表示创建的flask对象。
根目录下创建Dockerfile文件,内容:
# 基于的基础镜像,这里使用python,开发版本是 3.x ,基础镜像也写 3.x 就可以,这样可以保持版本一致,避免 Python 版本差异带来的问题
FROM python:3.10
# /app 是要部署到服务器上的路径
WORKDIR /app
# Docker 避免每次更新代码后都重新安装依赖,先将依赖文件拷贝到项目中
COPY requirements.txt requirements.txt
# 执行指令,安装依赖
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
# COPY指令和ADD指令功能和使用方式类似。只是COPY指令不会做自动解压工作。
# 拷贝项目文件和代码
COPY . .
# 执行指令,字符串间是以空格间隔
CMD ["gunicorn", "app:app", "-c", "./gunicorn.conf.py"]
PS:这里我踩了一个坑是FROM python:3.10 开始将‘python’大写了,注意这里必须小写,否则后续build docker会失败,我推测除了FROM其他字段也是一样需要小写。
docker build -t 'noticedemo' .
noticedemo是创建的镜像名称,可以自行修改。
需要注意的是这个过程需要一点时间,首次创建需要拉取基础镜像,并且安装依赖也需要时间。
构建完成之后,通过如下命令查看镜像列表,可以发现 noticedemo显示在其中
docker images
生产环境运行(以daemon方式运行)
docker run -d -p 3000:3000 noticedemo
-d:以daemon方式运行
-p:指定端口映射,格式为:主机(宿主)端口:容器端口
更多参数可以通过docker -help查看
。
# 列出所有镜像
docker images
# 列出容器(运行中的)
docker ps
# 列出所有的容器(包括未运行的)
docker ps -a
# 运行/停止容器
docker start/stop [CONTAINER ID]
# 删除容器
docker rm [CONTAINER ID]
# 删除镜像
docker rmi [IMAGE ID]
如果是公有开源的API服务,可以将镜像 push 到 docker cloud 上实现共享,使用者只要拉取你的镜像就可以在想要部署的服务器上运行服务;
但对于内部其实有更简单的方式,将整个项目文件上传到gitlab或其他类似平台,需要使用服务的人只需要通过拉取代码->创建docker镜像->启动容器运行docker镜像,就可以将服务灵活地部署到想要部署的服务器上;
别忘了写好README文档,主要将启动容器运行docker镜像的命令和API应用文档包含在内就好。