mysql 异步编程_异步编程 - 实战案例

实战案例

为了更好理解,上述所有示例的IO情况都是以 asyncio.sleep 为例,而真实的项目开发中会用到很多IO的情况

异步 - Reids

当通过python去操作redis时,链接、设置值、获取值 这些都涉及网络IO请求,使用asycio异步的方式可以在IO等待时去做一些其他任务,从而提升性能。

安装Python异步操作redis模块

pip3 install aioredis

示例1:异步操作redis。

import asyncio

import aioredis

async def execute(address, password):

print("开始执行", address)

# 网络IO操作:创建redis连接

redis = await aioredis.create_redis(address, password=password)

# 网络IO操作:在redis中设置哈希值car,内部在设三个键值对,即: redis = { car:{key1:1,key2:2,key3:3}}

await redis.hmset_dict('car', key1=1, key2=2, key3=3)

# 网络IO操作:去redis中获取值

result = await redis.hgetall('car', encoding='utf-8')

print(result)

redis.close()

# 网络IO操作:关闭redis连接

await redis.wait_closed()

print("结束", address)

asyncio.run(execute('redis://47.93.4.198:6379', "root!2345"))

示例2:连接多个redis做操作(遇到IO会切换其他任务,提供了性能)。

import asyncio

import aioredis

async def execute(address, password):

print("开始执行", address)

# 网络IO操作:先去连接 47.93.4.197:6379,遇到IO则自动切换任务,去连接47.93.4.198:6379

redis = await aioredis.create_redis_pool(address, password=password)

# 网络IO操作:遇到IO会自动切换任务

await redis.hmset_dict('car', key1=1, key2=2, key3=3)

# 网络IO操作:遇到IO会自动切换任务

result = await redis.hgetall('car', encoding='utf-8')

print(result)

redis.close()

# 网络IO操作:遇到IO会自动切换任务

await redis.wait_closed()

print("结束", address)

task_list = [

execute('redis://47.93.4.197:6379', "root!2345"),

execute('redis://47.93.4.198:6379', "root!2345")

]

asyncio.run(asyncio.wait(task_list))

异步 - MySQL

当通过python去操作MySQL时,连接、执行SQL、关闭都涉及网络IO请求,使用asycio异步的方式可以在IO等待时去做一些其他任务,从而提升性能。

安装Python异步操作redis模块

pip3 install aiomysql

示例1:

import asyncio

import aiomysql

async def execute():

# 网络IO操作:连接MySQL

conn = await aiomysql.connect(host='127.0.0.1', port=3306, user='root', password='123', db='mysql', )

# 网络IO操作:创建CURSOR

cur = await conn.cursor()

# 网络IO操作:执行SQL

await cur.execute("SELECT Host,User FROM user")

# 网络IO操作:获取SQL结果

result = await cur.fetchall()

print(result)

# 网络IO操作:关闭链接

await cur.close()

conn.close()

asyncio.run(execute())

示例2:

#!/usr/bin/env python

# -*- coding:utf-8 -*-

import asyncio

import aiomysql

async def execute(host, password):

print("开始", host)

# 网络IO操作:先去连接 47.93.40.197,遇到IO则自动切换任务,去连接47.93.40.198:6379

conn = await aiomysql.connect(host=host, port=3306, user='root', password=password, db='mysql')

# 网络IO操作:遇到IO会自动切换任务

cur = await conn.cursor()

# 网络IO操作:遇到IO会自动切换任务

await cur.execute("SELECT Host,User FROM user")

# 网络IO操作:遇到IO会自动切换任务

result = await cur.fetchall()

print(result)

# 网络IO操作:遇到IO会自动切换任务

await cur.close()

conn.close()

print("结束", host)

task_list = [

execute('47.93.40.197', "root!2345"),

execute('47.93.40.197', "root!2345")

]

asyncio.run(asyncio.wait(task_list))

FastAPI框架

FastAPI是一款用于构建API的高性能web框架,框架基于Python3.6+的 type hints搭建。

接下里的异步示例以FastAPI和uvicorn来讲解(uvicorn是一个支持异步的asgi)。

安装FastAPI web 框架,

pip3 install fastapi

安装uvicorn,本质上为web提供socket server的支持的asgi(一般支持异步称asgi、不支持异步称wsgi)

pip3 install uvicorn

示例:

#!/usr/bin/env python

# -*- coding:utf-8 -*-

import asyncio

import uvicorn

import aioredis

from aioredis import Redis

from fastapi import FastAPI

app = FastAPI()

REDIS_POOL = aioredis.ConnectionsPool('redis://47.193.14.198:6379', password="root123", minsize=1, maxsize=10)

@app.get("/")

def index():

""" 普通操作接口 """

return {"message": "Hello World"}

@app.get("/red")

async def red():

""" 异步操作接口 """

print("请求来了")

await asyncio.sleep(3)

# 连接池获取一个连接

conn = await REDIS_POOL.acquire()

redis = Redis(conn)

# 设置值

await redis.hmset_dict('car', key1=1, key2=2, key3=3)

# 读取值

result = await redis.hgetall('car', encoding='utf-8')

print(result)

# 连接归还连接池

REDIS_POOL.release(conn)

return result

if __name__ == '__main__':

uvicorn.run("luffy:app", host="127.0.0.1", port=5000, log_level="info")

在有多个用户并发请求的情况下,异步方式来编写的接口可以在IO等待过程中去处理其他的请求,提供性能。

例如:同时有两个用户并发来向接口 http://127.0.0.1:5000/red 发送请求,服务端只有一个线程,同一时刻只有一个请求被处理。 异步处理可以提供并发是因为:当视图函数在处理第一个请求时,第二个请求此时是等待被处理的状态,当第一个请求遇到IO等待时,会自动切换去接收并处理第二个请求,当遇到IO时自动化切换至其他请求,一旦有请求IO执行完毕,则会再次回到指定请求向下继续执行其功能代码。

爬虫

在编写爬虫应用时,需要通过网络IO去请求目标数据,这种情况适合使用异步编程来提升性能,接下来我们使用支持异步编程的aiohttp模块来实现。

安装aiohttp模块

pip3 install aiohttp

示例:

import aiohttp

import asyncio

async def fetch(session, url):

print("发送请求:", url)

async with session.get(url, verify_ssl=False) as response:

text = await response.text()

print("得到结果:", url, len(text))

async def main():

async with aiohttp.ClientSession() as session:

url_list = [

'https://python.org',

'https://www.baidu.com',

'https://www.pythonav.com'

]

tasks = [asyncio.create_task(fetch(session, url)) for url in url_list]

await asyncio.wait(tasks)

if __name__ == '__main__':

asyncio.run(main())

总结

为了提升性能越来越多的框架都在向异步编程靠拢,例如:sanic、tornado、django3.0、django channels组件 等,用更少资源可以做处理更多的事,何乐而不为呢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值