dubbo跟thrift都是比较常见的RPC框架。
Dubbo
Dubbo只支持Java语言。
Dubbo 的架构主要包含四个角色,其中 Consumer 是服务消费者,Provider 是服务提供者,Registry 是注册中心,Monitor 是监控系统。具体的交互流程是 Consumer 一端通过注册中心获取到 Provider 节点后,通过 Dubbo 的客户端 SDK 与 Provider 建立连接,并发起调用。Provider 一端通过 Dubbo 的服务端 SDK 接收到 Consumer 的请求,处理后再把结果返回给 Consumer。
- From:hongda整理的面试题
分布式方面的问题收集
1.Dubbo简介:
调用关系:
服务容器负责启动,加载,运行服务提供者。
服务提供者在启动时,向注册中心注册自己提供的服务。
服务消费者在启动时,向注册中心订阅自己所需的服务。
注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
http://dubbo.io/books/dubbo-user-book/preface/architecture.html
2.Dubbo中zookeeper做注册中心,如果注册中心集群都挂掉,发布者和订阅者之间还能通信么?
可以的,启动dubbo时,消费者会从zk拉取注册的生产者的地址接口等数据,缓存在本地。每次调用时,按照本地存储的地址进行调用
注册中心对等集群,任意一台宕掉后,会自动切换到另一台
注册中心全部宕掉,服务提供者和消费者仍可以通过本地缓存通讯
服务提供者无状态,任一台宕机后,不影响使用
服务提供者全部宕机,服务消费者会无法使用,并无限次重连等待服务者恢复
3 dubbo连接注册中心和直连的区别
在开发及测试环境下,经常需要绕过注册中心,只测试指定服务提供者,这时候可能需要点对点直连,
点对点直联方式,将以服务接口为单位,忽略注册中心的提供者列表,
服务注册中心,动态的注册和发现服务,使服务的位置透明,并通过给消费方获取服务提供方地址列表,实现软负载均衡和Failover, 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,服务消费者向注册中心获取服务提供者地址列表,并根据负载算法直接调用提供者,注册中心,服务提供者,服务消费者三者之间均为长连接,监控中心除外,注册中心通过长连接感知服务提供者的存在,服务提供者宕机,注册中心将立即推送事件通知消费者
注册中心和监控中心全部宕机,不影响已运行的提供者和消费者,消费者在本地缓存了提供者列表
注册中心和监控中心都是可选的,服务消费者可以直连服务提供者
4.Dubbo在安全机制方面是如何解决的
Dubbo通过Token令牌防止用户绕过注册中心直连,然后在注册中心上管理授权。Dubbo还提供服务黑白名单,来控制服务所允许的调用方。
5.dubbo默认使用什么序列化框架
默认使用Hessian,现在高效的有Kryo和FST
6.Dubbo超时设置和重连机制:
DUBBO消费端设置超时时间需要根据业务实际情况来设定,如果设置的时间太短,一些复杂业务需要很长时间完成,导致在设定的超时时间内无法完成正常的业务处理。
这样消费端达到超时时间,那么dubbo会进行重试机制,不合理的重试在一些特殊的业务场景下可能会引发很多问题,需要合理设置接口超时时间。
dubbo在调用服务不成功时,默认会重试2次。Dubbo的路由机制,会把超时的请求路由到其他机器上,而不是本机尝试,所以 dubbo的重试机器也能一定程度的保证服务的质量。
但是如果不合理的配置重试次数,当失败时会进行重试多次,这样在某个时间点出现性能问题,调用方再连续重复调用,系统请求变为正常值的retries倍,系统压力会大增,容易引起服务雪崩,需要根据业务情况规划好如何进行异常处理,何时进行重试。
在重试发送的时候也可能会出现这样的问题:
比如有一个bug反馈,但是因为数据库io瓶颈,这时候这个服务阻塞了,然后过了一会查看数据库里有3条除了id外剩下都一样的数据(id是在服务提供者里生成的,这里只做异常例子举例).
这就是重试机制下,业务不合理的设计所造成的坑,这时候我们处理的方式有两种:
合理规划业务(例如id放在服务上游生成,数据库主键唯一的机制)
服务增加幂等性设置(例如接口中增加消息id)
7.Dubbo支持dubbo、rmi、hessian、http、webservice、thrift、redis等多种协议,但是Dubbo官网是推荐我们使用Dubbo协议的。
dubbo协议:
缺省协议,使用基于mina1.1.7 NIO框架库+hessian3.2.1 序列化协议 的tbremoting交互。
连接个数:单连接
连接方式:长连接
传输协议:TCP
传输方式:NIO异步传输
序列化:Hessian二进制序列化
适用范围:传入传出参数数据包较小(建议小于100K),消费者比提供者个数多,单一消费者无法压满提供者,尽量不要用dubbo协议传输大文件或超大字符串。
适用场景:常规远程服务方法调用
http://blog.csdn.net/fuyuwei2015/article/details/72848310
https://www.cnblogs.com/1201x/p/6482638.html
8.为什么要消费者比提供者个数多:
因dubbo协议采用单一长连接,
假设网络为千兆网卡(1024Mbit=128MByte),
根据测试经验数据每条连接最多只能压满7MByte(不同的环境可能不一样,供参考),
理论上1个服务提供者需要20个服务消费者才能压满网卡。
9.为什么不能传大包:
因dubbo协议采用单一长连接,
如果每次请求的数据包大小为500KByte,假设网络为千兆网卡(1024Mbit=128MByte),每条连接最大7MByte(不同的环境可能不一样,供参考),
单个服务提供者的TPS(每秒处理事务数)最大为:128MByte / 500KByte = 262。
单个消费者调用单个服务提供者的TPS(每秒处理事务数)最大为:7MByte / 500KByte = 14。
如果能接受,可以考虑使用,否则网络将成为瓶颈。
10.为什么采用异步单一长连接:
因为服务的现状大都是服务提供者少,通常只有几台机器,
而服务的消费者多,可能整个网站都在访问该服务,
比如Morgan的提供者只有6台提供者,却有上百台消费者,每天有1.5亿次调用,
如果采用常规的hessian服务,服务提供者很容易就被压跨,
通过单一连接,保证单一消费者不会压死提供者,
长连接,减少连接握手验证等,
并使用异步IO,复用线程池,防止C10K问题。
网络服务在处理数以万计的客户端连接时,往往出现效率底下甚至完全瘫痪,这被成为C10K问题。
(C10K = connection 10 kilo 问题)。k 表示 kilo,即 1000 比如:kilometer(千米), kilogram(千克)。
linux方面使用epoll解决方案
11.Java Remoting选取方案
性能要求特别高的:可以选用Socket,RMI;
跨平台,跨语言,安全性,易用性:Webservice;
跨平台,跨语言,易用性,性能:Hessian,REST;
不跨语言,性能,易用性:NIO(Netty,Mina),RMI。
12.Dubbo负载均衡和集群容错模式:
在集群负载均衡时,Dubbo提供了多种均衡策略,缺省为random随机调用。
Random LoadBalance
随机,按权重设置随机概率。
在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。
RoundRobin LoadBalance
轮循,按公约后的权重设置轮循比率。
存在慢的提供者累积请求问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。
LeastActive LoadBalance
最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。
使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。
ConsistentHash LoadBalance
一致性Hash,相同参数的请求总是发到同一提供者。
当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。
集群容错模式:
Failover Cluster
失败自动切换,当出现失败,重试其它服务器。(缺省)
通常用于读操作,但重试会带来更长延迟。
可通过retries="2"来设置重试次数(不含第一次)。正是文章刚开始说的那种情况.
Failfast Cluster
快速失败,只发起一次调用,失败立即报错。
通常用于非幂等性的写操作,比如新增记录。
Failsafe Cluster
失败安全,出现异常时,直接忽略。
通常用于写入审计日志等操作。
Failback Cluster
失败自动恢复,后台记录失败请求,定时重发。
通常用于消息通知操作。
Forking Cluster
并行调用多个服务器,只要一个成功即返回。
通常用于实时性要求较高的读操作,但需要浪费更多服务资源。
可通过forks="2"来设置最大并行数。
Broadcast Cluster
广播调用所有提供者,逐个调用,任意一台报错则报错。(2.1.0开始支持)
通常用于通知所有提供者更新缓存或日志等本地资源信息。
重试次数配置如:(failover集群模式生效)
Dubbo的集群容错和负载均衡同样也是Dubbo本身的高级特性.正如我们在说自定义扩展的时候一样,这两个特征同样也可以进行自定义扩展,用户可以根据自己实际的需求来扩展他们从而满足项目的实际需求.
13.Dubbo的优点是什么?Dubbo对分布式事务是如何处理的?
Dubbo的优点:
1)Dubbo具有调度、发现、监控、治理等功能,支持相当丰富的服务治理能力
2)集群容错
当服务调用失败时,根据我们的业务不同,可以使用不同的策略来应对这种失败。
3)负载均衡
当同一个服务有多个提供者在提供服务时, 客户端如何正确的选择提供者实现负载均衡dubbo也给我们提供了几种方案
4)多协议
dubbo提供了多种协议给用户选择, 如Dubbo协议、Hessian协议、HTTP协议、RMI协议、WebService协议、Thrift协议、Memcached协议、Redis协议。
Dubbo对分布式事务的处理:
分布式事务暂不支持。用户可以自己根据实际情况来实现分布式事务,比如:
1)结合RocketMQ消息中间件实现的可靠消息最终一致性
2)TCC补偿性事务解决方案
3)最大努力通知型方案
http://bbs.itheima.com/forum.phpmod=viewthread&tid=386556
https://dubbo.apache.org/zh-cn/docs/user/preface/architecture.html
zookeeper
一般,zookeeper配合dubbo使用,作为注册中心。
zookeeper是一种为分布式应用所设计的高可用、高性能且一致的开源协调服务,它提供了一项基本服务:分布式锁服务。由于zookeeper的开源特性,后来我们的开发者在分布式锁的基础上,摸索出了其他的使用方法:配置服务、组服务、分布式消息队列、分布式通知/协调等。
注意:zookeeper性能上的特点决定了它能够用在大型的、分布式的系统当中。从可靠性方面来说,它并不会因为一个节点的错误而崩溃。除此之外,它严格的序列访问控制意味着复杂的控制原语可以应用在客户端上。zookeeper在一致性、可用性、容错性的保证,也是zookeeper的成功之处,它获得的一切成功都与它采用的协议-Zab协议是密不可分的。
zookeeper集群的角色主要有一下三类:
1.leader角色: leader服务器是整个zookeeper集群的核心,主要的工作任务有两项1.事务请求的唯一调度和处理者,保证集群事务处理的顺序性2.集群内部各服务器的调度者。
2.follower角色:follower角色的主要职责是1.处理客户端非事务请求,转发事务请求给leader服务器2.参与事务请求proposal的投票(需要半数以上服务器通过才能通知leader commit数据;leader发起的提案,要求follower投票)3.参与leader选举的投票
3.observer角色: observer是zookeeper3.3开始引入的一个全新的服务器角色,从字面来理解,该角色充当了观察者的角色。观察zookeeper集群中的最新状态变化并将这些状态变化同步到observer服务器上。observer的工作原理与follower角色基本一致,而它和follwer角色唯一的不同在于observer不参与任何形式的投票,包括事务请求proposal的投票和leader选举的投票。简单来说,observer服务器只提供非事务请求服务,通常在于不影响集群事务处理能力的前提下提升集群非事务处理的能力。
版权归原作者 bluepad 所有, 如有侵权,请联系我们删除。