python并发网络库
一、常见的并发网络库
1、Tornado
Tornado 并发网络库和同时也是一个 web 微框架。适用于微服务,实现 Restful 接口。
(1) 底层基于 Linux 多路复用;
(2) 可以通过协程或者回调实现异步编程;
(3) 生态不完善,相应的异步框架比如 ORM 不完善。
(4) 示例 tornado_demo.py:
import tornado.ioloop
import tornado.web
from tornado.httpclient import AsyncHTTPClient
class APIHandler(tornado.web.RequestHandler):
async def get(self):
url = "http://httpbin.org/get"
http_client = AsyncHTTPClient()
response = await http_client.fetch(url)
print("body: ", response.body.decode())
return response.body
def make_app():
return tornado.web.Application([(r"/api", APIHandler),])
if __name__ == "__main__":
app = make_app()
app.listen(8000)
tornado.ioloop.IOLoop.current().start()
首先我们在第一个终端启动 tornado_demo.py 文件:
接着我们在另一个终端执行:curl http://127.0.0.1:8000/api 命令
再回到第一个终端,会有如下输出信息:
2、Gevent
Gevent 绿色线程(greenlet)实现并发,猴子补丁修改内置 socket。高性能的并发网络库。
(1) 基于轻量级绿色线程(greenlet)实现并发;
(2) 需要注意 monkey patch,gevent 修改了内置的 socket 改为非阻塞;
(3) 配合 gunicorn 和 gevent 部署作为 wsgi server。
(4) 示例 gevent_demo.py:
import gevent.monkey
gevent.monkey.patch_all() # 修改内置的一些库非阻塞
import gevent
import requests
def fetch(i):
url = "http://httpbin.org/get"
response = requests.get(url)
print(str(i) + ":" + str(len(response.text)))
def asynchronous():
threads = []
for i in range(1, 10):
threads.append(gevent.spawn(fetch, i))
gevent.joinall(threads)
print("Asynchronous:")
asynchronous()
运行 gevent_demo.py 文件:
3、Asyncio
python3 内置的并发网络库,基于原生协程。
(1) python3 引入到内置库,协程 + 事件循环;
(2) 生态不够完善,没有大规模生产环境检验;
(3) 目前应用不够广泛,基于 Aiohttp 可以实现一些小的服务。
(4) 示例 aiohttp_demo.py:
"""
基于 aiohttp 并发请求
"""
import asyncio
from aiohttp import ClientSession
async def fetch(url, session):
async with session.get(url) as response:
return await response.read()
async def run(r=10):
url = "http://httpbin.org/get"
tasks = []
async with ClientSession() as session:
for i in range(r):
task = asyncio.ensure_future(fetch(url, session))
tasks.append(task)
response = await asyncio.gather(*tasks)
for body in response:
print(len(body))
loop = asyncio.get_event_loop()
future = asyncio.ensure_future(run())
loop.run_until_complete(future)
运行 aiohttp_demo.py 文件: