问题沉淀「二」

关键字: 幂等CountDownLatch异常处理B+ 树

问题: 如何保证幂等机制
解决方案:
  幂等机制的核心是保证资源唯一性,例如客户端重复提交或服务端的多次重试只会产生一份结果。支付场景、退款场景,涉及金钱的交易不能出现多次扣款等问题。事实上,查询接口用于获取资源,因为它只是查询数据而不会影响到资源的变化,因此不管调用多少次接口,资源都不会改变,所以是它是幂等的。而新增接口是非幂等的,因为调用接口多次,它都将会产生资源的变化。因此,我们需要在出现重复提交时进行幂等处理。

那么,如何保证幂等机制呢?事实上,我们有很多实现方案。其中,一种方案就是常见的创建唯一索引。在数据库中针对我们需要约束的资源字段创建唯一索引,可以防止插入重复的数据。但是,遇到分库分表的情况是,唯一索引也就不那么好使了,此时,我们可以先查询一次数据库,然后判断是否约束的资源字段存在重复,没有的重复时再进行插入操作。注意的是,为了避免并发场景,我们可以通过锁机制,例如悲观锁与乐观锁保证数据的唯一性。这里,分布式锁是一种经常使用的方案,它通常情况下是一种悲观锁的实现。但是,很多人经常把悲观锁、乐观锁、分布式锁当作幂等机制的解决方案,这个是不正确的。除此之外,我们还可以引入状态机,通过状态机进行状态的约束以及状态跳转,确保同一个业务的流程化执行,从而实现数据幂等。

事实上,并不是所有的接口都要保证幂等,换句话说,是否需要幂等机制可以通过考量需不需要确保资源唯一性,例如行为日志可以不考虑幂等性。当然,还有一种设计方案是接口不考虑幂等机制,而是在业务实现的时候通过业务层面来保证,例如允许存在多份数据,但是在业务处理的时候获取最新的版本进行处理。


问题: redis key 过期后如何防止流量瞬间打在DB上?
探讨:
因为key过期后,不确定有多大的流量打在db上,所以,要提前reload
这种情况,没有特别好的方式。有文章说用分布式锁。其实是错误的,这样所有流量压力也会打到锁上,这种只是把压力转换了。
最好的方式只能对DB做限流,热点数据做本地缓存,这样能防止一个特别热的key,很大的流量都到DB。
什么是热点数据?而且基本上所有item都是长尾效应,用户能接触的只有10%的商品;剩下的90%商品都用不到缓存,
热与否,是会随时间的变化而变化的~,当然99%的公司,不需要考虑这个问题,所以很多时候在大流量面前
很多方案变的那么无力!!!


问题: CountDownLatch 实际运用在项目中什么样的场景?
解答:

  1. 做某个事情可能会有前置条件,比如 A depends on B,C,那 A 要等到 B,C 任务完成了才能开始。比如聚餐,可能需要等所有人到齐才能开始,比赛颁奖需要等所有运动员赛完了,才能开始颁奖。等等…
  2. futureTask 只是等待线程池里的线程执行完毕,但是线程间没有依赖关系,完全互相独立的。所以 fututreTask 和 countDownLatch 适用的场景不一样。

问题: 项目中的异常一般是不是不在 controller 层 catch 处理,而是丢给专门的 ControllerAdvice 处理?
解答:
ControllerAdvice 处理确实是一种好方案。我们自定义一个运行时异常,然后统一处理,并且封装给一个统一格式的异常 JSON 格式。


问题: 为什么 B+ 树适合做索引?
解答:
索引本身很大,因此索引往往以索引文件的形式存储的磁盘上。这样的话,索引查找过程中就要产生磁盘 I/O 消耗,相对于内存存取,I/O 存取的消耗要高几个数量级,所以评价一个数据结构作为索引的优劣最重要的指标就是在查找过程中磁盘 I/O 操作次数的渐进复杂度。换句话说,索引的结构组织要尽量减少查找过程中磁盘 I/O 的存取次数。而 B+ 树带有顺序访问的指针,并且利用了磁盘预读以及计算机局部性原理,相比 B 树和红黑树,B+ 树的磁盘IO数最少。具体原理看:MySQL索引背后的数据结构及算法原理

Reference:

  • 梁桂钊的知识星球 –「服务端思维」
-------------本文结束感谢您的阅读-------------
Thank you for your encouragement