当前位置 博文首页 > 青春季风暴:Java面试题--dubbo&zookeeper
dubbo是什么
dubbo是一个分布式框架,远程服务调用的分布式框架,其核心部分包含:
集群容错:提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。
远程通讯: 提供对多种基于长连接的NIO框架抽象封装,包括多种线程模型,序列化,以及“请求-响应”模式的信息交换方式。
自动发现:基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。
?
dubbo能做什么
1.透明化的远程方法调用,就像调用本地方法一样调用远程方法,只需简单配置,没有任何API侵入。
2.软负载均衡及容错机制,可在内网替代F5等硬件负载均衡器,降低成本,减少单点。
3.服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址,并且能够平滑添加或删除服务提供者。
?
在 Provider 上可以配置的 Consumer 端的属性有哪些?
1)timeout:方法调用超时
2)retries:失败重试次数,默认重试 2 次
3)loadbalance:负载均衡算法,默认随机
4)actives 消费者端,最大并发调用限制
?
Dubbo支持服务多协议吗?
Dubbo 允许配置多协议,在不同服务上支持不同协议或者同一服务上同时支持多种协议。
?
当一个服务接口有多种实现时怎么做?
当一个接口有多种实现时,可以用 group 属性来分组,服务提供方和消费方都指定同一个 group 即可。
?
服务上线怎么兼容旧版本?
可以用版本号(version)过渡,多个不同版本的服务注册到注册中心,版本号不同的服务相互间不引用。这个和服务分组的概念有一点类似。
?
Dubbo可以对结果进行缓存吗?
可以,Dubbo 提供了声明式缓存,用于加速热门数据的访问速度,以减少用户加缓存的工作量。
?
Dubbo服务之间的调用是阻塞的吗?
默认是同步等待结果阻塞的,支持异步调用。
Dubbo 是基于 NIO 的非阻塞实现并行调用,客户端不需要启动多线程即可完成并行调用多个远程服务,相对多线程开销较小,异步调用会返回一个 Future 对象。
?
Dubbo中zookeeper做注册中心,如果注册中心集群都挂掉,发布者和订阅者之间还能通信么?
可以通信的,启动dubbo时,消费者会从zk拉取注册的生产者的地址接口等数据,缓存在本地。每次调用时,按照本地存储的地址进行调用;
注册中心对等集群,任意一台宕机后,将会切换到另一台;注册中心全部宕机后,服务的提供者和消费者仍能通过本地缓存通讯。服务提供者无状态,任一台 宕机后,不影响使用;服务提供者全部宕机,服务消费者会无法使用,并无限次重连等待服务者恢复;
挂掉是不要紧的,但前提是你没有增加新的服务,如果你要调用新的服务,则是不能办到的。
?
dubbo服务负载均衡策略?
l Random LoadBalance
????随机,按权重设置随机概率。在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。(权重可以在dubbo管控台配置)
l RoundRobin LoadBalance
????轮循,按公约后的权重设置轮循比率。存在慢的提供者累积请求问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。
?
l LeastActive LoadBalance
???最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。
l ConsistentHash LoadBalance
一致性Hash,相同参数的请求总是发到同一提供者。当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。缺省只对第一个参数Hash,如果要修改,请配置
?
?Dubbo在安全机制方面是如何解决的
Dubbo通过Token令牌防止用户绕过注册中心直连,然后在注册中心上管理授权。Dubbo还提供服务黑白名单,来控制服务所允许的调用方。
?
dubbo的调用流程
Provider
第 0 步,start 启动服务。
第 1 步,register 注册服务到注册中心。
Consumer
第 2 步,subscribe 向注册中心订阅服务。
注意,只订阅使用到的服务。
再注意,首次会拉取订阅的服务列表,缓存在本地。
【异步】第 3 步,notify 当服务发生变化时,获取最新的服务列表,更新本地缓存。
invoke 调用
Consumer 直接发起对 Provider 的调用,无需经过注册中心。而对多个 Provider 的负载均衡,Consumer 通过 cluster 组件实现。
count 监控
【异步】Consumer 和 Provider 都异步通知监控中心。
?
Dubbo 可以对调用结果进行缓存吗?
Dubbo 通过 CacheFilter 过滤器,提供结果缓存的功能,且既可以适用于 Consumer 也可以适用于 Provider 。
通过结果缓存,用于加速热门数据的访问速度,Dubbo 提供声明式缓存,以减少用户加缓存的工作量。
Dubbo 目前提供三种实现:
lru :基于最近最少使用原则删除多余缓存,保持最热的数据被缓存。
threadlocal :当前线程缓存,比如一个页面渲染,用到很多 portal,每个 portal 都要去查用户信息,通过线程缓存,可以减少这种多余访问。
jcache :与 JSR107 集成,可以桥接各种缓存实现。
?
服务提供方的优雅停机过程
首先,从注册中心中取消注册自己,从而使消费者不要再拉取到它。
然后,sleep 10 秒( 可配 ),等到服务消费,接收到注册中心通知到该服务提供者已经下线,加大了在不重试情况下优雅停机的成功率。
之后,广播 READONLY 事件给所有 Consumer 们,告诉它们不要在调用我了!!!【很有趣的一个步骤】并且,如果此处注册中心挂掉的情况,依然能达到告诉 Consumer ,我要下线了的功能。
再之后,sleep 10 毫秒,保证 Consumer 们,尽可能接收到该消息。
再再之后,先标记为不接收新请求,新请求过来时直接报错,让客户端重试其它机器。
再再再之后,关闭心跳线程。
最后,检测线程池中的线程是否正在运行,如果有,等待所有线程执行完成,除非超时,则强制关闭。
最最后,关闭服务器。
?
Dubbo Consumer 只能调用从注册中心获取的 Provider 么?
不是,Consumer 可以强制直连 Provider 。
在开发及测试环境下,经常需要绕过注册中心,只测试指定服务提供者,这时候可能需要点对点直连,点对点直连方式,将以服务接口为单位,忽略注册中心的提供者列表,A 接口配置点对点,不影响 B 接口从注册中心获取列表。
?
Dubbo 支持哪些通信协议?
对应【protocol 远程调用层】。
Dubbo 目前支持如下 9 种通信协议:
【重要】dubbo:
【重要】rest:
webservice:
redis:
http:
?
服务调用超时问题怎么解决
dubbo在调用服务不成功时,默认是会重试两次的。这样在服务端的处理时间超过了设定的超时时间时,就会有重复请求,比如在发邮件时,可能就会发出多份重复邮件,执行注册请求时,就会插入多条重复的注册数据,那么怎么解决超时问题呢?如下
1.对于核心的服务中心,去除dubbo超时重试机制,并重新评估设置超时时间。
2.业务处理代码必须放在服务端,客户端只做参数验证和服务调用,不涉及业务流程处理
全局配置实例
<dubbo:provider delay="-1" timeout="6000" retries="0"/>??
当然Dubbo的重试机制其实是非常好的QOS保证,它的路由机制,是会帮你把超时的请求路由到其他机器上,而不是本机尝试,所以 dubbo的重试机器也能一定程度的保证服务的质量。但是请一定要综合线上的访问情况,给出综合的评估。
?
默认使用什么序列化框架,还有其他的吗?
Dubbo默认使用的是Hessian序列化。hessian是一个采用二进制格式传输的服务框架,相对传统soap web service,更轻量,更快速。
?
遇到的问题
场景描述:客户端远程异步调用ServiceA,ServiceA在处理客户端请求的过程中需要远程同步调用ServiceB,ServiceA从ServiceB的响应中取数据时,得到的是null。
对于上面的问题,解决办法有三个:
1.方法调用两次
ServiceA调用ServiceB的地方写两次一样的调用,这个方法原理就像ServiceB调用ServiceC一样,即清除attachements。
这个方法最简单,但是可能对不了解的人来说,这块业务代码写重复了,会不小心删除掉,而且从写代码的角度来说,这个很鸡肋,所以不推荐。
2.修改Dubbo源码
?
修改AbstractInvoker第137行,改成每次都对async进行实际赋值,
boolean isAsync = getUrl().getMethodParameter(invocation.getMethodName(), Constants.ASYNC_KEY, false);
invocation.setAttachment(Constants.ASYNC_KEY, String.valueOf(isAsync));
3.自定义Filter
?
实现com.alibaba.dubbo.rpc.Filter,在RpcContext中清除这个async,
@Activate(group = {Constants.PROVIDER})
??public class AsyncFilter implements Filter {
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
?????RpcContext.getContext().getAttachments().remove(Constants.ASYNC_KEY);
return invoker.invoke(invocation);
}
}
同时在src/main/resources/META-INF/dubbo/下添加com.alibaba.dubbo.rpc.Filter文件,内容文件如下:
asyncFilter=com.abc.filter.AsyncFilter
?
Zookeeper是什么框架
分布式开源框架,提供分布式协调服务,解决了分布式一致性问题。原本是Hadoop、HBase的一个重要组件。
?
应用场景
结合实际工作中,Zookeeper主要是用于dubbo框架的注册中心。Dubbo框架的提供者会向Zookeeper下的provider目录注册自己的URL。消费者订阅提供者的注册URL,并在consumer下注册自己的URL,以便在后续执行中调用提供者。消费者获取到URL之后,netty调用提供者提供的服务。提供者若发生了变化会主动通过zookeeper推送给消费者。
?
Paxos算法&Zookeeper使用协议
Paxos算法是分布式选举算法,Zookeeper使用的 ZAB协议(Zookeeper原子广播)
相同点:
比如都有一个Leader,用来协调N个Follower的运行;Leader要等待超半数的Follower做出正确反馈之后才进行提案
?
?
Zookeeper有哪几种节点类型
持久:创建之后一直存在,除非有删除操作,创建节点的客户端会话失效也不影响此节点。
持久顺序:持久节点名后缀加上一个10位数字。
临时:创建客户端会话失效(注意是会话失效,不是连接断了),节点也就没了。不能建子节点。
临时顺序:临时节点名后缀加上一个10位数字。
?
Zookeeper对节点的watch监听通知是永久的吗?
不是。官方声明:一个Watch事件是一个一次性的触发器,当被设置了Watch的数据发生了改变的时候,则服务器将这个改变发送给设置了Watch的客户端,以便通知它们。
?
为什么不是永久的,举个例子,
如果服务端变动频繁,而监听的客户端很多情况下,每次变动都要通知到所有的客户端,这太消耗性能了。
一般是客户端执行getData(“/节点A”,true),如果节点A发生了变更或删除,客户端会得到它的watch事件,但是在之后节点A又发生了变更,而客户端又没有设置watch事件,就不再给客户端发送。
在实际应用中,很多情况下,我们的客户端不需要知道服务端的每一次变动,我只要最新的数据即可。
?
部署方式?集群中的机器角色都有哪些?集群最少要几台机器
单机,集群,伪集群。Leader、Follower、Observer。集群最低3(2N+1)台,保证奇数,主要是为了选举算法。
集群如果有3台机器,挂掉一台集群还能工作吗?挂掉两台呢?
过半存活即可用。
集群支持动态添加机器吗?
其实就是水平扩容了,Zookeeper在这方面不太好。两种方式:
全部重启:关闭所有Zookeeper服务,修改配置之后启动。不影响之前客户端的会话。
逐个重启:这是比较常用的方式。
?
Zookeeper 具有如下特性:
顺序一致性(有序性)
从同一个客户端发起的事务请求,最终将会严格地按照其发起顺序被应用到 Zookeeper 中去。
有序性是 Zookeeper 中非常重要的一个特性。
单一视图
无论客户端连接的是哪个 Zookeeper 服务器,其看到的服务端数据模型都是一致的。
可靠性
一旦服务端成功地应用了一个事务,并完成对客户端的响应,那么该事务所引起的服务端状态变更将会一直被保留,除非有另一个事务对其进行了变更。
实时性
Zookeeper 保证在一定的时间段内,客户端最终一定能够从服务端上读取到最新的数据状态。
?
Zookeeper 的通知机制是什么?
Zookeeper 允许客户端向服务端的某个 znode 注册一个 Watcher 监听,当服务端的一些指定事件触发了这个 Watcher ,服务端会向指定客户端发送一个事件通知来实现分布式的通知功能,然后客户端根据 Watcher 通知状态和事件类型做出业务上的改变。
?
Zookeeper 的会话管理是怎么样的?
ZooKeeper 的每个客户端都维护一组服务端信息,在创建连接时由应用指定,客户端随机选择一个服务端进行连接,连接成功后,服务端为每个连接分配一个唯一标识。
?
集群如果有 3 台机器,挂掉 1 台集群还能工作吗?挂掉 2 台呢?
记住一个原则:过半存活即可用。所以挂掉 1 台可以继续工作,挂掉 2 台不可以工作。
?
ZooKeeper 的工作原理?
ZooKeeper 的核心是原子广播,这个机制保证了各个 Server 之间的同步。实现这个机制的协议叫做 Zab 协议。Zab 协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步):
?
Zookeeper 的选举过程?
当 Leader 崩溃,或者 Leader 失去大多数的 Follower,这时 Zookeeper 进入恢复模式,恢复模式需要重新选举出一个新的 Leader,让所有的 Server 都恢复到一个正确的状态。
?
?
cs