eventlet是基于greenlet的基础上实现,由于协程的“非阻塞”特性,基于eventlet的HTTP server 具有很好的网络性能。每一个任务都是在一个独立的线程中执行,并且在“用户态”进行调度。唯一需要注意一点的是,在代码实现上,或者调用上,需要保证引用的第三方库也是非阻塞的,我们可以对第三方I/O库进行“绿化”来使其非阻塞。eventlet提供的wsgi是单线程异步I/O,由于API服务是一个网络交互的过程,异步I/O对于提升性能有很大帮助。
WSGI协议实现了web server 和 application的解耦,对于HTTP请求的处理,分为服务层和应用层,服务层,接收来自于socket的数据包,并将其解析,然后调用application,给application提供环境信息包括请求的详细信息,并且给application传入一个start_reponse的回调函数;在application层,会处理来自于服务器层的请求,然后调用start_reponse函数,返回请求的响应。
关于WSGI协议,详见[[1]][1]
[uwsgi]
wsgi-file = /usr/local/bin/mogan-api-wsgi
chmod-socket = 666
socket = /var/run/uwsgi/mogan-api-wsgi.socket
# Override the default size for headers from the 4k default.
buffer-size = 65535
# This is running standalone
master = true
enable-threads = true
# Tune this to your environment.
processes = 4
# uwsgi recommends this to prevent thundering herd on accept.
thunder-lock = true
plugins = python
# This ensures that file descriptors aren't shared between Searchlight processes.
lazy-apps = true
变迁历史: eventlet -- > mod_wsgi -- > uWSGI 注:Nova在最早的时候直接使用Python web server来作为API服务,但是很快淘汰
eventlet方式启动API服务
eventlet是基于greenlet的基础上实现,由于协程的“非阻塞”特性,基于eventlet的HTTP server 具有很好的网络性能。每一个任务都是在一个独立的线程中执行,并且在“用户态”进行调度。唯一需要注意一点的是,在代码实现上,或者调用上,需要保证引用的第三方库也是非阻塞的,我们可以对第三方I/O库进行“绿化”来使其非阻塞。eventlet提供的wsgi是单线程异步I/O,由于API服务是一个网络交互的过程,异步I/O对于提升性能有很大帮助。
mod_wsgi方式启动API服务
使用mod_wsgi主要基于安全考虑,apache提供了完整的生态,来支持一些安全标准。eventlet只提供了基本的认证功能。eventlet目前也不支持IPV6,目前是在上游做了一些实现来支持(D版的时候,现在已经支持了)。作为一个标准的开源web服务器,提供了更完备的审查机制。支持GSSAPI/Kerberos authentication,服务端和客户端都是基于证书的,也很好地支持IPv6。并且,apache在生产环境中应用广泛,也不会存在性能瓶颈。
mod_wsgi是一个Python包,实现了借助于Apache直接讲一个python的支持WSGI协议的application托管到Apache的web服务器上。有两种方式,一种是配置Apache来加载相应的模块。另一种是通过pip安装mod_wsig的Python包。
WSGI协议实现了web server 和 application的解耦,对于HTTP请求的处理,分为服务层和应用层,服务层,接收来自于socket的数据包,并将其解析,然后调用application,给application提供环境信息包括请求的详细信息,并且给application传入一个start_reponse的回调函数;在application层,会处理来自于服务器层的请求,然后调用start_reponse函数,返回请求的响应。 关于WSGI协议,详见[[1]][1]
mod_wsgi vs uWSGI
相比较于mod_wsgi,uWSGI的方式启动服务,主要有以下不同点
在部署方式上,mod_wsgi是直接将应用托管到apache上,而uWSGI的方式虽然也依赖于Apache,但是Apache只起到了一个代理的作用,而将具体的请求转发到uwsgi服务来处理。
注:它是一个二进制协议,可以携带任何类型的数据。一个uwsgi分组的头4个字节描述了这个分组包含的数据类型。 WSGI是一种Web服务器网关接口。它是一个Web服务器(如nginx)与应用服务器(如uWSGI服务器)通信的一种规范。
如何给一个项目增加uWSGI支持
这里需要注意,通常uWSGI指的是一个Web服务器,它实现了WSGI协议、HTTP、uwsgi等协议。 实现API服务的uWSGI方式启动,需要做如下工作:
其中上面的build_wsgi_app即定义了一个入口,用于返回一个WSGI引用,通过pbr安装项目,会生成一个
/usr/local/binmogan-api-wsgi
的二进制文件用于处理正真的API请求。各种常见的API server框架都提供了WSGI的支持,例如使用Pecan实现的API server,可以通过如下的方式来定义一个WSGI application的入口:在上面的配置文件样例中:wsgi-file定义了真正处理API请求的入口;socket定义了监听请求的端口信息。
mod_proxy_uwsgi
模块,例如在ubuntu下,使用如下命令来打开:mod_proxy_uwsgi
模块的代理配置文件:这里可以看出,利用
mod_proxy_uwsgi
进行了请求转发的功能,通过对应的socket文件定义的端口信息将请求转发给对应于Mogan的uwsgi进程来处理。为什么要使用apache做的代理,直接使用uWSGI交互可以吗?答案是可以的,但是Apache2提供了完善的安全机制以及负载均衡。
涉及到uWSGI启动API服务的相关文件
● uwsgi文件 -- 用于生成一个wsgi对象 ● uwsgi 配置文件--定义一些uwsgi启动参数 ● Apache mod_proxy文件 -- 定义Apache代理入口 ● systemd启动脚本 执行uwsgi --ini /etc/{project}/xxx.ini
参考:
[1] http://geocld.github.io/2017/08/14/wsgi/ [2] http://adam.younglogic.com/2012/03/keystone-should-move-to-apache-httpd/ [3] http://adam.younglogic.com/2012/04/keystone-httpd/ [4] https://governance.openstack.org/tc/goals/pike/deploy-api-in-wsgi.html