摘要
本节讲解ZooKeeperServer类中的异常报警,关闭机制,在其他地方都没有找到类似解析以及源码说明。
这里自己分析源码,进行展开
ZooKeeperServerListener,作为服务器监听器,主要函数notifyStopping设置server状态为ERROR
ZooKeeperCriticalThread,作为zk危机线程,提供有处理异常的方式,即调用ZooKeeperServerListener.notifyStopping
ZooKeeperServerShutdownHandler,在zk状态为ERROR或SHUTDOWN时,完成zk的关闭操作
ZooKeeperServer的异常报警,关闭机制讲解
状态监听器
主要讲解接口ZooKeeperServerListener以及实现类ZooKeeperServerListenerImpl
监听器与服务器关系类图.png
接口ZooKeeperServerListener
方法如下
void notifyStopping(String threadName, int errorCode);//用于在线程发生严重问题时,通知server
实现类ZooKeeperServerListenerImpl
private final ZooKeeperServer zkServer;
ZooKeeperServerListenerImpl(ZooKeeperServer zkServer) {
this.zkServer = zkServer;
}
@Override
public void notifyStopping(String threadName, int exitCode) {
LOG.info("Thread {} exits, error code {}", threadName, exitCode);
zkServer.setState(State.ERROR);//ZooKeeperServer设置对应状态即可
}
这里只是调用 zkServer.setState(State.ERROR),具体监听到ERROR时该怎么干,是在zkserver中完成的事情,这里只监听和通知
上面有notifyStopping这个方法,那么这个方法在何时被调用呢?
报警危机线程ZooKeeperCriticalThread
ZooKeeperServerListener#notifyStopping何时被调用呢,就在ZooKeeperCriticalThread中
备注:这个中文名是我自己起的。。。
类图如下
源码如下,很简单
/**
* Represents critical thread. When there is an uncaught exception thrown by the
* thread this will exit the system.
*/
public class ZooKeeperCriticalThread extends ZooKeeperThread {
private static final Logger LOG = LoggerFactory
.getLogger(ZooKeeperCriticalThread.class);
private final ZooKeeperServerListener listener;
public ZooKeeperCriticalThread(String threadName,
ZooKeeperServerListener listener) {
super(threadName);//父类是个thread
this.listener = listener;//设置监听器实例
}
/**
* This will be used by the uncaught exception handler and make the system
* exit.
*
* @param threadName
* - thread name
* @param e
* - exception object
*/
@Override
protected void handleException(String threadName, Throwable e) {//处理异常
LOG.error("Severe unrecoverable error, from thread : {}", threadName, e);
listener.notifyStopping(threadName, ExitCode.UNEXPECTED_ERROR);//观察者模式,调用监听器的对应逻辑
}
}
这里通过观察者模式,当ZooKeeperCriticalThread的实例遇到异常时,调用handleException,会给对应的监听器通知,完成notifyStopping的操作
ZooKeeperServerShutdownHandler
这个类图都不用画了,直接源码
class ZooKeeperServerShutdownHandler {
private final CountDownLatch shutdownLatch;
ZooKeeperServerShutdownHandler(CountDownLatch shutdownLatch) {
this.shutdownLatch = shutdownLatch;
}
/**
* This will be invoked when the server transition to a new server state.
*
* @param state new server state
*/
void handle(State state) {
if (state == State.ERROR || state == State.SHUTDOWN) {
shutdownLatch.countDown();
}
}
}
就是说,关闭处理器handle,就是把一个计时器-1
异常报警,关闭机制流程
这里以例子为说明,入口以ZooKeeperCriticalThread的一个子类为例,如SessionTrackerImpl好了,源码之前也讲解过
1.异常触发
SessionTrackerImpl#run
调用
catch (InterruptedException e) {
handleException(this.getName(), e);
}
2.调用ZooKeeperCriticalThread#handleException
@Override
protected void handleException(String threadName, Throwable e) {//处理异常
LOG.error("Severe unrecoverable error, from thread : {}", threadName, e);
listener.notifyStopping(threadName, ExitCode.UNEXPECTED_ERROR);//观察者模式,调用监听器的对应逻辑
}
3.监听器通知stop:ZooKeeperServerListener#notifyStopping
实现类ZooKeeperServerListenerImpl#notifyStopping
@Override
public void notifyStopping(String threadName, int exitCode) {
LOG.info("Thread {} exits, error code {}", threadName, exitCode);
zkServer.setState(State.ERROR);//ZooKeeperServer设置对应状态即可
}
4.zkServer设置状态:ZooKeeperServer#setState
protected void setState(State state) {//根据zkShutdownHandler处理state
this.state = state;
// Notify server state changes to the registered shutdown handler, if any.
if (zkShutdownHandler != null) {
zkShutdownHandler.handle(state);
} else {
LOG.error("ZKShutdownHandler is not registered, so ZooKeeper server "
+ "won't take any action on ERROR or SHUTDOWN server state changes");
}
}
5.zkShutdownHandler处理state:ZooKeeperServerShutdownHandler#handle
void handle(State state) {
if (state == State.ERROR || state == State.SHUTDOWN) {
shutdownLatch.countDown();
}
}
6.计时器到0,停止server
这一部分代码在zkServer外层,在ZooKeeperServerMain#runFromConfig中
zkServer与计时器完成server停止也就是启动时,zkServer有一个计时器为1,当遇到严重异常时,计时器-1变为0,就调用ZooKeeperServerMain#shutdown
ZooKeeperServerMain#shutdown这里不展开,讲到ServerCnxnFactory再讲
思考
遇到严重异常时,server的关闭流程调用链总结
遇到严重异常 -> ZooKeeperCriticalThread#handleException -> ZooKeeperServerListener#notifyStopping -> ZooKeeperServer#setState -> ZooKeeperServerShutdownHandler#handle -> 计数器为0 -> ZooKeeperServerMain#shutdown
ZooKeeperCriticalThread,ZooKeeperServerListener,ZooKeeperServerShutdownHandler三个类的作用总结
ZooKeeperCriticalThread:表明了哪些入口的异常可以算作是严重的异常,能够让server关闭的,并且handleException方法完成对ZooKeeperServerListener的调用
ZooKeeperServerListener:表示接收到异常时,通知zk状态变更为ERROR
ZooKeeperServerShutdownHandler:用于处理zk为ERROR和SHUTDOWN状态时,计数器-1
refer
无
网友评论