uvloop
asyncio 的事件循环的替代方案
效率默认大于asyncio的事件循环
性能是更高的
性能接近go
pip install uvloop
import asyncio
import uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
...
asgi-->uvicorn
内部使用的是uvlooop
异步操作redis
在我们操作redis的时候,连接,操作,断开都是网络io
asyncio 提高并发
pip install aioredis
import asyncio
import uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
import aioredis
async def execute(address,password):
print('开始执行',address)
redis = await aioredis.create_redis(address)
await redis.hmset_dict('car',key1=1,key2=2,key3=3)
res = await redis.hgetall('car',encoding='utf8')
print(res)
redis.close()
await redis.wait_closed()
print('结束',address)
asyncio.run(execute('redis://127.0.0.1:6379',password=''))
import asyncio
import uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
import aioredis
async def execute(address,password):
print('开始执行',address)
redis = await aioredis.create_redis(address)
await redis.hmset_dict('car',key1=1,key2=2,key3=3)
res = await redis.hgetall('car',encoding='utf8')
print(res)
redis.close()
await redis.wait_closed()
print('结束',address)
# asyncio.run(execute('redis://127.0.0.1:6379',password=''))
task_list = [
execute('redis://127.0.0.1:6379',password='') for i in range(0,10000)
]
asyncio.run(asyncio.wait(task_list))
# aioredis.errors.MaxClientsError: ERR max number of clients reached
通过lsof -p pid |wc -l ,发现连接数量超过10500. 出错。
解决方法1:
1. 增加redis的最大连接数:修改redis.conf文件的maxclient ,修改到20000.
2. 一般redis的连接使用完毕之后会释放,如果要用lsof命令发现链接始终没有减少,则检查代码,看下使用redis的代码部分是否执行类似close()的函数。将资源进行释放
import asyncio
import uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
import aioredis
async def execute(address,password):
print('开始执行',address)
try:
redis = await aioredis.create_redis(address)
await redis.hmset_dict('car',key1=1,key2=2,key3=3)
res = await redis.hgetall('car',encoding='utf8')
print(res)
redis.close()
await redis.wait_closed()
print('结束',address)
except aioredis.errors.MaxClientsError as e :
print(e)
await asyncio.sleep(10)
# asyncio.run(execute('redis://127.0.0.1:6379',password=''))
task_list = [
execute('redis://127.0.0.1:6379',password='') for i in range(0,10000)
]
asyncio.run(asyncio.wait(task_list))
# aioredis.errors.MaxClientsError: ERR max number of clients reached
异步操作mysql
pip install aiomysql
import aiomysql
import asyncio
import pymysql
async def execute(host,user,pwd):
try:
conn = await aiomysql.connect(host=host,port=3306,user=user,password=pwd)
cur = await conn.cursor()
await cur.execute("select host,user from mysql.user;")
res = await cur.fetchall()
print(res)
await cur.close()
conn.close()
except pymysql.err.OperationalError as e :
asyncio.sleep(10)
host='127.0.0.1'
user='root'
pwd='1234'
task_list =[
execute(host,user,pwd) for i in range(10000)
]
asyncio.run(asyncio.wait(task_list))
# pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on '127.0.0.1'")