快速开发你的小服务
前言
现在微服务盛行,很多项目依赖一些协同工作小而自治的服务。那么对于python,虽然有grpc
、nameko
这样的微服务框架,或者Flask
、Django
这样的web框架。我们是否可以编写一个轻量可复用的服务框架呢?
准备
python: 2.7+/3.6+
主要库:PyMySQL、redis、DBUtils、requests、supervisor、urllib3、Werkzeug、gevent、gunicorn
简介
我们主要使用Werkzeug
、gevent
、gunicorn
来实现。
Werkzeug
是一个WSGI
工具包,他可以作为一个Web框架的底层库。它可以作为一个 Web 框架的底层库,因为它封装好了很多 Web 框架的东西,例如 Request
,Response
等等,例如 Flask
框架就是一 Werkzeug
为基础开发的.
Gevent
是一个基于greenlet
的Python的并发框架,以微线程greenlet
为核心,使用了epoll
事件监听机制以及诸多其他优化而变得高效。
Gunicorn
是一个unix上被广泛使用的高性能的Python WSGI UNIX HTTP Server。和大多数的web框架兼容,并具有实现简单,轻量级,高性能等特点。
一般微服务都是本质上是一些数据库简易CRUD操作的集合,一个服务基本包含数据库连接、日志记录,业务逻辑等。那么我们看看这些的基本实现.
实现
数据库连接
mysql我们使用pymysql
和DBUtils
做一个连接池,缓存我们使用redis
.
操作数据库我们也使用了日志记录,日志记录实现请看下段。
1 | #!/usr/bin/env python |
日志记录
使用logging模块,配置轮转
1 | #!/usr/bin/env python |
请求返回
我们编写了一个expose装饰器来做路由:
1 | #!/usr/bin/env python |
对应url_map绑定到环境:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @File : app.py
# @Author : cgDeepLearn
# @Create Date : 2020/11/12-2:47 下午
from gevent import monkey
monkey.patch_all()
from traceback import format_exc
from werkzeug.wrappers import Request, Response
from werkzeug.exceptions import HTTPException, NotFound, MethodNotAllowed, BadRequest
from server import g_server
from utils.log import logger
from decorator import url_map
def g_app(environ, start_response):
request = Request(environ)
adapter = url_map.bind_to_environ(environ)
try:
endpoint, values = adapter.match()
response = getattr(g_server, endpoint)(request, **values)
except (NotFound, MethodNotAllowed, BadRequest) as e:
response = e
except HTTPException as e:
response = e
except:
Response()
response = Response('Uncatched Error')
logger.error('app uncatched error, exception:%s', format_exc())
return response(environ, start_response)请求/test响应示例
1 | #!/usr/bin/env python |
如果我们想要新增一个路由,只需再server模块增加对应处理即可
业务逻辑简答示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @File : api.py
# @Author : cgDeepLearn
# @Create Date : 2020/11/16-3:40 下午
import datetime
import random
class TestApi(object):
def __init__(self, req_data):
self.req_data = req_data
def process(self):
"""
处理返回
"""
results = [-1, 0, 1]
res = {
'timestamp': datetime.datetime.now().timestamp(),
'result': random.choice(results)
}
return res
gunicorn 配置
我们使用gevent协程工作方式,配置对应服务器ip、端口、进程数等参数。
1 | #!/usr/bin/env python |
启动脚本
脚本里使用gunicorn启动服务、通过kill
命令停止、重载或者重启服务。
1 | !/bin/sh |
请求示例
请求:
1
curl http://127.0.0.1:10001/test -d '{"order_id":12345}'
返回:
1
{"order_id": 12345,"uuid": "e3bd4a7e-35eb-11eb-bd7e-5254008f07ce","err_msg":"ok","err_code":0,"data": {"timestamp":1589193745,"result":1}}
小结
以上我们使用Werkzeug
、gevent
、gunicorn
实现了一个轻量的python服务,修改配置、添加对应业务逻辑即可快速开发一个业务对应的微服务。项目git代码: https://github.com/cgDeepLearn/pyserver
此外
- 我们还可以使用
supervisor
来控制服务的监控拉起。 - 使用
docker
来进行容器化管理 使用cookiecutter来生成可配置的代码
使用
serviceMesh
来进行服务注册发现