在高并发的场景下,异步是一个极其重要的优化方向。
前段时间,生产环境发生一次事故,笔者认为事故的场景非常具备典型性 。
写这篇文章,笔者想和大家深入探讨该场景的架构优化方案。希望大家读完之后,可以对异步有更深刻的理解。
1 业务场景
老师登录教研平台,会看到课程列表,点击课程后,课程会以视频的形式展现出来。
访问课程详情页面,包含两个核心动作:
读取课程视频信息 :
从缓存服务器 Redis 获取课程的视频信息 ,返回给前端,前端通过视频组件渲染。
写入课程观看行为记录 :
当教师观看视频的过程中,浏览器每隔3秒发起请求,教研服务将观看行为记录插入到数据库表中。而且随着用户在线人数越多,写操作的频率也会指数级增长。
上线初期,这种设计运行还算良好,但随着在线用户的增多,系统响应越来越慢,大量线程阻塞在写入视频观看进度表上的 Dao 方法。上。
首先我们会想到一个非常直观的方案,提升写入数据库的能力。
- 优化 SQL 语句;
- 提升 MySQL 数据库硬件配置 ;
- 分库分表。
这种方案其实也可以满足我们的需求,但是通过扩容硬件并不便宜,另外写操作可以允许适当延迟和丢失少量数据,那这种方案更显得性价比不足。
那么架构优化的方向应该是:“减少写动作的耗时,提升写动作的并发度”, 只有这样才能让系统更顺畅的运行。
于是,我们想到了第二种方案:写请求异步化。
- 线程池模式
- 本地内存 + 定时任务
- MQ 模式
- Agent 服务 + MQ 模式