面试专题(分布式系统微服务)

安稳与你 提交于 2021-01-31 23:48:01

架构设计相关

0. 什么是分布式系统,什么是微服务?

集群:多机器做同一件事情;
分布式系统: 一件事情,多系统协同完成;
微服务架构:构建分布式系统的一种架构方式, 核心思路是:去中心化;
http://www.cnblogs.com/liuning8023/p/4493156.html
 

1. RPC和RPC框架

RPC是指远程过程调用,实现远程过程调用的方式有很多中,Dubbo,Rmi,Hessian等等;
RPC的核心过程包括了客户端和服务端的通讯协议,寻址,数据序列化/反序列化;
对上述过程进行了封装,不需要开发人员自己去定义通讯协议,去实现序列化的细节工作,
这样的组件称为RPC框架;常见RPC框架有 thrift,gRpc,dubbo,motan


2. 序列化方式及作用

序列化:将java对象或者其他内存中的数据,转换为一种特定格式的流,使之可以在网络中传输或者磁盘上存储;
反序列化:将流以特定的格式转为java对象或者内存中其他形式的数据;# json,jdk serializable, Hessian,Dubbo, Protobuf,
作用:压缩;持久化存储;跨网络传输;


3. 分布式系统中事务的处理

参考:https://wenku.baidu.com/view/be946bec0975f46527d3e104.html
          https://segmentfault.com/a/1190000004468442
事务相关必了解的概念:
ACID (Atomic原子性,Consistency一致性,Isolation隔离性,Durability持久性)
CAP (一致性Consistency,可用性Availability,分区容错性Partitiontolerance),分布式系统来说,P是不能放弃的
BASE (Basically Available(基本可用),Soft state(软状态),Eventuallyconsistent(最终一致性))
分布式事务实现方式:
1.  XA (数据库厂商实现);2. 后台任务定期校对数据;3. 通过消息队列,实现最终一致(确保消息到达MQ,幂等性);4. TCC机制(Try,Confirm,Cancel)
https://www.cnblogs.com/rainwang/p/7099648.html

 

4. 系统监控

# 链路监控
Spring‐Cloud‐Sleuth + Zipkin
Sleuth收集微服务之间的接口调用信息以及内部方法调用。通过采样之后,将数据传输致
Zipkin,由Zipkin负责存储和可视化查询;
# 核心概念:Trace,Span。公开课有讲过Sleuth;
# 日志监控

ELK
1)ElasticSearch搜索服务器,提供了一个分布式多用户能力的全文搜索引擎,基于
RESTful web接口。
2)Logstash是可以对日志进行收集、过滤、分析,并将其存储供以后使用;
3)Kibana 是Elasticsearch前端展示工具,可以为 Logstash 和 ElasticSearch 提供
的日志分析友好的 Web 界面,可以帮助您汇总、分析和搜索重要数据日志
搭建方式参考资料: https://www.cnblogs.com/kevingrace/p/5919021.html
# 代码性能监控
Metrics:度量;我们需要为某个系统某个服务做监控、做统计,就需要用到Metrics;
代码执行的吞吐量,响应时间,并发量,瞬时状态值。
# 这个需要通过代码埋点实现,公开课有讲过Metrics+Grafana构建性能监控平台;


5. 高可用

服务的高可用可以通过多实例,自检测,自恢复,快速扩容机制来实现;
多实例:一个服务部署多个实例,通过负载均衡机制降低单实例的负载以及实现容错;
自检测:系统预留健康检查接口,通过docker集群模式的健康检查机制来实现自动重启和预警;
自恢复:对于网络抖动的问题,需要程序有一定的容错性,比如:熔断机制,Eureka的自我保护措施;
快速扩容:互联网应用的特殊性,在特定时候会出现高峰期的海量请求,此时,需要我们的分布式系统能够快速扩容。docker的服务编排就可以实现已有硬件资源的情况下秒级扩容;对于硬件资源,需要结合云计算技术来实现;


6. 服务调用的负载均衡

# 服务端负载均衡:对客户端屏蔽具体的接口地址,对外仅暴露负载均衡器,所有请求经过统一的负载服务;有硬件负载(f5,radware)和软件负载(nginx,apache,lvs)
优势:统一管理,控制;对外部调用友好,屏蔽了微服务地址多变的复杂性;
劣势:性能要求高,流量大对负载服务本身有很高的要求;管理复杂,大多数服务端负载器
需要手工配置服务实例信息;
# 客户端负载均衡:由客户端自己选择目标服务器,直调对应的地址;dubbo(源码参考com.alibaba.dubbo.rpc.cluster.LoadBalance),springcloud(ribbon)都是客户端负载均衡;
优势:性能好,可以根据具体应用微调负载策略;易管理,服务实例信息自发现
劣势:服务实例信息在多客户端之间的不同步;通常是集群内部使用;


7. 分布式配置中心

类似产品有很多:360 Qconf,百度 Disconf,淘宝 Diamond
参考:https://www.cnblogs.com/zhangxh20/p/5464103.html
我们着重讲了springcloudconfig 分布式配置中心,用来解决多配置的问题;
将配置文件统一存储在gitlab,svn,filesystem,并支持敏感信息的加密存储(configserver或者client均可解密)


8. 服务注册与发现机制

这种机制目的是实现:服务提供者的自注册,服务消费者的主动发现服务提供者;
服务注册:服务提供者启动实例时,将信息存储到注册中心;
注册中心:保存服务提供者或者消费者的实例信息(服务名称,IP,端口,方法地址等等)
服务发现:服务消费者,通过服务名在注册中心的信息中查询出具体的服务提供者实例信息。


9. 分布式系统如何拆分?

业务线(订单系统,积分系统,审计系统,支付系统,结算系统,推广系统….)
技术栈(php,java,nodejs,go)

架构分层 (前台,中台,后台; 存储服务,缓存服务,MQ服务,搜索引擎服务….)

 

SpringCloud

1. 微服务是如何保护自己的

http://blueskykong.com/2017/10/19/security1/

信息加密

通过Https实现信息传输的加密(nginx,tomcat都可以配置https);
对代码侵入性很小。因为微服务集群不直接对外提供服务,由统一的网关来提供业务API(zuul,nginx都可以的)。

权限校验方案

· 单点登录

# 每个应用都必须接入单点登录,大型系统中,需要集成单点登录带来的复杂工作和性能损耗;

· 分布式session方案

流程: 客户端 ‐> 获取session ‐> 请求微服务 ‐> 查询共享存储中授权信息 ‐> 校验权限 ‐> 提供服务 ‐> 给予响应
分布式session保存方案,根据session去查找共享存储中对应的权限信息来实现权限校验;
# 共享存储的高可用和安全性是个问题,类似直接redis,memcache来做;

· token方案

1. 客户端 ‐> uaa认证 ‐> 获取token
2. 客户端 ‐> 微服务 ‐> 校验token

token包含必要的授权信息,一次获取,多次使用,相对独立,实现简单,不需要cookie;长度有限,不能撤销,需要设置过期时间;
# 可以在网关层做;也可以构建成通用的组件,放在每个微服务上面去做;
# 根据不同的业务场景:token可以发放一次,也可以在每次请求的时候去申请,这样能够实现分控需要的账户禁用,黑名单等功能

 

2. 微服务网关

zuul是springcloud提供的成熟的路由方案;根据请求的路径不同,网关会定位到指定的微服务,并代理请求到不同的微服务接口;对外屏蔽了微服务接口调用的复杂性。
三个重要概念:动态路由表,路由定位,反向代理
反向代理:客户端请求到网关,网关受理后,再对目标服务发起请求,拿到响应之后,再响应给客户端;
动态路由表:zuul支持eureka路由,手动配置的路由,这两种都支持动态更新;
路由定位:根据请求路径,zuul有一套自身的服务定位规则以及路由匹配的表达式;
# 应用场景: 对外暴露,权限校验,服务聚合,日志审计

 

3. 各服务之间如何调用

服务对外以http接口形式暴露,所以调用有多种方式;
Fegin是cloud提供的一种服务调用客户端;
Resttemplate也可以快速的发起服务调用;
同时,也可以手动获取对应接口的具体地址,通过平常的httpclient进行调用;
# Feign和Resttemplate 都可以集成负载均衡,失败重试,熔断的功能;

 

4.如何保证服务健康的情况
1. Spring Boot‐Actuator 可以用来监控我们的项目,可以通过HealthEndPoint/health来查看应用的健康状况;
SpringBoot在集成很多组件时,都会实现一个健康检查的接口,如ElasticsearchHealthIndicator,RedisHealthIndicator,RabbitHealthIndicator等。
2. 在微服务集群中,我们通常还会通过sleuth来进行服务调用的链路追踪,可以通过抽样看到服务调用的异常情况;
3. 日志信息也是我们监控服务监控情况的一个重要手段,常用通过ELK实现日志收集,分析和查看;
4. 在通过docker部署微服务时,我们可以利用docker的健康检查机制,实现服务的自动重启;

 

5. 容错机制

# Ribbon 负载均衡&重试
通过服务名获取实例信息,根据负载策略选择合适的实例去访问;
服务调用失败时,可以配置重试次数,以及实例切换的次数;
# Hystrix熔断机制
限流,降级,熔断;
限流:限制接口访问并发量,限制缓冲区大小,超出限制,调用Fallback方法
熔断:出错率超过阈值,一定时间内不再请求该接口。(超时、run方法抛出异常)
降级:凡是没有正常的从接口中拿到数据,就会调用Fallback方法,获取一个结果
# 通过命令模式的封装,SpringCloud内部自动集成,且可作用于任意JAVA方法上,不关心方法的具体实现。代表着(http、redis、db操作都可以做熔断);

 

6. SpringCloud中的服务注册与发现机制

两个角色eurekaServer, eurekaClient
server提供httpapi服务,存储服务实例的信息,并且具备主动剔除服务(心跳检测)和server高可用的功能;
client集成在具体的微服务中,在服务启动时,将服务实例信息post到server上;client也会定时同步server上面其他service信息;
# eureka的工作大多是后台thread在定时工作,任务执行的间隔时间都可以通过配置文件进行配置;

 

7. SpringCloud的实施推广

# 集成SpringMVC项目
微服务改造的过渡期,在传统的SpringMvc项目中,引入部分SpringCloud的特性,即可通过微改造变成微服务;
# 其他语言的项目加入SpringCloud微服务系统
Eureka提供HttpApi,使得非java语言加入到SpringCloud微服务集群成为可能;

 

Dubbo

http://dubbo.io/books/dubbo­user­book/ 
http://dubbo.io/books/dubbo­dev­book 
http://dubbo.io/books/dubbo­admin­book/

1. 如果注册中心集群都挂掉,发布者和订阅者之间还能通信么?

# 有缓存;
注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯
新的服务将无法发现;服务下架后仍旧有被调用的可能;

2. dubbo连接注册中心和直连的区别

注册中心: 消费者动态发现服务提供者,实现软负载均衡和集群容错;
直连:不能动态增减提供者;开发、测试环境可通过指定Url方式绕过注册中心直连指定的服务地址,快速测试

3. dubbo服务的容错机制

# http://dubbo.io/books/dubbo‐user‐book/demos/fault‐tolerent‐strategy.html
Failover Cluster:失败自动切换,当出现失败,重试其它服务器,默认两次;
Failfast Cluster:失败立即报错
Failsafe Cluster:失败安全,出现异常时,直接忽略
Failback Cluster:失败自动恢复,后台记录失败请求,定时重发
Forking Cluster:并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较
高的读操作,但需要浪费更多服务资源
Broadcast Cluster:播调用所有提供者,逐个调用,任意一台报错则报错
# 要注意分布式事务

4. 具体问题示例1:关于服务调用超时
# 超时是针对消费端还是服务端?
dubbo的超时是争对客户端的,由于是一种NIO模式,消费端发起请求后得到一个ResponseFuture,然后消费端一直轮询这个ResponseFuture直至超时或者收到服务端的返回结果
# 超时在哪设置,优先级是什么?
http://dubbo.io/books/dubbo‐user‐book/configuration/xml.html
# 实现原理
消费端发起远程请求后,线程不会阻塞等待服务端的返回,而是马上得到一个ResponseFuture(ReponseFuture的实现类:DefaultFuture),消费端通过不断的轮询机制判断结果是否有返回。因为是通过轮询,轮询有个需要特别注要的就是避免死循环,所以为了解决这个问题就引入了超时机制,只在一定时间范围内做轮询,如果超时时间就返回超时异常

5. 服务提供者能实现失效踢出是什么原理

源码参考  RegistryService, 文档参考http://dubbo.io/books/dubbo‐user‐book/references/registry/introduction.html
# redis ‐ 脏数据由监控中心删除
# zookeeper ‐ 的临时节点

6. dubbo通讯协议

# 什么是通讯协议
客户端服务端之间进行数据流转的一种约定,将数据按照标准格式来组装;
# 协议内容
头部信息(调用控制协议16B) + body(序列化)
head = 魔数(2) + 标识(1) + 响应状态(1) + 消息ID(8) + 内容长度(4)
body = dubbo版本 + 服务接口路径 + 服务版本号 + 服务方法名 + 参数描述符 + 参数值序列化 + 隐式参数

7. 大概率的问题

# dubbo文档,仔细阅读一遍,面试官可能随便抽取一个。
# dubbo配置的方式和属性

http://dubbo.io/books/dubbo‐user‐book/configuration/
# dubbo底层协议
http://dubbo.io/books/dubbo‐user‐book/references/protocol/introduction.html
# dubbo服务注册与发现流程
http://dubbo.io/books/dubbo‐user‐book/references/registry/introduction.html

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!