打开网易新闻 查看精彩图片

2020年百日百更原创Java最全面试题库之往期回顾

【032期】JavaEE面试题(四)Spring(2)

开篇介绍

大家好,我是Java最全面试题库提裤姐,今天这篇是JavaEE系列的第十三篇,主要总结了ZooKeeper相关的问题;在后续,会沿着第一篇开篇的知识线路一直总结下去,做到日更!如果我能做到百日百更,希望你也可以跟着百日百刷,一百天养成一个好习惯。

Q:

说一下Zookeeper Watcher机制

Zookeeper允许客户端向服务端的某个Znode注册个Watcher监听,当服务端的一些指定事件触发了这个 Watcher,服务端会向指定客户端发送一个事件通知来实现分布式的通知功能,客户端根据 Watcher通知状态和事件类型做出业务上的改变。

工作机制:

  • 客户端注册 watcher

  • 服务端处理watcher

  • 客户端回调 watcher

Q:

客户端注册Watcher的流程?

1、客户端注册Watcher实现
2、调用getData()/getChildren()/exist()三个API,传入Watcher对象
3、标记请求request,封装Watcher到WatchRegistration
4、封装成Packet对象,发服务端发送request
5、收到服务端响应后,将Watcher注册到ZKWatcherManager中进行管理
6、请求返回,完成注册。

Q:

服务端处理Watcher的流程?

1、服务端接收Watcher并存储
接收到客户端请求,处理请求判断是否需要注册Watcher,需要的话将数据节点的节点路径和ServerCnxn(ServerCnxn代表一个客户端和服务端的连接,实现了Watcher的process接口,此时可以看成一个Watcher对象)存储在WatcherManager的WatchTable和watch2Paths中去。

2、Watcher触发

  • 以服务端接收到 setData() 事务请求触发NodeDataChanged事件为例:

  • 封装WatchedEvent

  • 将通知状态(SyncConnected)、事件类型(NodeDataChanged)以及节点路径封装成一个WatchedEvent对象

  • 查询Watcher

  • 从WatchTable中根据节点路径查找Watcher
    没找到;说明没有客户端在该数据节点上注册过Watcher
    找到;提取并从WatchTable和Watch2Paths中删除对应Watcher(从这里可以看出Watcher在服务端是一次性的,触发一次就失效了)

3、调用process方法来触发Watcher
这里process主要就是通过ServerCnxn对应的TCP连接发送Watcher事件通知。

Q:

客户端回调 Watcher流程?

1、客户端SendThread线程接收事件通知,交由 EventThread线程回调 Watcher。
2、客户端的Watcher机制同样是一次性的,一旦被触发后,该 Watcher就失效了。

Q:

Zookeeper对节点的 watch监听通知是永久的吗?为什么不是永久的?

不是永久的。
官方声明:一个 Watch事件是一个次性的触发器,当被设置了 Watch的数据发生了改变的时候,则服务器将这个改变发送给设置了 Watch的客户端,以便通知它们。

原因:
如果服务端变动频繁,而监听的客户端很多情况下,每次变动都要通知到所有的客户端,给网络和服务器造成很大压力。一般是客户端执行getData(“/节点”,true),如果节点A发生了变更或删除,客户端会得到它的 watch事件,但是在之后节点A又发生了变更,而客户端又没有设置 watch事件,就不再给客户端发送。

在实际应用中,很多情况下,我们的客户端不需要知道服务端的每一次变动,我只要最新的数据即可。

Q:

说说ACL权限控制机制

1、权限模式(Scheme)
IP:从IP地址粒度进行权限控制
Digest:最常用,用类似于 username:password 的权限标识来进行权限配置,便于区分不同应用来进行权限控制
World:最开放的权限控制方式,是一种特殊的digest模式,只有一个权限标识“world:anyone”
Super:超级用户

2、授权对象
授权对象指的是权限赋予的用户或一个指定实体,例如IP地址或是机器灯。

3、权限 Permission

  • CREATE:数据节点创建权限,允许授权对象在该Znode下创建子节点

  • DELETE:子节点删除权限,允许授权对象删除该数据节点的子节点

  • READ:数据节点的读取权限,允许授权对象访问该数据节点并读取其数据内容或子节点列表等

  • WRITE:数据节点更新权限,允许授权对象对该数据节点进行更新操作

  • ADMIN:数据节点管理权限,允许授权对象对该数据节点进行ACL相关设置操作

Q:

服务器有哪些角色?

1、Leader
事务请求的唯一调度和处理者,保证集群事务处理的顺序性
集群内部各服务的调度者

2、Follower
处理客户端的非事务请求,转发事务请求给Leader服务器
参与事务请求Proposal的投票
参与Leader选举投票

3、Observer
处理客户端的非事务请求,转发事务请求给Leader服务器
不参与任何形式的投票

Q:

Zookeeper 下 Server工作状态有哪些?

1、LOOKING:寻找Leader状态。当服务器处于该状态时,它会认为当前集群中没有Leader,因此需要进入Leader选举状态。
2、FOLLOWING:跟随者状态。表明当前服务器角色是Follower。
3、LEADING:领导者状态。表明当前服务器角色是Leader。
4、OBSERVING:观察者状态。表明当前服务器角色是Observer。

Q:

集群支持动态添加机器吗?

其实就是水平扩容,Zookeeper在这方面不太好。
两种方式:

  • 全部重启:关闭所有 Zookeeper服务,修改配置之后启动。不影响之前客户端的会话。

  • 逐个重启:在过半存活即可用的原则下一台机器重启不影响整个集群对外提供服务。(这是比较常用的方式)

3.5版本开始支持动态扩容。

Q:

3.2.0版本后,添加了该特性,该特性允许每个客户端为自己设置一个命名空间。如果一个客户端设置了 Chroot,那么该客户端对服务器的任何操作,都将会被限制在其自己的命名空间下。

通过设置 Chroot,能够将一个客户端应用与 Zookeeper服务端的一颗子树相对应,在那些多个应用公用一个 Zookeeper集群的场景下,对实现不同应用间的相互隔离非常有帮助。