热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用Python搭建http服务器

DavidWheeler有一句名言:“计算机科学中的任何问题,都可以通过加上另一层间接的中间层解决。”为了提高Python网络服务的可移植性,Python社区在PE
David Wheeler有一句名言:“计算机科学中的任何问题,都可以通过加上另一层间接的中间层解决。”为了提高Python网络服务的可移植性,Python社区在PEP 333中提出了Web服务器网关接口(WSGI,Web Server Gateway Interface)。

为了提高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_server 
 
def 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实例。

4、平台即服务

这个概念的出现是因为现在的自动化部署、持续集成以及高性能大规模服务的相关技术的出现和处理有一些繁杂。所以有一些提供商提出了PaaS(Platform as a Service),现在只需关心应该如何打包自己的应用程序,以便将自己的应用部署到这些服务之上。
PaaS提供商会解决构建和运行HTTP服务中的出现的各种烦心事。不需要再关心服务器,或者是提供IP地址之类的事情。
PaaS会根据客户规模提供负载均衡器。只需要给PaaS提供商提供配置文件即可完成各种复杂的步骤。
现阶段比较常用的有Heroku和Docker。
大多数PaaS提供商不支持静态内容,除非我们在Python应用程序中实现了对静态内容的更多支持或者向容器中加入了Apache或ngnix。尽管我们可以将静态资源和动态页面的路径放在两个完全不同的URL空间内,但是许多架构师还是倾向于将两者放在同一个名字空间内。

5、不使用Web框架编写WSGI可调用对象

下面第一段代码是用于返回当前时间的原始WSGI可调用对象。

#!/usr/bin/env python3 
# A simple HTTP service built directly against the low-level WSGI spec. 
 
import time 
 
def app(environ, start_response): 
    host = environ.get('HTTP_HOST', '127.0.0.1') 
    path = environ.get('PATH_INFO', '/') 
    if ':' in host: 
        host, port = host.split(':', 1) 
    if '?' in path: 
        path, query = path.split('?', 1) 
    headers = [('Content-Type', 'text/plain; charset=utf-8')] 
    if environ['REQUEST_METHOD'] != 'GET': 
        start_response('01 Not Implemented', headers) 
        yield b'01 Not Implemented' 
    elif host != '127.0.0.1' or path != '/': 
        start_response('404 Not Found', headers) 
        yield b'404 Not Found' 
    else: 
        start_response('200 OK', headers) 
        yield time.ctime().encode('ascii')

第一段比较冗长。下面使用第三方库简化原始WGSI的模式方法。
第一个示例是使用WebOb编写的可调用对象返回当前时间。

#!/usr/bin/env python3 
# A WSGI callable built using webob. 
 
import time, webob 
 
def app(environ, start_response): 
    request = webob.Request(environ) 
    if environ['REQUEST_METHOD'] != 'GET': 
        response = webob.Response('501 Not Implemented', status=501) 
    elif request.domain != '127.0.0.1' or request.path != '/': 
        response = webob.Response('404 Not Found', status=404) 
    else: 
        response = webob.Response(time.ctime()) 
    return response(environ, start_response)

第二个是使用Werkzeug编写的WSGI可调用对象返回当前时间。

#!/usr/bin/env python3 
# A WSGI callable built using Werkzeug. 
 
import time 
from werkzeug.wrappers import Request, Response 
 
@Request.application 
def app(request): 
    host = request.host 
    if ':' in host: 
        host, port = host.split(':', 1) 
    if request.method != 'GET': 
        return Response('501 Not Implemented', status=501) 
    elif host != '127.0.0.1' or request.path != '/': 
        return Response('404 Not Found', status=404) 
    else: 
        return Response(time.ctime())

大家可以对比这两个库在简化操作时的不同之处,Werkzeug是Flask框架的基础。



推荐阅读
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • 微软评估和规划(MAP)的工具包介绍及应用实验手册
    本文介绍了微软评估和规划(MAP)的工具包,该工具包是一个无代理工具,旨在简化和精简通过网络范围内的自动发现和评估IT基础设施在多个方案规划进程。工具包支持库存和使用用于SQL Server和Windows Server迁移评估,以及评估服务器的信息最广泛使用微软的技术。此外,工具包还提供了服务器虚拟化方案,以帮助识别未被充分利用的资源和硬件需要成功巩固服务器使用微软的Hyper - V技术规格。 ... [详细]
  • 本文介绍了NetCore WebAPI开发的探索过程,包括新建项目、运行接口获取数据、跨平台部署等。同时还提供了客户端访问代码示例,包括Post函数、服务器post地址、api参数等。详细讲解了部署模式选择、框架依赖和独立部署的区别,以及在Windows和Linux平台上的部署方法。 ... [详细]
  • SQL Server 内存中OLTP内部机制概述(一)
    内存中OLTP(项目名为“Hekaton”)是一个新的完全集成到SQLServer中的数据库引擎组件。它专为访问内存常驻数据的OLTP工作负荷而进行优化。内存中OLTP有助于OLT ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
  • Linux如何安装Mongodb的详细步骤和注意事项
    本文介绍了Linux如何安装Mongodb的详细步骤和注意事项,同时介绍了Mongodb的特点和优势。Mongodb是一个开源的数据库,适用于各种规模的企业和各类应用程序。它具有灵活的数据模式和高性能的数据读写操作,能够提高企业的敏捷性和可扩展性。文章还提供了Mongodb的下载安装包地址。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 怎么在PHP项目中实现一个HTTP断点续传功能发布时间:2021-01-1916:26:06来源:亿速云阅读:96作者:Le ... [详细]
  • 31.项目部署
    目录1一些概念1.1项目部署1.2WSGI1.3uWSGI1.4Nginx2安装环境与迁移项目2.1项目内容2.2项目配置2.2.1DEBUG2.2.2STAT ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • Android系统源码分析Zygote和SystemServer启动过程详解
    本文详细解析了Android系统源码中Zygote和SystemServer的启动过程。首先介绍了系统framework层启动的内容,帮助理解四大组件的启动和管理过程。接着介绍了AMS、PMS等系统服务的作用和调用方式。然后详细分析了Zygote的启动过程,解释了Zygote在Android启动过程中的决定作用。最后通过时序图展示了整个过程。 ... [详细]
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
author-avatar
mobiledu2502911457
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有