高并发 发送请求(asyncio)

news2024/11/17 3:30:54

在接手这个项目之前,关于数据存储的代码逻辑如上图,看起来按部就班,也很合理。(本人觉得这就像个玩具车)

在最后一步发送HTTP request响应足够快的话,其实速度说不上快但稳定,可以接受。但偏偏第三季度了,数据量上来了,最后一步得到response的时间达到了2秒多(因为这个请求是往mysql里存储新数据,数据量很大的情况下,存储会慢很多),若是一个压缩包有一万条数据,那处理该文件的时间能达到6小时左右,每天可能有几十个这样的压缩包进入监测文件系统。(意思是 要用这个玩具车 去工地盖大楼了,无语......)

话说,对这样一个简单直接的逻辑,能想到几种优化方法?

  1. 批量插入数据,在最后一步HTTP请求中批量发送数据,批量入库,这样比一个请求创建一个文件相关的数据快多了。

    BUT: 看了一下项目的代码,在HTTP请求发送后,入库的逻辑不是简单的创建一条数据,还会有:

    • 关联关系表的数据创建。

    • 非关联关系表的数据创建。

    • 每条数据入库前需要检查是否符合配置要求,不符合需剔除。

    • 需用规则表查寻规则信息,看情况为每条数据创建任务,并将任务记录在另一个表中。

    • 每个入库请求执行完需要记录成功数量和失败原因。

    所以批量入库会有不小的麻烦,但也不是不可能,只要考虑的全面一些。我怕麻烦,果断pass

  2. 多线程处理队列任务,在第二步中,仅用了单线程去处理队列(blocked)任务

    由于GIL和blocked Queue等原因,多线程和单线程应该没差

  3. 多进程

    需要考虑进程间通信等因素,说实话,我一直觉得,直接用Python的multiprocessing不是个好主意,除非你是大神,否则会遇到很多Errors,即使能跑起来,稳定性也会让你自我怀疑。

  4. 最简单的应该就是对最后一个for循环下手了,异步发送数据入库请求,不要一个等一个,就会快很多了,我觉得这个是最简单快速的处理方法。

    首先,这样对原始逻辑的改动不大,又能实现目的,何乐而不为。

    通常在Python中我们进行并发编程一般都是使用多线程或者多进程来实现的,对于计算型任务由于GIL的存在我们通常使用多进程来实现,而对于IO型任务我们可以通过线程调度来让线程在执行IO任务时让出GIL,从而实现表面上的并发。其实对于IO型任务我们还有一种选择就是协程,协程是运行在单线程当中的"并发",协程相比多线程一大优势就是省去了多线程之间的切换开销,获得了更大的运行效率。

重写的过程中(是的推翻重写,玩具就是玩具),看到了asyncio,之前从没用过,来学习一下。

asyncio 异步I/O

asyncio 是用来编写 并发 代码的库,使用async/await 语法。 asyncio 被用作多个提供高性能 Python 异步框架的基础,包括网络和网站服务,数据库连接库,分布式任务队列等等。

asyncio 可以实现单线程并发IO操作, 由于HTTP连接就是IO操作,因此可以用单线程+coroutine实现多用户的高并发支持。

asyncio实现了TCPUDPSSL等协议,aiohttp则是基于asyncio实现的HTTP框架。

为了简化并更好地标识异步IO,从Python3.5开始引入了新的语法asyncawait,可以让coroutine的代码更简洁易读。

Eventloop

Eventloop可以说是asyncio应用的核心,是中央总控。Eventloop实例提供了注册、取消和执行任务和回调的方法。

把一些异步函数(就是任务,Task,一会就会说到)注册到这个事件循环上,事件循环会循环执行这些函数(但同时只能执行一个),当执行到某个函数时,如果它正在等待I/O返回,事件循环会暂停它的执行去执行其他的函数;当某个函数完成I/O后会恢复,下次循环到它的时候继续执行。因此,这些异步函数可以协同(Cooperative)运行:这就是事件循环的目标。

Coroutine

协程,又称微线程,纤程,英文名Coroutine。协程的作用是在执行函数A时可以随时中断去执行函数B,然后中断函数B继续执行函数A(可以自由切换)。但这一过程并不是函数调用,这一整个过程看似像多线程,然而协程只有一个线程执行。

协程(Coroutine)本质上是一个函数,特点是在代码块中可以将执行权交给其他协程

Future

它代表了一个「未来」对象,异步操作结束后会把最终结果设置到这个Future对象上。Future是对协程的封装,不过日常开发基本是不需要直接用这个底层Future类的。

Task

Eventloop除了支持协程,还支持注册Future和Task 2种类型的对象,那为什么要存在Future和Task这2种类型呢?

先回忆前面的例子,Future是协程的封装,Future对象提供了很多任务方法(如完成后的回调、取消、设置任务结果等等),但是开发者并不需要直接操作Future这种底层对象,而是用Future的子类Task协同的调度协程以实现并发

最后一个循环的请求发送要提出来一个异步函数了,用async 修饰

async def send_request(data, semaphore):
    async with semaphore:
        async with ClientSession() as _session:
            async with _session.post(url, data=data) as res:
                if res.status == 200:
                    print("入库成功")
                    # content_type设置为None不去检查content type,可以避免response解析错误,因为下面调用了json
                    content = res.json(content_type=None, encoding="utf-8")
                else:
                    # 或在此分类错误返回信息
                    print("入库失败")
                    content = {"error": "解析失败"}
                # 请求的服务端是Django项目,一个请求就会创建一个连接,拿到结果后使用close可避免占用连接过多
                res.close()
                # 因为我的逻辑需要统计入库信息,所以要结果返回,若不需要结果,则不用返回
                return content
                

常见错误

  • aiohttp message='Attempt to decode JSON with unexpected mimetype: text/html;

    或者是另一种content type application/json,都有可能遇到,

  • RuntimeWarning: Enable tracemalloc to get the object allocation traceback

    调用async标记的函数时没有使用前缀 await 修饰

  • Too many connections

        Django后端可能并发处理两个请求,会创建重复数据,解决方法是设置unique属性

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1073509.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

segment方案解决VXLAN分布式网关DCI间互联

segment概念: segment方案是在需要互联的两个DCI间建立3条VXLAN隧道实现两个DCI间的二层和三层间互通需求,常用于大型的DCI间互联,无需考虑两个DCI内的VXLAN参数规划的不同,其中二层互通可以采用映射VNI或局部VNI的方式进行解决&…

运营商大数据,三网融合大数据,联通大数据,移动大数据

有许多公司和企业依靠电话营销和短信营销。对于他们来说,客户资源就是维生素和维生素,客户资源的及时性和准确性是这些公司和企业最关心的问题。长期使用低质量、大量无效的客户资源,是对时间的浪费,是对人力物力财力的浪费&#…

基于Springboot实现房屋租赁租房平台系统项目【项目源码+论文说明】

基于Springboot实现房屋租赁租房平台系统演示 摘要 在网络高速发展的时代,众多的软件被开发出来,给用户带来了很大的选择余地,而且人们越来越追求更个性的需求。在这种时代背景下,房东只能以用户为导向,所以开发租房网…

基于springboot实现准妈妈孕期交流平台项目【项目源码+论文说明】分享

基于springboot实现准妈妈孕期交流平台演示 摘要 随着科学技术的飞速发展,社会的方方面面、各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势,准妈妈孕期交流平台当然也不能排除在外。准妈妈孕期交流平台是以实际运用为开…

加密的重要性,MySQL加密有哪些好处?

加密是一种将信息转化为无法直接读取的格式的技术,从而保护信息安全。在当今数字化的世界中,数据已成为企业的重要资产,因此加密的重要性不言而喻。在这篇文章中,我们将探讨MySQL加密的好处以及如何选择合适的加密算法。 MySQL加密…

Windows系统安装

安装Windows系统有很多方法、而Windows系统也有不同的版本,下面主要介绍两种方法安装系统,第一种是使用微软官方提供的镜像文件安装Win10系统,第二种是使用微PE工具箱来安装Win10系统 准备工作:内存大于8G的空U盘,Win1…

软件测试「转行」答疑(未完更新中)

⭐ 专栏简介 软件测试行业「转行」答疑: 如果你对于互联网的职业了解一知半解!不知道行业的前景如何?对于众说纷纭的引流博主说法不知所措!不确定这个行业到底适不适合自己? 那么这一篇文章可以告诉你所有真实答案&a…

10-Node.js入门

01.什么是 Node.js 目标 什么是 Node.js,有什么用,为何能独立执行 JS 代码,演示安装和执行 JS 文件内代码 讲解 Node.js 是一个独立的 JavaScript 运行环境,能独立执行 JS 代码,因为这个特点,它可以用来…

使用docker搭建nacos单机、集群 + mysql

单机搭建 1 拉取mysql镜像 docker pull mysql:5.7.40 2 启动mysql容器 docker run -d --namemysql-server -p 3306:3306 -v mysql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD123456 mysql:5.7.40 3 执行nacos的数据库脚本 /* * Copyright 1999-2018 Alibaba Group Holding L…

树的基本概念及二叉树

目录 一、树的基本概念 (1)树的结点 (2)度 (3)结点层次 (4)树的高度 树的特点: 二、二叉树 (1)满二叉树 (2)完…

nodejs 16版本

Index of /download/release/latest-v16.x/

医院内网多台主机中毒流量分析案例

背景 最近医院的医生多次反馈网络出现慢和卡顿现象。医院十分重视这个问题,并将之反馈给网络部门同事进行处理。经过多次排查和分析,并没有发现网络中的异常情况。为了更好地解决这一问题,我们推荐安装NetInside流量分析系统。这个系统可以对…

c++视觉图像----扩充边界

图像扩充边界 #include <opencv2/opencv.hpp> #include <opencv2/highgui/highgui.hpp>int main() {// 读取图像cv::Mat image cv::imread("1.jpg", cv::IMREAD_COLOR);if (image.empty()) {std::cerr << "Could not open or find the imag…

【JVM--StringTable字符串常量池】

文章目录 1. String 的基本特性2. 字符串拼接操作3. intern()的使用4. StringTable 的垃圾回收 1. String 的基本特性 String 声明为 final 的&#xff0c;不可被继承String 实现了 Serializable 接口&#xff1a;表示字符串是支持序列化的。String 实现了 Comparable 接口&am…

求臻人故事 | 在求臻医学的沃土中,我像竹子般茁壮成长

在这个快节奏的社会中&#xff0c;我们时常忽略了身边的“小人物”&#xff0c;他们或许默默无闻&#xff0c;或许平凡无奇&#xff0c;但他们的经历、奋斗和成就&#xff0c;却能给我们带来深深的启示。让我们一起走进每个平凡的求臻人世界&#xff0c;聆听他们的“大故事”&a…

Direct3D网格(一)

创建网格 我们可以用D3DXCreateMeshFVF函数创建一个"空"网格对象 &#xff0c;空网格对象是指我们指定了网格的面片总数和顶点总数&#xff0c;然后由该函数为顶点缓存、索引缓存和属性缓存分配大小合适的内存&#xff0c;之后即可手工填入网格数据。 HRESULT WINA…

供水管网监测系统

随着城市人口的不断增长和经济的快速发展&#xff0c;供水管网的安全和可靠性变得尤为重要。在过去&#xff0c;供水管网的监测往往是依靠人工巡查&#xff0c;这种方式不仅费时费力&#xff0c;而且容易出现疏漏和盲区。然而&#xff0c;随着科技的进步&#xff0c;供水管网监…

【算法|动态规划No.16】leetcode931. 下降路径最小和

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…

智能售后工单系统是什么?智能工单系统有什么用?

对于传统的客服问题处理机制中&#xff0c;如果使用智能工单详细记录客户的问题以及解决问题的全过程&#xff0c;可以有效地帮助客服中心或业务管理层从总体层面了解客户的问题&#xff0c;给出有效的解决方案以及处理问题的紧急程度。从每个服务分支到问题&#xff0c;基于大…

361154-30-5|点击糖化学试剂Ac4ManNAz

产品简介&#xff1a;N-叠氮乙酰基甘露糖胺-三酰化&#xff08;AC4MANAZ&#xff09;可用作标记试剂&#xff0c;点击糖化学试剂&#xff0c;叠氮化物基团允许它与炔烃反应&#xff0c;是一种含叠氮的代谢糖蛋白标记试剂&#xff0c;叠氮化物修饰的蛋白质可以通过与炔烃反应检测…