python web service开发
由于项目业务需要,接下来的一段时间主要是做web service开发。关于python web service开发主要有两方面的考量:
- 实现服务
- 测试服务性能
服务的整个过程就是提供一个接口供别人来请求,服务器接收请求后就准备数据,并将准备好的结果返回给请求端。小组采用Flask + Gunicorn + Nginx 部署的整体方案来实现服务支持,其中重点需要了解的是Flask和Gunicorn,Nginx是运维那边负责。
Nginx
Nginx(发音同engine x)是异步框架的网页服务器,也可以用作反向代理、负载平衡器和HTTP缓存。该软件由伊戈尔·赛索耶夫创建并于2004年首次公开发布。2011年成立同名公司以提供支持。2019年3月11日,Nginx公司被F5 Networks以6.7亿美元收购。
Nginx是免费的开源软件,根据类BSD许可证的条款发布。一大部分Web服务器使用Nginx,通常作为负载均衡器,作用如下:
- Nginx可以缓存住请求,然后内网再次发起请求,并且可以配置负载均衡,如果一台机器 的多进程(Gunicorn就是多进程)吃不消的情况下,负载均衡可以把请求打向多个机器
- Nginx替代Python处理静态文件的请求,以提高性能
- 很多时候一个机器上可能不止一个服务,需要像Nginx这样的web服务器做一次proxy_pass
下面是其基本框架:
Gunicorn
Gunicorn是Python下的一个WSGI服务器,听起来很普通,不过因为它支持很多特性,在 Python界还是很流行,例如作为起Flask的父进程,支持用gevent把Flask打个patch等。
它使用的是pre-fork的模式,即启动的时候fork出n个进程,然后master进程负责监听 信号和子进程,如果子进程挂了,那么master会拉一个新的起来,如果有对应信号, master会发起相应的动作。
Gunicorn的选项从三个地方读取:
- 首先从框架里指定,这里只有一个叫Paste的框架才有,我们可以忽略之
- 其次从
-c <path/to/configuration>
中指定的python文件里读取 - 最后从命令行参数里读取
顺序是从上往下,优先级递增。
详细的配置都在这里:http://docs.gunicorn.org/en/stable/settings.html
Flask
Flask是一个使用Python编写的轻量级Web应用框架。基于Werkzeug WSGI工具箱和Jinja2 模板引擎。Flask使用BSD授权。
Flask被称为“microframework”,因为它使用简单的核心,用extension增加其他功能。Flask没有默认使用的数据库、窗体验证工具。然而,Flask保留了扩增的弹性,可以用Flask-extension加入这些功能:ORM、窗体验证工具、文件上传、各种开放式身份验证技术。
实现服务
主要服务程序是基于Flask框架编写的,将离线封装好的python程序用Flask封装一下,使其支持GET或POST请求。例如
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run()
上面这个程序为印出Hello World的网页程序,程序启动之后,在本地输入0.0.0.1:5000/
即可出现显示Hello World的网页。
def hello()
就是主函数,离线运算的主函数封装在此就行,其余的Flask框架都封装好的,方便实现接口服务器。
缓存
用完缓存之后,性能得到飞跃的提升。
连接池
由于项目需要多线程读写数据库,所以使用数据库连接池这种方式连接会比较好,不然容易产生数据库事务问题。
数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。
性能测试
性能测试使用工具是siege,在之前的文章《web service压测工具:siege安装及使用介绍》中介绍过了,这里不再进行详细介绍,下面展示性能测试结果:
- 未使用缓存的情况:
- 使用缓存的情况:
- 使用缓存和连接池的情况:
可以看到,当使用缓存时,性能得到飞跃的提升,使用连接池,性能变化不大,但不会产生事物问题。