常见面试题之微服务
1.1.SpringCloud
常见组件有哪些?
问题说明:这个题目主要考察对SpringCloud
的组件基本了解
难易程度:简单
参考话术:
SpringCloud
包含的组件很多,有很多功能是重复的。其中最常用组件包括:
•注册中心组件:Eureka
、Nacos
等
•负载均衡组件:Ribbon
•远程调用组件:OpenFeign
•网关组件:Zuul
、Gateway
•服务保护组件:Hystrix
、Sentinel
•服务配置管理组件:SpringCloudConfig
、Nacos
1.2.Nacos
的服务注册表结构是怎样的?
问题说明:考察对Nacos
数据分级结构的了解,以及Nacos
源码的掌握情况
难易程度:一般
参考话术:
Nacos
采用了数据的分级存储模型,最外层是Namespace
,用来隔离环境。然后是Group
,用来对服务分组。接下来就是服务(Service
)了,一个服务包含多个实例,但是可能处于不同机房,因此Service
下有多个集群(Cluster
),Cluster
下是不同的实例(Instance
)。
对应到Java
代码中,Nacos
采用了一个多层的Map
来表示。结构为Map<String, Map<String, Service>>
,其中最外层Map
的key
就是namespaceId
,值是一个Map
。内层Map
的key
是group
拼接serviceName
,值是Service
对象。Service
对象内部又是一个Map
,key
是集群名称,值是Cluster
对象。而Cluster
对象内部维护了Instance
的集合。
如图:
1.3.Nacos
如何支撑阿里内部数十万服务注册压力?
问题说明:考察对Nacos
源码的掌握情况
难易程度:难
参考话术:
Nacos
内部接收到注册的请求时,不会立即写数据,而是将服务注册的任务放入一个阻塞队列就立即响应给客户端。然后利用线程池读取阻塞队列中的任务,异步来完成实例更新,从而提高并发写能力。
1.4.Nacos
如何避免并发读写冲突问题?
问题说明:考察对Nacos
源码的掌握情况
难易程度:难
参考话术:
Nacos
在更新实例列表时,会采用CopyOnWrite
技术,首先将旧的实例列表拷贝一份,然后更新拷贝的实例列表,再用更新后的实例列表来覆盖旧的实例列表。
这样在更新的过程中,就不会对读实例列表的请求产生影响,也不会出现脏读问题了。
1.5.Nacos
与Eureka
的区别有哪些?
问题说明:考察对Nacos
、Eureka
的底层实现的掌握情况
难易程度:难
参考话术:
Nacos
与Eureka
有相同点,也有不同之处,可以从以下几点来描述:
- 接口方式:
Nacos
与Eureka
都对外暴露了Rest
风格的API
接口,用来实现服务注册、发现等功能 - 实例类型:
Nacos
的实例有永久和临时实例之分;而Eureka
只支持临时实例 - 健康检测:
Nacos
对临时实例采用心跳模式检测,对永久实例采用主动请求来检测;Eureka
只支持心跳模式 - 服务发现:
Nacos
支持定时拉取和订阅推送两种模式;Eureka
只支持定时拉取模式
1.6.Sentinel
的限流与Gateway
的限流有什么差别?
问题说明:考察对限流算法的掌握情况
难易程度:难
参考话术:
限流算法常见的有三种实现:滑动时间窗口、令牌桶算法、漏桶算法。Gateway
则采用了基于Redis
实现的令牌桶算法。
而Sentinel
内部却比较复杂:
- 默认限流模式是基于滑动时间窗口算法
- 排队等待的限流模式则基于漏桶算法
- 而热点参数限流则是基于令牌桶算法
1.7.Sentinel
的线程隔离与Hystix
的线程隔离有什么差别?
问题说明:考察对线程隔离方案的掌握情况
难易程度:一般
参考话术:
Hystix
默认是基于线程池实现的线程隔离,每一个被隔离的业务都要创建一个独立的线程池,线程过多会带来额外的CPU
开销,性能一般,但是隔离性更强。
Sentinel
是基于信号量(计数器)实现的线程隔离,不用创建线程池,性能较好,但是隔离性一般。
认是基于线程池实现的线程隔离,每一个被隔离的业务都要创建一个独立的线程池,线程过多会带来额外的CPU
开销,性能一般,但是隔离性更强。
Sentinel
是基于信号量(计数器)实现的线程隔离,不用创建线程池,性能较好,但是隔离性一般。