大家好,又见面了,我是你们的朋友全栈君。
目录
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,提供了事务机制,你可以在消息发送前提交事务,如果发送失败会自动回滚.
// 开启事务
channel.txSelect
try {
// 这里发送消息
} catch (Exception e) {
channel.txRollback
// 这里再次重发这条消息
}
// 提交事务
channel.txCommit
但这样会比较耗性能,所以更推荐的做法是使用rabbitmq提供的confirm机制.confirm机制是异步的,在消费者收到生产者发送的消息后会回调ack,如果消费者接收失败会回调nack接口.
要想真正做到万无一失,我们不仅需要对Message进行持久化,还需要对Exchange,Queue也进行持久化,而rabbitMQ提供了这些持久化机制,因此使用一款好的消息中间件就可以很好的解决消息丢失问题.
当然除了rabbitMQ,kafka也有相应的解决方案,就不细说了(主要是不会).
5.什么是分布式事务?分布式事务的类型有哪些?
涉及到多个数据库操作的事务即为分布式事务,目的是为保证分布式系统中的数据一致性.
分布式事务类型:
二阶段提交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过滤掉,从而减轻数据库的压力.
19.zookeeper的原理
zab协议,zab协议有2种模式恢复模式(选主)和广播模式(同步),当服务启动或者主节点宕机后,zk会进入恢复模式,选出Master节点后就可以进行数据同步了.
20.zookeeper有哪些应用场景
zookeeper可以作为dubbo的注册中心,可以做分布式锁,可以做mycat的配置中心.
21.zookeeper的节点类型有哪些?有什么区别?
有临时节点和永久节点,分再细一点有临时有序/无序节点,有永久有序/无序节点.
当创建临时节点的程序结束后,临时节点会自动消失,临时节点上的数据也会一起消失.
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同上…
当有节点挂了之后,开始重新选举,选举规则跟上面类似.
23.zookeeper的节点数为什么只能为奇数个?
因为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倍速率消费队列中积压的消息.
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/131589.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...