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的重试机制其实是非常好的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 都恢复到一个正确的状态。

 

 

你可能感兴趣的:(java,面试题,dubbo,zookeeper,面试)