当前位置: 首页 > news >正文

Python订单生成器+队列+异步提高性能和容错

以下代码实现了一个订单生成器,使用 asyncio 和 aioredis 库实现了高并发地生成订单,并将新增订单异步更新到数据库。具体实现流程如下:

初始化 OrderGenerator 类。传入 Redis 服务器地址和并发数,在初始化函数中设置并发数和一个订单队列,用于存储新生成的订单数据。

定义 generate_order() 方法。该方法使用 Redis 的 WATCH、MULTI 和 EXEC 命令实现事务操作,生成一个订单数据,并将其添加到订单队列和 Redis 缓存中。如果生成订单的过程中监视到订单号已被修改,则重试生成订单,直到生成成功。

定义 update_database() 方法。该方法从订单队列中获取一个订单数据,模拟将其异步更新到数据库的操作,并将更新完成的订单标记为完成。

定义 generate_orders() 方法。该方法在循环中尝试连接 Redis 服务器,如果连接成功则创建多个 generate_order() 协程任务和一个 update_database() 协程任务,等待所有订单生成任务完成后等待订单队列中的所有任务完成,然后取消 update_database() 协程任务并关闭 Redis 连接。如果连接失败,则重试连接,最多重试三次。

import time
import random
import asyncio
import aioredisclass OrderGenerator:def __init__(self, redis_url, num_concurrent=10):# 初始化函数,传入 Redis 服务器地址和并发数self.redis_url = redis_urlself.num_concurrent = num_concurrent# 初始化订单队列,用于存储新生成的订单数据self.order_queue = asyncio.Queue()async def generate_order(self, redis):# 生成订单的协程任务async with redis.pipeline(transaction=True) as pipe:while True:try:# 使用 WATCH 命令监视订单号是否被修改await pipe.watch('order_id')# 获取当前订单号并自增order_id = await pipe.incr('order_id')# 使用 MULTI 命令开始一个事务pipe.multi()# 生成订单数据order_data = {'order_id': order_id,'user_id': random.randint(1, 100),'total_price': random.randint(100, 1000),'create_time': time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}# 将订单添加到队列中await self.order_queue.put(order_data)# 将订单写入缓存await pipe.hmset(f'order:{order_id}', order_data)# 使用 EXEC 命令提交事务await pipe.execute()breakexcept aioredis.WatchError:# 如果订单号被修改,则重新尝试生成订单continueasync def update_database(self):# 将新生成的订单异步更新到数据库的协程任务while True:# 从订单队列中获取一个订单order_data = await self.order_queue.get()# 模拟将订单异步更新到数据库的操作await asyncio.sleep(1)print(f'订单 {order_data["order_id"]} 已更新到数据库')# 标记订单队列中的任务完成self.order_queue.task_done()async def generate_orders(self):retries = 0while retries < 3:# 与 Redis 服务器建立连接redis = await aioredis.Redis.from_url(self.redis_url)try:# 测试 Redis 服务器的可用性await redis.ping()# 创建并发数个生成订单的协程任务tasks = [asyncio.create_task(self.generate_order(redis)) for i in range(self.num_concurrent)]# 创建一个将新订单更新到数据库的协程任务update_task = asyncio.create_task(self.update_database())# 等待所有订单生成任务完成await asyncio.gather(*tasks)# 等待订单队列中的所有任务完成(即新订单更新到数据库)await self.order_queue.join()# 取消将新订单更新到数据库的协程任务update_task.cancel()# 关闭 Redis 连接redis.close()await redis.wait_closed()except (ConnectionError, TimeoutError):# 如果连接失败,则重试retries += 1print(f'Redis server is not available ({retries} retries)')redis.close()await redis.wait_closed()# 如果重试次数仍然失败,则抛出异常raise ConnectionError('Redis server is not available')if __name__ == '__main__':# 实例化 OrderGenerator 类,并运行生成订单的任务order_generator = OrderGenerator('redis://localhost', num_concurrent=10)asyncio.run(order_generator.generate_orders())
http://www.lryc.cn/news/198431.html

相关文章:

  • 理德名人故事:全球投资之父-约翰.邓普顿
  • 微前端三:qiankun 协作开发和上线部署
  • HTML三叉戟,标签、元素、属性各个的意义是什么?
  • prometheus获取kubelet接口监控数据
  • 国产主控应用案例:汉王电子血压计-君正开发板
  • 万宾科技智能井盖传感器特点介绍
  • YoloV8改进策略:SwiftFormer,全网首发,独家改进的高效加性注意力用于实时移动视觉应用的模型,重构YoloV8
  • Jupyter Notebook在指定位置打开
  • 树控件的使用
  • C++实现顺序栈类的定义,编写main ()函数验证顺序栈类设计的合理性
  • 手机直播助手软件app哪个好用?
  • 腾讯待办宣布关停,哪款待办事项提醒APP好?
  • 【单片机毕业设计】【hj-006-7】CO、有害混合气体检测 | 空气质量检测 | 有害气体检测
  • wpf主页面解析
  • 三相交错LLC软启动控制程序算法实现---充电桩电源设计实战细节
  • Chrome 115之后的版本,安装和使用chromedriver
  • 潮玩宇宙:收藏、交流与竞技的数字乐园
  • 企拓客app骗局为不实信息,企拓客保持正常经营状态
  • 【性能】JDK和Jmeter的安装与配置
  • 02_单片机及开发板介绍
  • 华测监测预警系统 2.2---任意文件读取漏洞
  • 新版多功能去水印工具微信小程序源码下载+带流量主功能
  • 文章必备| 叶绿体基因组高级分析内容汇总
  • 阿里实习JAVA后端面经总结
  • 利用 NLP 超能力:一步步介绍Hugging Face微调教程
  • 凝聚技术力量 共建测试生态 ——集成电路测试技术交流日成功举办
  • 机器学习-ROC曲线:技术解析与实战应用
  • macos平台好用的FTP客户端 Transmit 5最新中文
  • 用JavaScript输出0-9的两种方法、以及setTimeout的三个参数的意义
  • 酷鸟云近期主要新功能合集