“不积跬步,无以至千里。”
背景
- 确定使用Curator作为zk客户端的情况下,断网[发生SUSPENDED | LOST事件]重连后每次都会回调
org.apache.curator.framework.state.ConnectionStateListener#stateChanged方法,且事件类型为org.apache.curator.framework.state.ConnectionState#RECONNECTED - 部署zookeeper的版本为最新稳定版3.8.3,curator-recipes相关依赖的版本为5.5.0
源码分析过程
-
首先需要构建一个CuratorFramework对象,并基于这个CuratorFramework对象创建一个用于实现Leader选举功能的LeaderSelector,并将它启动
public static final String leaderSelectorPath = "/source-code-analyse/reconnect"; public static void main(String[] args) throws InterruptedException { CuratorFramework curatorFramework = newCuratorFramework(); LeaderSelectorListener leaderSelectorListener = new LeaderSelectorListener() { @Override public void stateChanged(CuratorFramework curatorFramework, ConnectionState connectionState) { System.out.println("Thread " + Thread.currentThread().getName() + " Connection state changed : " + connectionState); } @Override public void takeLeadership(CuratorFramework curatorFramework) throws Exception { System.out.println("Thread " + Thread.currentThread().getName() + " get the leader."); TimeUnit.SECONDS.sleep(20); } }; LeaderSelector leaderSelector = new LeaderSelector(curatorFramework, leaderSelectorPath, leaderSelectorListener); leaderSelector.start(); TimeUnit.SECONDS.sleep(100); leaderSelector.close(); curatorFramework.close(); System.out.println("Test completed."); }public static CuratorFramework newCuratorFramework() { CuratorFramework curatorFramework = CuratorFrameworkFactory.builder() .connectString("192.168.0.104:2181") .sessionTimeoutMs(30000) .connectionTimeoutMs(6000) .retryPolicy(new ExponentialBackoffRetry(1000, 3)) .threadFactory(ThreadUtils.newThreadFactory("ReconnectionTestThread")).build(); curatorFramework.start(); return curatorFramework; } -
由于LeaderSelector的功能实现需要基于CuratorFramework,于是应该先看看CuratorFramework的start方法,直接看实现类CuratorFrameworkImpl
@Override public void start() { log.info("Starting"); if ( !state.compareAndSet(CuratorFrameworkState.LATENT, CuratorFrameworkState.STARTED) ) { throw new IllegalStateException("Cannot be started more than once"); } try { connectionStateManager.start(); //省略代码 -
发现
CuratorFrameworkImpl内部维护了一个与连接状态管理器,start方法中会启动它 -
在
ConnectionStateManager的start方法中,会向线程池提交一个任务,去调用processEvents方法public void start() { Preconditions.checkState(state.compareAndSet(State.LATENT, State.STARTED), "Cannot be started more than once"); service.submit ( new Callable<Object>() { @Override public Object call() throws Exception { processEvents(); return null; } } ); } -
processEvents方法里面核心的内容就是,从
eventQueue的一个阻塞队列中不断调用poll方法获取ConnectionState对象,因为处在一个while循环中,只要当前连接状态正常,就会一直去pollprivate void processEvents() { while ( state.get() == State.STARTED ) { try { int useSessionTimeoutMs = getUseSessionTimeoutMs(); long elapsedMs = startOfSuspendedEpoch ==

文章详细分析了使用Curator作为zk客户端时,断网后重连如何触发ConnectionStateListener的RECONNECTED事件,涉及源码追踪和事件处理机制。
最低0.47元/天 解锁文章
999

被折叠的 条评论
为什么被折叠?



