每天50个JAVA八股~(十五)

1、消息基于什么传输?

由于 TCP 连接的创建和销毁开销较大,且并发数受系统资源限制,会造成性能瓶颈。

RabbitMQ 使用信道的方式来传输数据。信道是建立在真实的 TCP 连接内的虚拟连接,且每条 TCP 连接上的信道数量没有限制

2、消息如何分发?

若该队列至少有一个消费者订阅,消息将以循环(round-robin)的方式发送给消费者。

每条消息只会分发给一个订阅的消费者(前提是消费者能够正常处理消息并进行确认)。

通过路由可实现多消费的功能

3、消息怎么路由?

消息提供方->路由->一至多个队列

消息发布到交换器时,消息将拥有一个路由键(routing key),在消息创建时设定。

通过队列路由键,可以把队列绑定到交换器上。 消息到达交换器后,RabbitMQ 会将消息的路由键与队列的路由键进行匹配(针对不同的交换器有不同的路由规则);

常用的交换器主要分为三种        

fanout:如果交换器收到消息,将会广播到所有绑定的队列上

direct:如果路由键完全匹配,消息就被投递到相应的队列

topic:可以使来自不同源头的消息能够到达同一个队列。 使用 topic 交换器时,可以使用通配符

4、如何确保消息不丢失?

消息持久化,当然前提是队列必须持久化

RabbitMQ 确保持久性消息能从服务器重启中恢复的方式是,将它们写入磁盘上的一个持久化日志文件,当发布一条持久性消息到持久交换器上时,Rabbit 会在消息提交到日志文件后才发送响应。

5、使用 RabbitMQ 有什么好处?

1)、服务间高度解耦

2)、异步通信性能高

3)、流量削峰

6、RabbitMQ 的集群

镜像集群模式

你创建的 queue,无论元数据还是 queue 里的消息都会存在于多个实例上,然后每次你写消息到 queue 的时候,都会自动把消息到多个实例的 queue 里进行消息同步。

好处在于,你任何一个机器宕机了,没事儿,别的机器都可以用。

坏处在于,

第一,这个性能开销大,消息同步所有机器,导致网络带宽压力和消耗很重!

第二,这么玩儿,就没有扩展性可言了,如果某个 queue 负载很重,你加机器,新增的机器也包含了这个 queue的所有数据,并没有办法线性扩展你的 queue

7、mq 的缺点

系统可用性降低

系统引入的外部依赖越多,越容易挂掉

系统复杂性提高

怎么保证消息没有重复消费?怎么处理消息丢失的情况?怎么保证消息传递的顺序性?

所以消息队列实际是一种非常复杂的架构

引入它有很多好处也得针对坏处做各种额外的技术方案和架构来规避掉,

之后系统复杂度提升了一个数量级,也许是复杂了 10 倍。

但是关键时刻,还是得用

8、Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么区别?

对于吞吐量来说kafka和RocketMQ支撑高吞吐,ActiveMQ和RabbitMQ比他们低一个数量级。

对于延迟量来说RabbitMQ是最低的。 

持久化消息比较

ActiveMq 和RabbitMq 都支持。持久化消息主要是指我们机器在不可抗力因素等情况下挂掉了,消息不会丢失的机制。

综合技术实现可靠性、灵活的路由、集群、事务、高可用的队列、消息排序、问题追踪、可视化管理工具、插件系统等等。

高并发

毋庸置疑,RabbitMQ 最高,原因是它的实现语言是天生具备高并发高可用的erlang 语言。

Kafka 设计的初衷就是处理日志的,可以看做是一个日志(消息)系统一个重要组件,针对性很强,所以 如果业务方面还是建议选择 RabbitMq 。还有就是,Kafka 的性能(吞吐量、TPS )比RabbitMq 要高出来很多

9、如何保证高可用的?

RabbitMQ 有三种模式:单机模式、普通集群模式、镜像集群模式。

单机模式,就是 Demo 级别的

镜像集群模式:这种模式,才是所谓的 RabbitMQ 的高可用模式

10、如何保证消息的可靠传输?如果消息丢了怎么办

数据的丢失问题,可能出现在生产者、MQ、消费者中

生产者丢失:生产者将数据发送到 RabbitMQ 的时候,可能数据就在半路给搞丢了

此时可以选择用 RabbitMQ 提供的事务功能,就是生产者发送数据之前开启 RabbitMQ事务channel.txSelect,然后发送消息,如果消息没有成功被 RabbitMQ 接收到,那么生产者会收到异常报错,此时就可以回滚事务channel.txRollback,然后重试发送消息;如果收到了消息,那么可以提交事务channel.txCommit。吞吐量会下来,因为太耗性能。

一般来说,如果你要确保说写RabbitMQ 的消息别丢,可以开启 confirm模式,在生产者那里设置开启confirm模式之后,你每次写的消息都会分配一个唯一的 id,

然后如果写入了 RabbitMQ 中, RabbitMQ 会给你回传一个ack消息,告诉你说这个消息 ok 了。如果 RabbitMQ 没能处理这个消息,会回调你一个nack接口,告诉你这个消息接收失败,你可以重试。

事务机制和cnofirm机制最大的不同在于,事务机制是同步的,你提交一个事务之后会阻塞在那儿,但是confirm机制是异步的,你发送个消息之后就可以发送下一个消息,然后那个消息RabbitMQ 接收了之后会异步回调你一个接口通知你这个消息接收到了。所以一般在生产者这块避免数据丢失,都是用confirm机制的

MQ中丢失:就是 RabbitMQ 自己弄丢了数据,这个必须开启 RabbitMQ 的持久化,就是消息写入之后会持久化到磁盘,哪怕是 RabbitMQ 自己挂了,恢复之后会自动读取之前存储的数据,一般数据不会丢。

消费端丢失:你消费的时候,刚消费到,还没处理,结果进程挂了,比如重启了,那么就尴尬了,RabbitMQ 认为你都消费了,这数据就丢了。这个时候得用 RabbitMQ 提供的ack机制,简单来说,就是你关闭 RabbitMQ 的自动ack,可以通过一个 api 来调用就行,然后每次你自己代码里确保处理完的时候,再在程序里ack一把。

这样的话,如果你还没处理完,不就没有ack?

那 RabbitMQ 就认为你还没处理完,这个时候 RabbitMQ 会把这个消费分配给别的 consumer 去处理,消息是不会丢的

11、如何保证消息的顺序性

先看看顺序会错乱的场景:RabbitMQ:一个 queue,多个 consumer,这不明显乱了;

12、如何解决消息队列的延时以及过期失效问题?消息队列满了以后该怎么处理?有几百万消息持续积压几小时,说说怎么解决

消息积压处理办法:临时紧急扩容:

先修复 consumer 的问题,确保其恢复消费速度,然后将现有 cnosumer 都停掉。新建一个 topic,partition 是原来的 10 倍,临时建立好原先 10 倍的 queue 数量。然后写一个临时的分发数据的 consumer 程序,这个程序部署上去消费积压的数据,消费之后不做耗时的处理,直接均匀轮询写入临时建立好的 10 倍数量的 queue。接着临时征用 10 倍的机器来部署 consumer,每一批 consumer 消费一个临时 queue 的数据。这种做法相当于是临时将 queue 资源和 consumer 资源扩大 10 倍,以正常的 10 倍速度来消费数据。等快速消费完积压数据之后,得恢复原先部署的架构,重新用原先的 consumer 机器来消费消息。

MQ中消息失效:

假设你用的是 RabbitMQ,RabbtiMQ 是可以设置过期时间的,也就是 TTL。如果消息在 queue 中积压超过一定的时间就会被 RabbitMQ 给清理掉,这个数据就没了。

13、什么是Message?

消息,消息是不具名的,它由消息头和消息体组成。

消息体是不透明的,而消息头则由一系列的可选属性组成,

属性包括 routing- key(路由键)、 priority(相对于其他消息的优先权)、 delivery-mode(指出该消息可能需要持久性存储)等。

14、什么是Publisher ?

消息的生产者,也是一个向交换器发布消息的客户端应用程序。

15、什么是Exchange(将消息路由给队列 )

交换器,用来接收生产者发送的消息并将这些消息路由给服务器中的队列

16、什么是Binding(消息队列和交换器之间的关联)

绑定,用于消息队列和交换器之间的关联。一个绑定就是基于路由键将交换器和消息队列连接起来的路由规则,所以可以将交换器理解成一个由绑定构成的路由表

17、什么是Queue?

消息队列,用来保存消息直到发送给消费者。

是消息的容器,也是消息的终点。  

一个消息可投入一个或多个队列。消息一直在队列里面,等待消费者连接到这个队列将其取走

18、什么是Connection ?

网络连接,比如一个 TCP 连接。

19、什么是Channel?

信道, 多路复用连接中的一条独立的双向数据流通道。信道是建立在真实的 TCP 连接内地虚拟连接, AMQP 命令都是通过信道发出去的,不管是发布消息、订阅队列还是接收消息,这些动作都是通过信道完成

20、什么是Consumer ?

消息的消费者,表示一个从消息队列中取得消息的客户端应用程序

21、什么是Virtual Host ?

虚拟主机,表示一批交换器、消息队列和相关对象。

虚拟主机是共享相同的身份认证和加密环境的独立服务器域。

22、什么是Broker?

表示消息队列服务器实体

23、Exchange 类型 ?

Exchange 分发消息时根据类型的不同分发策略有区别, 目前共四种类型: direct、 fanout、topic、 headers 。

headers 匹配 AMQP 消息的 header 而不是路由键,此外 headers 交换器和direct 交换器完全一致,但性能差很多,目前几乎用不到了。

24、Direct 键(routing key)分布

消息中的路由键(routing key)如果和 Binding 中的 binding key 一致,交换器就将消息发到对应的队列中。它是完全匹配、单播的模式。

25、Fanout(广播分发)?

Fanout: 每个发到 fanout 类型交换器的消息都会分到所有绑定的队列上去。很像子网广播,每台子网内的主机都获得了一份复制的消息。

fanout 类型转发消息是最快的。

26、topic 交换器(模式匹配) ?

topic 交换器: topic 交换器通过模式匹配分配消息的路由键属性,将路由键和某个模式进行匹配,此时队列需要绑定到一个模式上。

它将路由键和绑定键的字符串切分成单词,这些单词之间用点隔开。它同样也会识别两个通配符:符号“#” 和符号“” 。 #匹配 0 个或多个单词,匹配不多不少一个单词。

27、为什么要用 Dubbo?

随着服务化的进一步发展,服务越来越多,服务之间的调用和依赖关系也越来越复杂,诞生了面向服务的架构体系(SOA),也因此衍生出了一系列相应的技术,

如对服务提供、服务调用、连接处理、通信协议、序列化方式、服务发现、服务路由、日志输出等行为进行封装的服务框架。就这样为分布式系统的服务治理框架就出现了,Dubbo 也就这样产生了

28、Dubbo 的整体架构设计有哪些分层?

接口服务层(Service):该层与业务逻辑相关,根据 provider 和 consumer 的业务设计对应的接口和实现

配置层(Config)             服务代理层(Proxy)

服务注册层(Registry)   路由层(Cluster)

监控层(Monitor)           远程调用层(Protocal)

信息交换层(Exchange)  网络传输层(Transport)

数据序列化层(Serialize)

29、默认使用的是什么通信框架,还有别的选择吗?

默认也推荐使用 netty 框架,还有 mina

30、服务调用是阻塞的吗?

默认是阻塞的,可以异步调用,没有返回值的可以这么做。

Dubbo 是基于 NIO 的非阻塞实现并行调用,客户端不需要启动多线程即可完成并行调用多个远程服务,相对多线程开销较小,异步调用会返回一个 Future 对象。

31、一般使用什么注册中心?还有别的选择吗?

推荐使用 Zookeeper 作为注册中心,还有 Redis、Multicast、Simple 注册中心,但不推荐。

32、默认使用什么序列化框架,你知道的还有哪些?

推荐使用 Hessian 序列化,还有 Duddo、FastJson、Java 自带序列化。

33、服务提供者能实现失效踢出是什么原理?

服务失效踢出基于 zookeeper 的临时节点原理。

34、服务上线怎么不影响旧版本?

采用多版本开发,不影响旧版本。

35、如何解决服务调用链过长的问题?

可以结合 zipkin 实现分布式服务追踪。

36、Dubbo 推荐用什么协议?

dubbo://(推荐)

rmi://

hessian://

http://

webservice://

thrift://

memcached://

redis://

rest://

37、同一个服务多个注册的情况下可以直连某一个服务吗?

可以点对点直连,修改配置即可,也可以通过 telnet 直接某个服务。

38、Dubbo 集群容错有几种方案?

Failover Cluster    失败自动切换,自动重试其它服务器(默认)

Failfast Cluster      快速失败,立即报错,只发起一次调用

Failsafe Cluster     失败安全,出现异常时,直接忽略

Failback Cluster    失败自动恢复,记录失败请求,定时重发

Forking Cluster      并行调用多个服务器,只要一个成功即返回

39、Dubbo 服务降级,失败重试怎么做?

可以通过 dubbo:reference 中设置 mock="return null"。

mock 的值也可以修改为 true,然后再跟接口同一个路径下实现一个 Mock 类,命名规则是 “接口名称+Mock” 后缀。

然后在 Mock 类里实现自己的降级逻辑

40、Dubbo 使用过程中都遇到了些什么问题?

在注册中心找不到对应的服务,检查 service 实现类是否添加了@service 注解无法连接到注册中心,检查配置文件中的对应的测试 ip 是否正确

41、Dubbo 用到哪些设计模式?

Dubbo 框架在初始化和通信过程中使用了多种设计模式,可灵活控制类加载、权限控制等功能。

42、Dubbo 配置文件是如何加载到 Spring 中的?

Spring 容器在启动的时候,会读取到 Spring 默认的一些 schema 以及 Dubbo 自定义的 schema,每个 schema 都会对应一个自己的

NamespaceHandler,NamespaceHandler 里面通过 BeanDefinitionParser 来解析配置信息并转化为需要加载的 bean 对象!

43、Dubbo SPI 和 Java SPI 区别?

JDK SPI

JDK 标准的 SPI 会一次性加载所有的扩展实现

如果有的扩展吃实话很耗时,但也没用上,很浪费资源。所以只希望加载某个的实现,就不现实了

DUBBO SPI

1),对 Dubbo 进行扩展,不需要改动 Dubbo 的源码

2),延迟加载,可以一次只加载自己想要加载的扩展实现。

3),增加了对扩展点 IOC 和 AOP 的支持,一个扩展点可以直接 setter 注入其它扩展点。

4),Dubbo 的扩展机制能很好的支持第三方 IoC 容器,默认支持 Spring Bean。

44、Dubbo 支持分布式事务吗?

目前暂时不支持,可与通过 tcc-transaction 框架实现

45、Dubbo 可以对结果进行缓存吗?

为了提高数据访问的速度。

Dubbo 提供了声明式缓存,以减少用户加缓存的工作量

46、服务上线怎么兼容旧版本?

可以用版本号(version)过渡,多个不同版本的服务注册到注册中心,版本号不同的服务相互间不引用。这个和服务分组的概念有一点类似。

47、Dubbo 必须依赖的包有哪些?

Dubbo 必须依赖 JDK,其他为可选。

48、Dubbo 如何优雅停机?

Dubbo 是通过 JDK 的 ShutdownHook 来完成优雅停机的,所以如果使用kill -9 PID 等强制关闭指令,是不会执行优雅停机的,只有通过kill PID 时,才会执行。

49、Dubbo 和 Dubbox 之间的区别?

Dubbox 是继 Dubbo 停止维护后,当当网基于 Dubbo 做的一个扩展项目,如加了服务可 Restful 调用,更新了开源组件等。

50、Dubbo 和 Spring Cloud 的区别?

使用 Dubbo 构建的微服务架构就像组装电脑,各环节我们的选择自由度很高,但是最终结果很有可能因为一条内存质量不行就点不亮了,总是让人不怎么放心,但是如果你是一名高手,那这些都不是问题;

 Spring Cloud 就像品牌机,在Spring Source 的整合下,做了大量的兼容性测试,保证了机器拥有更高的稳定性,但是如果要在使用非原装组件外的东西,就需要对其基础有足够的了解。

  • 17
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值