day08 微服务阶段面试篇上
Java工程师高频面题:https://yjoffer.com/javaqa/readme.html
学习目标
- 能够说出ES索引同步的常用方案
- 能够说出Canal+MQ数据同步的方案
- 能够说出Canal是怎么伪装成 MySQL slave
- 能够测试通过Canal+MQ数据同步流程
- 能够说出Sentinel 底层滑动窗口算法原理
- 能够说出Sentinel 底层令牌桶算法和漏桶算法原理
- 能够说出商品查询缓存接口的执行流程
- 能够说出如何保证缓存一致性
- 能够说出分布式锁常用的方案
- 能够说出使用Redisson实现分布式锁的流程
- 能够说出缓存穿透、击穿、雪崩现象及解决方案
📺 视频链接:点击查看视频
1 ES索引同步方案
1.1. 技术方案分析
1.1.1 同步方式
管理员在商城的后台维护商品信息,数据存储在MySQL。
用户在商城搜索商品信息,从Elasticsearch搜索商品信息。

如果Elasticsearch的索引数据与MySQL的商品数据不一致会导致什么问题?
用户搜索到的商品信息并非商品最新的信息,比如:价格不同,搜索到的商品价格与实际价格不同,商品下架但是用户仍然可以搜索到商品信息,这些问题都会严重影响用户的体验。
我们需要一种方案,当管理员修改商品信息后及时的修改商品索引信息,使MySQL中的商品数据与ES中的商品数据保持一致。
常见的索引数据同步方案有两种:同步方式和异步方式。
首先说同步方式
在修改商品信息的方法中加入操作Elasticsearch索引的代码,即在原有业务方式的基础上添加索引同步的代码,CRUD操作MySQL的同时CRUD操作ES索引。
如下代码,是在添加商品信息的时候向ES索引添加文档。
public void insert(Item item){
//向Item表添加记录
//向Item索引添加文档
}此方式会在很多业务方法中加入操作ES索引的代码,增加代码的复杂度不方便维护,扩展性差。
其次,上边的代码存在分布式事务,操作Item表会访问数据库,向索引添加文档会访问ES,使用数据库本地事务是无法控制整个方法的一致性的,比如:向ES写成功了由于网络超时导致异常,最终写数据库操作回滚了而写ES操作没有回滚,数据库的数据和ES中的索引不一致。
1.1.2 异步方式
异步方式是通过引入MQ实现,修改商品信息时向MQ发送修改的商品信息,然后监听MQ的程序请求ES向索引写入,流程如下:

此方案的好处:
- 商品服务不用直接访问ES,通过MQ将商品服务和ES解耦合。
缺点:
- 在商品的CRUD方法中仍然需要加入向MQ发送消息的代码,如下:
public void insert(Item item){
//向Item表添加记录
//向MQ发送添加商品消息
}此方式仍然增加代码的复杂度不方便维护,扩展性差。
有没有一种方法不用对商品的CRUD方法进行侵入,商品的CRUD方法就是对商品的增删改查,不会存在向ES同步数据相关的代码。
此时我们要借助一个神器就是Canal [kə'næl],先看下Canal在整个流程中的位置,如下图:

从图中可以看出,商品管理的CRUD方式仅仅包括对商品表的CRUD业务操作(下图红色框内部分),不再有操作MQ的相关逻辑。

Canal是和MySQL存在联系,并且Canal负责和MQ交互,这种方案就是借助了Canal和MQ实现的。
请免费关注 预见猿份 公众号,发送:yjoffer.com,获取解锁密码
微信扫码关注关注公众号回复获取密码后,在下方输入并点击解锁,本机后续再读无需重复输入。
