dubbo&&zookeeper面试题

  1. 什么是dubbo
    Dubbo是阿里巴巴SOA服务化治理方案的核心框架,是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。
  2. 测试和生产公用一套zookeeper,怎么保证消费不冲突
  • dubbo白名单(Filter过滤器)
  • 服务分组

<dubbo:service group="feedback" interface="com.xxx.IndexService" />
<dubbo:service group="member" interface="com.xxx.IndexService" />


<dubbo:reference id="feedbackIndexService" group="feedback" interface="com.xxx.IndexService" />
<dubbo:reference id="memberIndexService" group="member" interface="com.xxx.IndexService" />
  • 多版本
<dubbo:service interface="com.foo.BarService" version="1.0.0" />

第一种方案:
实现com.alibaba.dubbo.rpc.Filter接口:

public class AuthorityFilter implements Filter {  
    private static final Logger LOGGER = LoggerFactory.getLogger(AuthorityFilter.class);  

    private IpWhiteList ipWhiteList;  

    //dubbo通过setter方式自动注入  
    public void setIpWhiteList(IpWhiteList ipWhiteList) {  
        this.ipWhiteList = ipWhiteList;  
    }  

    @Override  
    public Result invoke(Invoker invoker, Invocation invocation) throws RpcException {  
        if (!ipWhiteList.isEnabled()) {  
            LOGGER.debug("白名单禁用");  
            return invoker.invoke(invocation);  
        }  

        String clientIp = RpcContext.getContext().getRemoteHost();  
        LOGGER.debug("访问ip为{}", clientIp);  
        List allowedIps = ipWhiteList.getAllowedIps();  
        if (allowedIps.contains(clientIp)) {  
            return invoker.invoke(invocation);  
        } else {  
            return new RpcResult();  
        }  
    }  
}

注意:只能通过setter方式来注入其他的bean,且不要标注注解!dubbo自己会对这些bean进行注入,不需要再标注@Resource让Spring注入

在resources目录下添加纯文本文件META-INF/dubbo/com.alibaba.dubbo.rpc.Filter,内容如下: xxxFilter=com.xxx.AuthorityFilter
修改dubbo的provider配置文件,在dubbo:provider中添加配置的filter, 内容如下:

    <dubbo:provider filter="xxxFilter" />  

这样就可以实现dubbo接口的IP白名单功能了。
出自https://www.cnblogs.com/wangzhongqiu/archive/2017/09/22/7575759.html
3. zookeeper是如何保证事务的顺序一致性的
zookeeper采用了递增的事务Id来标识,所有的proposal都在被提出的时候加上了zxid,zxid实际上是一个64位的数字,高32位是epoch用来标识leader是否发生改变,如果有新的leader产生出来,epoch会自增,低32位用来递增计数。当新产生proposal的时候,会依据数据库的两阶段过程,首先会向其他的server发出事务执行请求,如果超过半数的机器都能执行并且能够成功,那么就会开始执行
4. zookeeper的leader选举
要进行leader选举,zookeeper集群至少需要两台机器。
(myid(服务器id),ZXID(事务id))表示推举的服务器。

  • 启动时期的leader选举

每个server发出一个投票给集群中的其他机器;

服务器接受来自其他各个服务器的投票,并判断投票的有效性(包括检查是否是本轮投票、是否来自LOOKING状态的服务器);

处理投票(服务器将自己的投票和收到的投票进行对比,先检查ZXID,大的服务器作为leader;如果ZXID相同,检查myid,myid大的作为leader;更新投票),将最终的投票重新发出去;

统计投票:每次投票后,服务器统计所有投票,判断是否有过半的服务器收到相同的投票信息;如果是,则选举出了新的leader,如果不是,重新开始投票;

改变服务器状态:follower将自己的状态改为FOLLOWING,leader将自己的状态改为LEADING。

  • 运行期间的leader选举

变更状态:leader挂了以后,余下的非Observer服务器将自己的状态改为LOOKING,然后进入leader选举流程;
发出投票:每个server发出一个投票;
接收投票
处理投票:和启动时期的leader选举一样。
统计投票
改变服务器状态
5. leader选举过程
当leader崩溃或者leader失去大多数的follower,这时候zk进入恢复模式,恢复模式需要重新选举出一个新的leader,让所有的Server都恢复到一个正确的状态。Zk的选举算法使用ZAB协议:

  1. 选举线程由当前Server发起选举的线程担任,其主要功能是对投票结果进行统计,并选出推荐的Server;
  2. 选举线程首先向所有Server发起一次询问(包括自己);
  3. 选举线程收到回复后,验证是否是自己发起的询问(验证zxid是否一致),然后获取对方的id(myid),并存储到当前询问对象列表中,最后获取对方提议的leader相关信息(id,zxid),并将这些信息存储到当次选举的投票记录表中;
  4. 收到所有Server回复以后,就计算出zxid最大的那个Server,并将这个Server相关信息设置成下一次要投票的Server;
  5. 线程将当前zxid最大的Server设置为当前Server要推荐的Leader,如果此时获胜的Server获得n/2 + 1的Server票数, 设置当前推荐的leader为获胜的Server,将根据获胜的Server相关信息设置自己的状态,否则,继续这个过程,直到leader被选举出来。

通过流程分析我们可以得出:要使Leader获得多数Server的支持,则Server总数最好是奇数2n+1,且存活的Server的数目不得少于n+1
6. 客户端对serverList的轮询机制
随机,客户端在初始化( new ZooKeeper(String connectString, int sessionTimeout, Watcher watcher) )的过程中,将所有Server保存在一个List中,然后随机打散,形成一个环。之后从0号位开始一个一个使用。
两个注意点:

  • Server地址能够重复配置,这样能够弥补客户端无法设置Server权重的缺陷,但是也会加大风险。(比如: 192.168.1.1:2181,192.168.1.1:2181,192.168.1.2:2181).

  • 如果客户端在进行Server切换过程中耗时过长,那么将会收到SESSION_EXPIRED. 这也是上面第1点中的加大风险之处。

7.ZK为什么不提供一个永久性的Watcher注册机制
不支持用持久Watcher的原因很简单,ZK无法保证性能。
使用watch需要注意的几点

  • Watches通知是一次性的,必须重复注册.
  • 发生CONNECTIONLOSS之后,只要在session_timeout之内再次连接上(即不发生SESSIONEXPIRED),那么这个连接注册的watches依然在。
  • 节点数据的版本变化会触发NodeDataChanged,注意,这里特意说明了是版本变化。存在这样的情况,只要成功执行了setData()方法,无论内容是否和之前一致,都会触发NodeDataChanged。
  • 对某个节点注册了watch,但是节点被删除了,那么注册在这个节点上的watches都会被移除。
    同一个zk客户端对某一个节点注册相同的watch,只会收到一次通知。
  • Watcher对象只会保存在客户端,不会传递到服务端。

8.创建的临时节点什么时候会被删除,是连接一断就删除吗?延时是多少?
连接断了之后,ZK不会马上移除临时数据,只有当SESSIONEXPIRED之后,才会把这个会话建立的临时数据移除。因此,用户需要谨慎设置Session_TimeOut
9. 是否可以拒绝单个IP对ZK的访问,操作
ZK本身不提供这样的功能,它仅仅提供了对单个IP的连接数的限制。你可以通过修改iptables来实现对单个ip的限制;当然,你也可以通过这样的方式来解决。https://issues.apache.org/jira/browse/ZOOKEEPER-1320
10. ZooKeeper集群中服务器之间是怎样通信的?
Leader服务器会和每一个Follower/Observer服务器都建立TCP连接,同时为每个F/O都创建一个叫做LearnerHandler的实体。LearnerHandler主要负责Leader和F/O之间的网络通讯,包括数据同步,请求转发和Proposal提议的投票等。Leader服务器保存了所有F/OLearnerHandler
11. 出现调用超时com.alibaba.dubbo.remoting.TimeoutException异常怎么办?
通常是业务处理太慢,可在服务提供方执行:jstack PID > jstack.log 分析线程都卡在哪个方法调用上,这里就是慢的原因。如果不能调优性能,请将timeout设大。
12. 出现java.util.concurrent.RejectedExecutionException或者Thread pool exhausted怎么办?
RejectedExecutionException表示线程池已经达到最大值,并且没有空闲连,拒绝执行了一些任务。
Thread pool exhausted通常是min和max不一样大时,表示当前已创建的连接用完,进行了一次扩充,创建了新线程,但不影响运行。
原因可能是连接池不够用,请调整dubbo.properites中的:

// 设成一样大,减少线程池收缩开销  
dubbo.service.min.thread.pool.size=200  
dubbo.service.max.thread.pool.size=200  

你可能感兴趣的:(面试题)