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'")