侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

浅析使用Python搭建http服务器

Python  /  管理员 发布于 7年前   172

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请求发送至真正的服务器,最后将从服务器接受到的响应发挥扮演客户端的角色,将转发的请求发送至真正的服务器,最后将从服务器接受到的响应发回给最初的客户端。
下面是前向代理和反向代理的简图。

反向代理已经广泛应用于大型的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服务器。这是一个三层的架构。这些反向代理可以分布在不同的地理位置,这样子就能够将离客户端最近的反向代理上的缓存资源返回给发送请求的客户端。

长期以来,对这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框架的基础。

总结

以上所述是小编给大家介绍的使用Python搭建http服务器,希望对大家有所帮助!


  • 上一条:
    Python搭建代理IP池实现检测IP的方法
    下一条:
    Python搭建代理IP池实现存储IP的方法
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客