使用Python搭建http服务器

为了提高Python网络服务的可移植性 , Python社区在PEP 333中提出了Web服务器网关接口(WSGI , Web Server Gateway Interface) 。
WSGL标准就是添加了一层中间层 。通过这一个中间层 , 用Python编写的HTTP服务就能够与任何Web服务器进行交互了 。现在 , WSGI已经成为了使用Python进行HTTP操作的标准方法 。
按照标准的定义 , WSGI应用程序是可以被调用的 , 并且有两个输入参数 。
1、WSGI
下面是第一段代码 , 第一个参数是environ , 用于接收一个字典 , 字典中提供的键值对是旧式的CGI环境集合的拓展 。第二个参数本身也是可以被调用的 , 习惯上会将其命名为start_response() , WSGI应用程序通过这个参数来声明响应头信息 。
# 用WSGI应用形式编写的简单HTTP服务 。
#!/usr/bin/env python3 # A simple HTTP service built directly against the low-level WSGI spec.from pprint import pformat from wsgiref.simple_server import make_serverdef App(environ, start_response):headers = {'Content-Type': 'text/plain; charset=utf-8'}start_response('200 OK', list(headers.items()))yield 'Here is the WSGI environment:'.encode('utf-8')yield pformat(environ).encode('utf-8')if __name__ == '__main__':httpd = make_server('', 8000, app)host, port = httpd.socket.getsockname()print('Serving on', host, 'port', port)httpd.serve_forever() 上述只是一个简单的情况 。但是在编写服务器程序时 , 复杂度就大大提升了 。这是因为要完全考虑标准中的描述的许多注意点和边界情况 。
2、前向代理与反向代理
无论前向代理还是反向代理 , HTTP代理其实就是一个HTTP服务器 , 用于接收请求 , 然后对接收到的请求(至少是部分请求)进行转发 。转发请求时代理会扮演客户端的角色 , 将转发的HTTP请求发送至真正的服务器 , 最后将从服务器接受到的响应发挥扮演客户端的角色 , 将转发的请求发送至真正的服务器 , 最后将从服务器接受到的响应发回给最初的客户端 。
下面是前向代理和反向代理的简图 。

使用Python搭建http服务器

文章插图
 
 
反向代理已经广泛应用于大型的HTTP服务当中 。反向代理是Web服务的一部分 , 对于HTTP客户端并不可见 。
3、四种架构
架构师一般都使用很多种复杂的机制来将多个子模块组合建成一个HTTP服务 。现在在Python社区中 , 已经形成了4种基本的模式 。如果已经编写了用于生成动态内容的Python代码 , 并且已经选择了某个支持WSGI的API或框架 , 应该如何将HTTP服务部署到线上呢?
运行一个使用Python编写的服务器 , 服务器的代码中可以直接调用WSGI接口 。现在最流行的是Green Unicorn(Gunicorn)服务器 , 不过也有其他已经可以用于生产环境的纯Python服务器 。
配置mod_wsgi并运行Apache , 在一个独立的WSFIDaemonProcess中运行Python代码 , 由mod_wsgi启动守护进程 。
在后端运行一个类似于Gunicorn的Python HTTP服务器(或者支持所选异步框架的任何服务器) , 然后在前端运行一个既能返回静态文件 , 又能对Python编写的动态资源服务进行反向代理的Web服务器 。
在最前端运行一个纯粹的反向代理(如Varnish) , 在该反向代理后端运行Apache或者Nginx , 在后端运行Python编写的HTTP服务器 。这是一个三层的架构 。这些反向代理可以分布在不同的地理位置 , 这样子就能够将离客户端最近的反向代理上的缓存资源返回给发送请求的客户端 。
使用Python搭建http服务器

文章插图
 
 
长期以来 , 对这4个架构的选择主要基于CPython的3个运行时的特性 , 即解释器占用内存大、解释器运行慢、全局解释器(GIL , Global Interpreter Lock)禁止多个线程同时运行Python字节码 。但同时带来了内存中只能载入一定数量的Python实例 。
【使用Python搭建http服务器】4、平台即服务
这个概念的出现是因为现在的自动化部署、持续集成以及高性能大规模服务的相关技术的出现和处理有一些繁杂 。所以有一些提供商提出了PaaS(Platform as a Service) , 现在只需关心应该如何打包自己的应用程序 , 以便将自己的应用部署到这些服务之上 。


推荐阅读