【⾯试题】-java分布式及微服务⾯试题汇总
⽬录
1.CAP理论
任何分布式系统都⽆法同时满⾜⼀致性(consistency),可⽤性(availibity),分区容错性(partition tolerance)这三项,最多只可同时满⾜其中的两项.
看过⼀道京东的⾯试题:
请说⼀说⽤zookeeper做注册中⼼和Eureka做注册中⼼的不同之处.
可以从CAP的⾓度进⾏分析,zk做注册中⼼是满⾜CP的,spring cloud是满⾜AP的,具体的可以展开阐述.
2.BASE理论
BASE是 Basically Available (基本可⽤) Soft state(软状态) Eventually consistent(最终⼀致性)这⼏个单词的缩写,
是从CAP理论发展⽽来的,其核⼼思想是:即使⽆法做到强⼀致性,但每个应⽤都可以根据⾃⾝特点,采取适当的⽅式来使系统达到最终⼀致性.
3.接⼝的幂等性问题
幂等的意思是重复操作,接⼝的幂等性也就是接⼝被重复调⽤了,在前端不进⾏限制的情况下,同⼀个接⼝可能重复调⽤多次,为了避免类似重复下单的问题,可以通过以下⼏种⽅式来解决幂等性问题:
全局唯⼀ID,根据业务操作和内容⽣成全局唯⼀的ID,然后在执⾏操作前先判断是否已经存在该ID,如果不存在则将该ID进⾏持久化(存在数据库或者redis中),如果已经存在则证明该接⼝已经被调⽤过了.⽐如下单时可以⽣产⼀个流⽔号来作为该订单的唯⼀标识.
可以使⽤select+insert来进⾏判断,因为⼀般订单的ID都是唯⼀索引,在⾼并发场景下不推荐.
可以使⽤乐观锁解决,在表中可以添加⼀个version字段.
token机制,将token放在redis中.
4.消息中间件如何解决消息丢失问题
可以在消息发送者这⾥发送⼀个id,接收端收到消息后将该ID存储于DB中,然后可以通过判断DB是否存在该ID来确定消息是否成功发送.
当然现在的消息中间件都⽐较强⼤,已经考虑并完善了这块内容,所以你可以直接借助消息中间件提供的⽅法来解决.
⽐如rabbitMQ,提供了事务机制,你可以在消息发送前提交事务,如果发送失败会⾃动回滚.
// 开启事务
try {
// 这⾥发送消息
} catch (Exception e) {
// 这⾥再次重发这条消息
}
// 提交事务
但这样会⽐较耗性能,所以更推荐的做法是使⽤rabbitmq提供的confirm机制.confirm机制是异步的,在消费者收到⽣产者发送的消息后会回调ack,如果消费者接收失败会回调nack接⼝.
要想真正做到万⽆⼀失,我们不仅需要对Message进⾏持久化,还需要对Exchange,Queue也进⾏持久化,⽽rabbitMQ提供了这些持久化机制,因此使⽤⼀款好的消息中间件就可以很好的解决消息丢失问题.
当然除了rabbitMQ,kafka也有相应的解决⽅案,就不细说了(主要是不会).
5.什么是分布式事务?分布式事务的类型有哪些?
涉及到多个数据库操作的事务即为分布式事务,⽬的是为保证分布式系统中的数据⼀致性.
分布式事务类型:
redis支持的数据结构⼆阶段提交2PC:第⼀步请求阶段通过协调者来统计表决结果,第⼆步执⾏表决后的结果,如果表决的结果是提交,那就提交执⾏,否则不执⾏提交.缺点是同步阻塞,⽽且万⼀协调者挂了就⽆法保证ACID.
三阶段提交3PC:在2PC的第⼀步拆分成了2步并且引⼊了超时机制,解决了2PC的痛点.第⼀步先向参与者发出⼀个信号,看看⼤家是否都能提交,如果可以就返回yes,否则返回no.第⼆步PreCommit阶段,预提交⼀下,如果参与者可以完成commit,就返回ack进确认,如果不能则放弃提交本次事务.第三步doCommit阶段,进⾏真正的事务提交.
6.分布式事务的解决⽅案有哪些?
XA:XA是基于⼆阶段事务实现的⼀种标准协议,⽬前主流数据库都已⽀持该协议.由于是⼆阶段提交,缺点很明显,不适合⾼并发场景.
补偿机制TCC:try,commit,cancel的缩写,try阶段进⾏检测,commit提交执⾏,只要try阶段成功了commit就⼀定会被执⾏,cancel业务出现错误时执⾏,回滚事务,释放资源.
消息中间件MQ:可以通过阿⾥的消息中间件RocketMQ来进⾏解决.RocketMQ⽀持带事务的消息,具体思路⼤概是这样的:
第⼀步:消息⽣产者向消息集发送prepared消息,获取消息地址.
第⼆步:本地提交事务,并向集发送确认消息.
第三步:通过第⼀步获取到的地址,访问消息并改变消息状态.
7.Dubbo的服务请求失败怎么处理
Dubbo启动时有默认的重试机制和超时机制,如果服务在限定的请求时间内没有响应,则认为本次请求失败.
如果在配置的重试次数内,请求失败后dubbo会重新发送请求,如果超过请求失败的重试次数还没有请求成功,则认为本次请求失败,抛出异常.
8.Dubbo⽀持哪些协议?Dubbo的默认协议是什么?
Dubbo⽀持多种协议,⽐如dubbo,http,rmi,webservice,默认⽀持的协议是dubbo协议.
9.Dubbo和SpringCloud有哪些区别?
Dubbo是soa(⾯向服务的架构),SpringCloud是微服务架构.
Dubbo基于RPC(远程过程调⽤),SpringCloud是基于Restful,前者底层是tcp连接,后者是http,在⼤量请求的情况下,dubbo的响应时间要短于springcloud.
Dubbo的提供的功能要少于springcloud,springcloud提供了⼀整套的微服务治理⽅案,⽐如服务熔断,监控,追踪,配置中⼼等.
10.Soa和微服务架构有哪些区别?
微服务是在Soa的基础上发展⽽来,从粒度上来说,微服务的粒度要⽐SOA更细.
微服务由于粒度更细,所以微服务架构的耦合度相对于SOA架构的耦合度更低.
微服务的服务规模相较于SOA⼀般要更⼤,所能承载的并发量也更⾼.
11.dubbo服务提供者,服务消费者需要配置哪些信息?
提供者:需要配置IP,端⼝,协议.
消费者:注册中⼼的地址.
12.Dubbo有哪些负载均衡策略
⼀致性Hash均衡算法,轮询,随机调⽤,最少活动调⽤法.
13Redis⽀持哪些数据结构?分别有哪些应⽤场景?
Redis⼀共⽀持5种数据类型:String,List,Hash,set,sort set.
String常被⽤来存放字符串,get,set缓存.
List可以⽤来做列表.Hash⽤来放对象,⽐如⽤户的信息.sort set可以⽤来做排⾏榜
13.Redis的持久化⽅式有哪些?各有何利弊?
Redis的持久化有两种⽅式,AOF和RDB.
AOF:以独⽴⽇志记录写命令⽅式存储⽇志,重启时再重新执⾏⽇志中记录的数据即可完成恢复.优势是数据安全,不容易丢数据,⽽且aof中的内容可以读懂,如果不⼩⼼敲了flushall命令,还可以将aof⽂件尾部的flushall命令删掉,然后就可以恢复数据了.缺点是占⽤存储空间⼤,数据恢复较慢.
RDB:将内存中的数据以快照的⽅式写进⼆进制⽂件中.优势是数据恢复快,⽅便备份,缺点是⽐较耗内存,可能会造成数据丢失.
14.aof⽂件过⼤怎么处理?
可以重复执⾏aof命令,bgwriteaof,执⾏后会触发重写aof⽂件,会将aof中的重复命令进⾏压缩.
15.讲⼀下redis的事务
redis的事务先以MULTI开启事务,将多个命令⼊队到事务中,然后通过EXEC命令触发执⾏队伍中的所有命令,如果想取消事务可以执⾏discard命令.
16.缓存雪崩是什么
如果所有缓存数据设置的过期时间是相同的,那么所有缓存在同⼀时间内由于到期⽽失效,此时请求会全部进⼊数据库,这就是缓存雪崩. 17.如何避免缓存雪崩
可以对缓存的过期时间设置⼀个随机值,避免缓存在同⼀时间过期.
18.缓存穿透是什么?如何避免?
缓存穿透就是指在查询⼀个⼀定不存在的数据时,缓存会不命中,如果从数据库中查询不到则不放⼊缓存,则每次请求实际都会进数据库进⾏查询,失去了缓存的意义.
可以采⽤布隆过滤,也就是将数据库中所有可能存在的数据哈希放到⼀张⾜够⼤的bitmap中,⼀定不存在的数据就会被bitmap过滤掉,从⽽减轻数据库的压⼒.
zab协议,zab协议有2种模式恢复模式(选主)和⼴播模式(同步),当服务启动或者主节点宕机后,zk会进⼊恢复模式,选出Master节点后就可以进⾏数据同步了.
zookeeper可以作为dubbo的注册中⼼,可以做分布式锁,可以做mycat的配置中⼼.
有临时节点和永久节点,分再细⼀点有临时有序/⽆序节点,有永久有序/⽆序节点.
当创建临时节点的程序结束后,临时节点会⾃动消失,临时节点上的数据也会⼀起消失.
22.讲⼀下zookeeper的选举机制
zookeeper的节点数必须为2n+1,也就是奇数个节点,以此来保证选举成功.
以5个节点的集为例,每个zk都有⾃⼰的id,叫myid,这⾥假设我5台服务器zk的myid依次为1-5.
启动myid为1的zk,它会给⾃⼰投票,然后发现集中⽆其他节点启动,于是它处于looking状态
启动myid为2的zk,它会给⾃⼰投票,然后与节点1互换投票,由于节点2的myid⼤于节点1,所以此次投票节点2胜出,但节点2此时的得票少于总节点数的⼀半,所以节点2不能被作为master,节点2也将处于looking状态
启动myid为3的zk,它会给⾃⼰投票,然后与节点1,2互换投票,由于节点3的myid⼤于节点2,所以此次投票节点3胜出,节点3的得票数⼤于节点总数的⼀半了,此时节点3胜出,成为master节点,其他两个节点成为slaver节点
启动myid为4的zk,尽管节点4的myid最⼤,但此时已经有主了,节点4也只能乖乖做⼀个从节点...
启动myid为5同上...
当有节点挂了之后,开始重新选举,选举规则跟上⾯类似.
因为zookeeper的选举算法要求:可⽤节点数 > 总节点数/2 如果为奇数个节点的话,⼀旦zk集发⽣均等脑裂,就⽆法保证该算法要求.
24.如何保证消息队列的⾼可⽤
可⽤采⽤集来保证⾼可⽤,以RabbitMQ为例,推荐采⽤镜像集,普通集如果磁盘节点挂了就GG了,还是⽆法保证⾼可⽤,镜像集的配置要⽤到HAProxy,需要在后台管理页⾯中设置策略,将ha-mode设置为all,表明每个节点上都存放镜像...限于篇幅,具体的集配置我后⾯会专门写⼀篇博客总结.
25.如何保证消息不被重复消费(幂等性问题)
rabbitmq并没有提供防⽌消息重复消费的功能,只能在业务端去实现,如果业务是做了集的,我们可以⽤redis帮助解决,具体做法是将消息的msgid和消费状态⽤redis存储起来,每次消费前先查看⼀下本次消费的消息状态,如果已经被消费过了,就可以不⽤消费.如果尚未消费,就可以进⾏消费,消费完把对应的状态改为已消费即可.
26.如何保证消息的消费顺序?
以rabbitmq为例,消息1和消息2需要按顺序消费,必须先消费消息1,后消费消息2,我们可以将消息放顺序到不同的queue⾥,然后由worker来消费.
27.如何解决消息队列的延时及过期失效问题?
批量重导,⾃⼰写程序把失效的数据查出来然后重新导⼊队⾥中.
28.消息队列满了怎么处理?当消息过度积压怎么处理?
应当在设计上尽量避免出现这种问题,如果确实已经碰到了,可以采取服务降级策略,同时临时增加⼀些消费能⼒更强劲的消费者,以X倍速率消费队列中积压的消息.

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。