【八股消消乐】构建微服务架构体系—实现制作库与线上库分离
😊你好,我是小航,一个正在变秃、变强的文艺倾年。
🔔本专栏《八股消消乐》旨在记录个人所背的八股文,包括Java/Go开发、Vue开发、系统架构、大模型开发、具身智能、机器学习、深度学习、力扣算法
等相关知识点,期待与你一同探索、学习、进步,一起卷起来叭!
目录
- 题目
- 答案
- 隔离
- 机房隔离
- 实例隔离
- 分组隔离
- 连接池隔离和线程池隔离
- 第三方依赖隔离
- 简历优化
- 慢任务隔离
- 制作库与线上库分离
题目
💬技术栈:微服务架构
🔍简历内容:熟悉主流隔离策略,为保证C端用户服务体验,实现制作库与线上库隔离。
🚩面试问:如果采用分组隔离策略,热点的放一组,非热点的放一组,你觉得可不可行?为什么?
💡建议暂停思考10s,你有答案了嘛?如果你有不同题解,欢迎评论区留言、打卡。
答案
热点数据不能集中放,因为热点数据一般的请求量很大,需要将热点数据均衡分配各个节点,降低热点数据造成的压力
。
隔离
隔离:通过资源划分,在不同服务之间建立边界,防止相互影响的一种治理措施。
目的:
- 提升可用性,也就是说防止被影响或防止影响别人。这部分也叫做
故障隔离
。 - 提升性能, 这是隔离和熔断、降级、限流不同的地方,一些隔离方案能够
提高系统性能,而且有时候甚至能做到数量级提升
。 - 提升安全性, 也就是为安全性比较高的系统提供单独的集群、使用更加严苛的权限控制、迎合当地的数据合规要求等。
缺点:
- 带来资源浪费,需要更多钱, 维护它也需要钱。
- 隔离还容易引起资源不均衡的问题。比如说在连接池隔离里面,可能两个连接池其中一个已经满负荷了,另外一个还是非常轻松。
机房隔离
机房隔离:把核心业务单独放进一个机房隔离,不会和其他不重要的服务混在一起。
在这种形态下,其中一个机房崩溃了自然不会对另外一个机房有任何影响。
机房隔离:不同服务分散在不同的机房;
多活:同一个服务在不同的城市、不同的机房里面有副本。
实例隔离
实例隔离:某个服务独享某个实例的全部资源。
分组隔离
分组隔离:一起部署的服务上有多个接口或者方法
,那么就可以利用分组机制来达成隔离的效果。
- B 端一个组,C 端一个组。
- 普通用户一个组,VIP 用户一个组。
读接口一个组,写接口一个组
。这种也叫做读写隔离。比如说在生产内容的业务里面,没有实行制作库和线上库分离的话,那么就可以简单地把读取内容划分成一个组,编辑内容划分成另外一个组。快接口一个组,慢接口一个组
。这个和前面的读写隔离可能会重叠,因为一般来说读接口就是比较快。
连接池隔离和线程池隔离
两种都可以看作池子隔离,一个池子里面放的是连接,另一个池子里面放的是线程
。
线程池隔离在 Java 里面被广泛使用。 Go 语言中,虽然存在所谓的
GMP 调度
,里面有线程的概念,但是开发者是操作不了线程的
。而协程过于廉价了,似乎不太值得做池化。
第三方依赖隔离
第三方依赖隔离:为核心服务或者热点专门提供数据库集群、消息队列集群等第三方依赖集群
。
简历优化
确定隔离机制:
- 数据库方面:你们公司
有几个物理上的数据库(包括主从集群)
,有没有业务是独享某一个物理数据库
的。 - 你们公司
有没有准备多个 Redis 实例或者多个集群
。另外理论上来说开启了持久化功能或者被用作消息队列的 Redis 最好是一个独立的集群,防止影响正常将 Redis 用作缓存的业务。 - 其他类似的中间件,包括消息队列、Elasticsearch等,
是否针对不同业务启用了不同的集群
。 对核心业务、热点业务在资源配置上有没有什么特别之处
。- 在业务上,
有没有针对高价值用户做什么资源倾斜
。 - 在具体的系统上,有没有使用
连接池隔离、线程池隔离
等机制。 因为缺乏隔离机制引起的事故
报告。【大对象】- 因为组织关系引起的隔离。比如说公司
A 部门和 B 部门各自有独立的 Redis 集群
,但这并不是出于隔离的目的有意设计的,而是纯粹因为两个部门的利益冲突才各自维护了一个 Redis 集群
。
回答模板:
(1)BC 端隔离:
示例场景:为了保障我们 C 端用户的服务体验
,我在我们的服务上利用微服务框架的分组功能做了一个简单的隔离。
解决方案:我们的服务本身部署了八个实例
,我将其中三台实例分组为 B 端
。于是商家过来的请求就只会落在这三台机器上,而 C 端用户的请求就可以落到八台中的任意一台
。
核心目的:限制住 B 端使用的资源,但是 C 端就没有做任何限制
。
(2)大对象:
示例场景:服务原本运行得很好,结果突然之间 Redis 就卡住
了,导致Redis 请求大部分超时,请求都落到了数据库上,数据库负载猛增,导致数据库查询也超时。
原因分析:运维排查,确认了 Redis 在那段时间因为别的业务上线了一个新功能,这个功能会批量计算数据,产生的结果会存储在 Redis
。但是这个结果非常庞大
,所以在这个功能运行的时候,Redis 就相当于在频繁操作大对象
。
解决方案:使用 Redis 的时候,分成了核心与非核心
。核心 Redis 有更加严格的接入机制和代码 review 机制
,而非核心的就比较随意
。不仅如此,我们还为高并发的服务设计了数据库限流
,防止再来一次 Redis 失效导致 MySQL 被打崩的事故
。
慢任务隔离
有两种很常见的场景,我们会考虑开启一个线程池来处理。
- 异步任务:比如说收到请求之后直接返回一个已接收的响应,而后往线程池里面提交一个任务,异步处理这个请求。
- 定时任务:比如说
每天计算一下热榜
等。
存在的隐患:慢任务可能把所有的线程都占掉。
场景:我们的定时任务总不能及时得到调度
。后来我们加上监控之后,发现是因为存在少数执行很慢的任务,将线程池中的线程都占满了
。
解决方案:引入了线程池隔离机制
,核心就是让慢任务在一个专门的线程池里面执行
。
准备两个线程池:一个线程池专门执行慢任务,一个是执行快任务。
识别慢任务:当任务开始执行的时候,先在快任务线程池里执行一些简单的逻辑,确定任务规模
。根据要处理的数据量的大小
,分出慢任务。如果是快任务,就继续执行。否则,转交给慢任务线程池。
根据要处理的数据量的大小
:例如找到数据库里面符合条件的数据,然后逐条处理。那么可以先统计一下数据库有多少行是符合条件的。如果数据量很多,就转交给慢任务处理
。
也可以根据运行时间是否超过阈值。在
识别循环处理数据里面比较好用
。只需要在每次进入循环之前检测一下执行时长就可以了。
制作库与线上库分离
制作库:创作者正在创作的时候,他们的文章、视频等内容是存放在制作库的。
线上库:等到他们完成创作之后,点击发布的时候,就会保存到线上库。
场景:在我们的业务里面,采用了制作库和线上库分离的方案来保证业务的可用性和性能
。
- 作者
在 B 端写作,操作的都是制作库
,这个过程 C 端读者是没有任何感知的。 当作者点击发布之后,就会开始同步给审核,审核通过之后就会同步给线上库
。- 在
同步给线上库的时候,我们还会直接同步到缓存
,这样作者的关注者阅读文章的时候就会直接命中缓存
。 - 后面如果作者要修改文章,修改的也是 B 端制作库,等他修改完毕,就会再次提交审核。
审核完成之前,C 端用户看到的都是历史版本
,这样 B 端和 C 端隔离保证了两边的用户体验。- 同时拆成两个数据库之后,
C 端线上库几乎都是读流量,性能很好
。
往期精彩专栏内容,欢迎订阅:
🔗【八股消消乐】20250612:[构建微服务架构体系—限流算法优化]https://blog.csdn.net/m0_51517236/article/details/148607490)
🔗【八股消消乐】20250611:构建微服务架构体系—降级策略全总结
🔗【八股消消乐】20250610:构建微服务架构体系—熔断恢复抖动优化
🔗【八股消消乐】20250609:构建微服务架构体系—负载均衡算法如何优化
🔗【八股消消乐】20250608:构建微服务架构体系—服务注册与发现
🔗【八股消消乐】20250607:MySQL存储引擎InnoDB知识点汇总
🔗【八股消消乐】20250606:MySQL参数优化大汇总
🔗【八股消消乐】20250605:端午节产生的消费数据,如何分表分库?
🔗【八股消消乐】20250604:如何解决SQL线上死锁事故
🔗【八股消消乐】20250603:索引失效与优化方法总结
🔗【八股消消乐】20250512:慢SQL优化手段总结
🔗【八股消消乐】20250511:项目中如何排查内存持续上升问题
🔗【八股消消乐】20250510:项目中如何优化JVM内存分配?
🔗【八股消消乐】20250509:你在项目中如何优化垃圾回收机制?
🔗【八股消消乐】20250508:Java编译优化技术在项目中的应用
🔗【八股消消乐】20250507:你了解JVM内存模型吗?
🔗【八股消消乐】20250506:你是如何设置线程池大小?
🔗【八股消消乐】20250430:十分钟带背Duubo中大厂经典面试题
🔗【八股消消乐】20250429:你是如何在项目场景中选取最优并发容器?
🔗【八股消消乐】20250428:你是项目中如何优化多线程上下文切换?
🔗【八股消消乐】20250427:发送请求有遇到服务不可用吗?如何解决?
📌 [ 笔者 ] 文艺倾年
📃 [ 更新 ] 2025.6.12
❌ [ 勘误 ] /* 暂无 */
📜 [ 声明 ] 由于作者水平有限,本文有错误和不准确之处在所难免,本人也很想知道这些错误,恳望读者批评指正!