1、如何设计一个注册中心
- 高可用:集群
- 高并发:响应时间、吞吐量、并发用户数等等
- 增加服务器性能
- 扩展服务实例
- 高性能:程序处理速度
- 数据存储结构:设计简单一下,加锁方便
- 通信机制
- 集群同步
- 注册中心
- 服务注册
- 注册表的变动
- 服务发现
- 服务订阅
- 服务推送
- 服务检查
- 数据同步
2、Nacos1.x作为注册中心的原理
- 使用http发送注册
- 查询服务提供方列表
- 定时拉取(每10秒)
- 检测到服务提供者异常,基于UDP协议推送更新
- 定时心跳(5秒),检测服务状态
- 定时心跳任务检查
- 集群数据同步任务使用Distro
3、Nacos服务领域模型有哪些?
- Namespace:实现环境隔离,默认值public
- Group:不容的service可以组成一个Group,默认值Default-Group
- Service:服务名称
- Cluster:对执行的微服务虚拟划分,默认值Default
- Instance:某个服务的具体实例
4、Nacos中的Distro协议
- Nacos每个节点自己负责部分的写请求
- 每个节点会把自己负责的新增数据同步给其它节点
- 每个节点定时发送自己负责数据的校验值到其它节点来保持数据一致性
- 每个节点独立处理读请求,及时从本地发出响应
- 新加入的Distro节点会进行全量数据拉取
- 具体操作是轮询所有的Distro节点,通过向其它的机器发送请求拉取全量数据
5、配置中心的技术选型
- SpringCloudConfig:
- 不支持配置实时生效
- 不支持client本地缓存
- Nacos:springcloud用这个
- 不支持灰度发布
- Apollo:都支持
- 怎么选?
- 社区活跃度
- 自己的技术栈
- 产品功能
6、Nacos1.x配置中心长轮询机制
- 客户端会轮询向服务端发送一个长连接请求,这个长连接欸最多30s就会超时,服务端收到客户端的请求会先判断当前是否有配置更新,有则立即返回,如果没有,服务端会将这个请求拿住”hold“29.5s加入队列,最后0.5s加入队列,最后0.5s再检测配置文件无论有没有更新都正常返回,但等待的29.5s期间有配置更新可以提前结束并返回
7、Nacos2.x客户端探活机制
- Nacos服务端会启动一个定时任务,每3秒执行一次,查看所有连接是否超过20s没有通信,如果超过20秒没有通信,服务端就会给客户端发送一个请求,进行探活,如果能正常返回就表示这个服务为正常服务,如果不能正常返回就将其连接删除。
8、Ribbon底层怎样实现不同服务的不同配置
- 为不同的服务创建不同的Spring上下文
9、为什么Feign第一次调用耗时很长?
- ribbon默认是懒加载的,只有第一次调用的时候才会生成ribbon对应的组件,这就会导致首次调用的会很慢的问题
10、Ribbon的属性配置和类配置哪个优先级高?
- 类的优先级高
- 因为ribbon的默认配置文件被Condition注解,有类用类,没类用默认
11、Feign的性能优化
- Feign底层默认是JDK自导的HttpURLConnection,它是单线程发送HTTP请求的,不能配置线程池,我们使用Okhttp或者HttpClient来发送http请求,并且它们两个都支持线程池
12、在Feign中怎样实现认证的传递
- 实现接口RequestInterceptor,通过header实现认证传递
13、谈谈Sentinel中使用的限流算法
- 计数器固定窗口算法
- 计算器固定窗口算法是最简单的限流算法,实现方式也比较简单。就是通过维护一个单位时间内的计数值,每当一个请求通过时,就将计数值+1,当计数值超过预先设定的阈值时,就拒绝单位时间内的其它请求。如果单位时间已经结束,则将计数器清零,开启下一轮的计数
- 问题:如果在0.99s来了99个,然后1.1s又来100个,这样也不会超过阈值
- 计数器滑动窗口算法
- 计数器滑动窗口算法就是为了解决上述固定窗口数存在的问题而诞生。前面说了固定窗口存在临界值问题,要解决这种临界值问题,显然只用一个窗口是解决不了问题的。假设我们仍然设定1s内允许通过的请求是200个,但是在这里我们需要把1s的时间分成多格,假设分成5格,每格窗口的时间大小是200ms,没过200ms,就将窗口向前移动一格。
- 漏桶算法
- 漏桶算法以一个常量限制了出口流量速率,因此漏桶算法可以平滑突发的流量。其中漏桶作为流量容器我们可以看作一个FIFO的队列,当入口流量速率大于出口流量速率时,因为流量容器是有限的,当超出流量容器大小时,超出的流量会被丢弃
- 特点
- 具有固定容量,出口流量速率是固定常量(流出请求)
- 入口流量可以以任意速率流入到漏桶中(流入请求)
- 如果入口流量超出了桶的容量,则流入流量会溢出(新请求被拒绝)
- 因为漏桶算法限制了流出速率是一个固定常量值,所以漏桶算法不支持出现突发流出流量。但是在实际情况下,流量往往是突发的
- 令牌桶算法
- 令牌桶算法是漏桶算法的改进版,可以支持突发流量。不过与漏桶算法不同的是,令牌桶算法的漏桶中存放的是令牌而不是流量
- 以恒定速率往桶中加令牌,如果装满,多余令牌丢弃。当请求到来时,先尝试从令牌桶获取令牌,获取成功则请求放行,失败则阻塞后拒接请求
14、谈谈Sentinel服务熔断过程
- 服务熔断一般有三种状态
- 熔断关闭状态:服务没有故障时,熔断器所处的状态,对调用方的调用不做任何限制
- 熔断开启状态:后续对该服务接口的调用不再经过网络,直接执行本地的fallback方法
- 半熔断状态:尝试恢复服务调用,允许有限的流量调用该服务,并监控调用成功率。如果成功率达到预期,则说明服务已恢复,进入熔断关闭状态;如果成功率仍旧很低,则重新进入熔断开启状态
15、在Gateway中怎样实现服务平滑迁移
- 使用weight路由的断言工厂进行服务权重的配置,并将配置放到Nacos配置中心进行动态迁移
16、Seata支持哪些事务模式
- Seata是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata将为用户提供AT、TCC、SAGA和XA事务模式,为用户打造一站式的分布式解决方案
- AT模式:提供无侵入自动补偿的事务模式(这里是基于本地能支持事务的关系型数据库,然后java代码可以通过JDBC访问数据库,这里的无侵入:我们只需要加上对应的注解就可以开启全局事务)
- XA模式:支持已是心啊XA接口的数据库的XA模式(这里一般是需要数据库实现对应的XA模式的接口,一般像mysql、oracle都是心啊了XA
- TCC模式:TCC则可以理解为在应用层面的2PC,是需要我们编写业务逻辑来实现
- SAGA模式:为长事务提供有效的解决方案
17、请简述2PC流程以及优缺点
- 优点:尽量保证了数据的强一致,实现成本较低,在各大主流数据库都有自己的实现,对于mysql是从5.5开始支持(XA)
- 缺点:
- 单点问题:事务管理器在整个流程中扮演的角色很关键,如果其宕机,比如在第一阶段已经完成,在第二阶段正准备提交的时候,事务管理器宕机了,资源管理器就会一致阻塞,导致数据库无法使用
- 同步阻塞:在准备就绪之后,资源管理器中的资源一直处于阻塞,知道提交完成,释放资源
- 数据不一致:两阶段提交协议虽然为分布式数据一致性所设计,但仍然存在数据不一致的问题,比如在第二阶段中,假设协调者发出了事务commit的通知,但是因为网络问题该通知仅被一部分参与者所收到并执行了commit操作,其余的参与者则因为没有收到通知一直处于阻塞状态,这时候就产生了数据的不一致
18、Seata中xid怎样通过Feign进行全局传递
- 全局事务id通过Feign的header进行传递
19、分布式事务应用的典型场景
- 多服务:多个服务处理一个业务,改业务需要事务处理
- 多数据源
- 跨库
- 分库分表
20、简述Seata的AT模式两阶段过程
- 一阶段:开启全局事务、注册分支事务、存储全局锁、业务数据和回滚日志进行提交
- 二阶段:事务协调者根据所有分支的情况,决定本次全局事务是commit还是rollback(二阶段是完全异步删除undolog日志,全局事务、分支事务、存储的全局锁)