一次线上事故,我顿悟了异步的精髓

news2024/12/26 0:46:50

在高并发的场景下,异步是一个极其重要的优化方向。

前段时间,生产环境发生一次事故,笔者认为事故的场景非常具备典型性

写这篇文章,笔者想和大家深入探讨该场景的架构优化方案。希望大家读完之后,可以对异步有更深刻的理解。

1 业务场景

老师登录教研平台,会看到课程列表,点击课程后,课程会以视频的形式展现出来。

访问课程详情页面,包含两个核心动作:

  1. 读取课程视频信息 :

    从缓存服务器 Redis 获取课程的视频信息 ,返回给前端,前端通过视频组件渲染。

  2. 写入课程观看行为记录 :

    当教师观看视频的过程中,浏览器每隔3秒发起请求,教研服务将观看行为记录插入到数据库表中。而且随着用户在线人数越多,写操作的频率也会指数级增长。

上线初期,这种设计运行还算良好,但随着在线用户的增多,系统响应越来越慢,大量线程阻塞在写入视频观看进度表上的 Dao 方法。上。

首先我们会想到一个非常直观的方案,提升写入数据库的能力

  1. 优化 SQL 语句;
  2. 提升 MySQL 数据库硬件配置 ;
  3. 分库分表。

这种方案其实也可以满足我们的需求,但是通过扩容硬件并不便宜,另外写操作可以允许适当延迟和丢失少量数据,那这种方案更显得性价比不足。

那么架构优化的方向应该是: “减少写动作的耗时,提升写动作的并发度” , 只有这样才能让系统更顺畅的运行。

于是,我们想到了第二种方案:写请求异步化

  • 线程池模式
  • 本地内存 + 定时任务
  • MQ 模式
  • Agent 服务 + MQ 模式

2 线程池模式

2014年,笔者在艺龙旅行网负责红包系统相关工作。运营系统会调用红包系统给特定用户发送红包,当这些用户登录 app 后,app 端会调用红包系统的激活红包接口 。

激活红包接口是一个写操作,速度也比较快(20毫秒左右),接口的日请求量在2000万左右。

应用访问高峰期,红包系统会变得不稳定,激活接口经常超时,笔者为了快速解决问题,采取了一个非常粗糙的方案:

"控制器收到请求后,将写操作放入到独立的线程池中后,立即返回给前端,而线程池会异步执行激活红包方法"。

坦率的讲,这是一个非常有效的方案,优化后,红包系统非常稳定。

回到教研的场景,见下图,我们也可以设计类似线程池模型的方案:

使用线程池模式,需要注意如下几点:

  1. 线程数不宜过高,避免占用过多的数据库连接池 ;
  2. 需要考虑评估线程池队列的大小,以免出现内存溢出的问题。

3 本地内存 + 定时任务

开源中国统计浏览数的方案非常经典。

用户访问过一次文章、新闻、代码详情页面,访问次数字段加 1 , 在 oschina 上这个操作是异步的,访问的时候只是将数据在内存中保存,每隔固定时间将这些数据写入数据库。

示例代码如下:

我们可以借鉴开源中国的方案 :

  1. 控制器接收请求后,观看进度信息存储到本地内存 LinkedBlockingQueue 对象里;
  2. 异步线程每隔1分钟从队列里获取数据 ,组装成 List 对象,最后调用 Jdbc batchUpdate 方法批量写入数据库;
  3. 批量写入主要是为了提升系统的整体吞吐量,每次批量写入的 List 大小也不宜过大 。

这种方案优点是:不改动原有业务架构,简单易用,性能也高。该方案同样需要考虑内存溢出的风险。

4 MQ 模式

很多同学们会想到 MQ 模式 ,消息队列最核心的功能是异步解耦,MQ 模式架构清晰,易于扩展。

核心流程如下:

  1. 控制器接收写请求,将观看视频行为记录转换成消息 ;
  2. 教研服务发送消息到 MQ ,将写操作成功信息返回给前端 ;
  3. 消费者服务从 MQ 中获取消息 ,批量操作数据库 。

这种方案优点是:

  1. MQ 本身支持高可用和异步,发送消息效率高 , 也支持批量消费;
  2. 消息在 MQ 服务端会持久化,可靠性要比保存在本地内存高;

不过 MQ 模式需要引入新的组件,增加额外的复杂度。

5 Agent 服务 + MQ 模式

互联网大厂还有一种常见的异步的方案:Agent 服务 + MQ 模式。

教研服务器上部署 Agent 服务(独立的进程) , 教研服务接收写请求后,将请求按照固定的格式(比如 JSON )写入到本次磁盘中,然后给前端返回成功信息。

Agent 服务会监听文件变动,将文件内容发送到消息队列 , 消费者服务获取观看行为记录,将其存储到 MySQL 数据库中。

还有一种演进,假设我们不想在应用中依赖消息队列,不生成本地文件,可以采用如下的方式:

这种方案最大的优点是:架构分层清晰,业务服务不需要引入 MQ 组件。

笔者原来接触过的性能监控平台,或者日志分析平台都使用这种模式。

6 总结

学习需要一层一层递进的思考。

第一层:什么场景下需要异步

  • 大量写操作占用了过多的资源,影响了系统的正常运行;
  • 写操作异步后,不影响主流程,允许适当延迟;

第二层:异步的外功心法

本文提到了四种异步方式:

  • 线程池模式
  • 本地内存 + 定时任务
  • MQ 模式
  • Agent 服务 + MQ 模式

它们的共同特点是:将写操作命令存储在一个池子后,立刻响应给前端,减少写动作的耗时。任务服务异步从池子里获取任务后执行。

第三层:异步的本质

在笔者看来,异步是更细粒度的使用系统资源的一种方式

在教研课程详情场景里,数据库的资源是固定的,但写操作占据大量数据库资源,导致整个系统的阻塞,但写操作并不是最核心的业务流程,它不应该占用那么多的系统资源。

我们使用异步的解决方案时,无论是使用线程池,还是本地内存 + 定时任务 ,亦或是 MQ ,对数据库资源的使用都需要在合理的范围内,只有这样系统才能顺畅的运行。

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

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

相关文章

Linux 环境变量 命令行参数

文章目录 问题引入环境变量环境变量相关操纵(附源码)命令行参数问题解释 问题引入 Linux下,为什么我们自己写的可执行文件需要写明路径才可以执行,而系统的命令不需要? 如何使自己的命令也可以不带路径执行&#xff…

MioIO笔记01

视频地址:分布式文件系统MinIO教程,2021最新版【通俗易懂】_哔哩哔哩_bilibili 目录 1【分布式文件存储系统Minio实战】 P001【1.课程介绍】05:08 P002【2.Minio优点和基础概念】19:29 P003【3.Minio的EC码和文件存储结构】11:33 2【Minio环境搭建】…

【youcans动手学模型】ShuffleNet 模型

欢迎关注『youcans动手学模型』系列 本专栏内容和资源同步到 GitHub/youcans 【youcans动手学模型】ShuffleNet 模型 1. ShuffleNet 网络模型1.1 模型简介1.2 论文介绍 2. 在 PyTorch 中定义 ShuffleNet V1 模型类2.1 分组卷积与通道混洗2.2 ShuffleNet 单元2.3 自定义 Shuffle…

0、如何用运python成为顶级黑客

前言 黑客攻击可以导致个人、组织或公司的机密信息被窃取、破坏或泄露,造成财务损失、声誉受损、系统崩溃等各种问题 一、为什么Python编程语言适合网络安全工作? Python编程语言在网络安全工作中具有许多优势,以下是一些详细介绍&#xf…

性能测试中的随机数性能问题探索

目录 缘起 多线程 单线程 末了 总结: 在软件测试中,经常会遇到随机数。我简单分成了两类: 简单取随机数; 从一个集合中随机取值。 其实第二个场景包含在第一个场景内。对于接口测试来说,通常我们直接使用第二种…

springboot定时任务详解

文章目录 一、基于注解(静态)1、添加依赖2、创建定时任务3、参数说明 二、基于接口(动态)1、添加依赖2、添加数据库记录3、创建定时器4、启动测试 三、Quartz1、添加依赖2、编写任务类3、编写配置类4、启动项目 在我们开发项目过程…

css基础知识十四:什么是响应式设计?响应式设计的基本原理是什么?如何做?

一、是什么 响应式网站设计(Responsive Web design)是一种网络页面设计布局,页面的设计与开发应当根据用户行为以及设备环境(系统平台、屏幕尺寸、屏幕定向等)进行相应的响应和调整 描述响应式界面最著名的一句话就是“Content is like wat…

AD20|原理图导入Pcb时三极管引脚报错 Unkown Pin:Pin Q1-B

完成原理图绘制后,将其导入到Pcb中进行布局时,出现报错;Unknown Pin: Pin Q1-B. 原因是:引脚名称不一致 在原理图中,三个引脚分别定义B、C、E; 而在常见的TO—92A封装中,使用1、2、3作为三个引脚的名称&am…

实习工作之定时任务

需求:在当天晚上12点定时将过期数据的状态置为冻结状态 版本一代码实现[相当于是一个死代码,因为不能自动调度] public void updateStatus() throws CommonException, ParseException {String date_str "2023-07-01 00:00:00";Date expireT…

为什么我从 Manjaro Linux 跳到 EndeavourOS

我使用 Manjaro Linux 已经两年了,但随着时间的推移,我最初对 Manjaro 的喜爱逐渐减少,我对它的感觉越来越不舒服。这就是我转向 EndeavourOS 的原因。 我根本不是你所说的 Distrohopper 我早在 20 世纪 90 年代中期就开始使用 Linux,当时使用的是 RedHat Linux。2003 年…

网络请求库-axios的入门指南

网络请求库axios-入门指南 网络请求库-axios认识axios库axios发送请求axios基本使用axios基本演练配置baseURLaxios创建实例axios发送多个请求(了解) axios请求和响应拦截器axios请求封装(简洁) 网络请求库-axios 认识axios库 有…

使用 Maya Mari 设计 3D 波斯风格道具(p2)

今天瑞云渲染小编给大家带来了Simin Farrokh Ahmadi 分享的Persian Afternoon 项目过程,解释了 Maya 和 Mari 中的建模、纹理和照明过程。由于篇幅较长,分上下两篇来分别阐述。接着会继续讲述Persian Afternoon 项目过程的纹理和灯光渲染方面内容。 纹理…

Apikit 自学日记:安装、使用浏览器插件测试

Apikit 研发管理和自动化测试产品中,提供了多种发起 API 测试的方式: 服务器测试:通过 Apikit 官方远程服务器发送请求,不需要安装任何插件,但是无法访问本地服务器(localhost)、内网、局域网。 插件测试:…

linux创建软链接

目录 软链接的作用创建软链接删除软链接修改链接 软链接的作用 就如同电影里演的一样,为保护价值昂贵的钻石,做一个和真正的钻石一模一样的假钻石来掩人耳目,假钻石的信息和真的一模一样,看到假的钻石就如同看到真的一样。Linux中…

《基于AidLux的自动驾驶智能预警应用方案》

YOLOP模型转ONNX ONNX是开放式神经网络(Open Neural Network Exchange)的简称,ONNX的规范及代码主要由微软,亚马逊,Facebook和IBM等公司共同开发,以开放源代码的方式托管在Github上。目前官方支持加载ONNX模型的框架有&#xff1…

记录实现QT和qml model/view 交互时候遇到的坑

使用QT的model/view 建立全局静态变量 打印发现有值输出 但是界面无日志显示 原因是一开始使用调用函数传参传的logModel参数加了const参数修饰 这个错误太傻了,找了半天一直怀疑外部类的问题 其实setContextProperty是这么用的 传QObject类型的引用之后它内部会…

【无标题】下载redis工具RESP.app(RedisDesktopManager)

1、安装前提: Windows: 1、Install Microsoft Visual C 2015-2019 x64 (If you have not already). 2、Download Windows Installer from http://redisdesktop.com/download. (Requires subscription)指导手册地址: https://docs.resp.app/…

DataSecurity Plus金融行业案例

摘要:DataSecurity Plus是一款强大的数据安全解决方案,为金融机构提供全面的数据保护和合规性监控。本文将介绍DataSecurity Plus在金融行业的使用案例,包括文件审计、数据分类和合规性报告等功能的应用。 DataSecurity Plus 文件审计&#…

《The book of why》读书笔记 -- introduction:mind over data

最近在浅学causal learning,拜读《The Book of Why》,记录一些笔记,下为书的introduction部分 下面这段话我觉得写得非常好 This book tells the story of a science that has changed the way we distinguish facts from fiction and yet ha…

性能测试如何做?资深10年测试带你揭秘,测试之路进阶...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 在做功能测试、自…