![JAR search and dependency download from the Maven repository](/logo.png)
nirvana.support.services.ZkClientSupport.scala Maven / Gradle / Ivy
// Copyright 2014 Jun Tsai. All rights reserved.
// site: http://www.ganshane.com
package nirvana.support.services
import org.apache.curator.framework.{CuratorFrameworkFactory, CuratorFramework}
import org.apache.curator.retry.RetryNTimes
import org.apache.curator.framework.state.{ConnectionState, ConnectionStateListener}
import org.apache.tapestry5.ioc.services.cron.{IntervalSchedule, PeriodicExecutor}
import java.util.concurrent.locks.ReentrantLock
/**
* zookeeper的客户端
*/
trait ZkClientSupport extends ServiceLifecycle with ServiceWaitingInitSupport {
this:ZookeeperTemplate =>
sealed class WatchMode;
case object OnceWatch extends WatchMode
case object PermanentWatch extends WatchMode
private var client:Option[CuratorFramework] = None
private final val lock = new ReentrantLock()
/**
* 得到Zookeeper的客户端
* @return zookeeper client
*/
def zkClient: CuratorFramework = {
awaitServiceInit()
client.getOrElse {
throw new NirvanaException("zk client not be initialized", NirvanaSupportErrorCode.ZK_NOT_BE_INITIALIZED)
}
}
/**
* 启动对象实例
*/
def start() {
throwExceptionIfServiceInitialized()
val builder = CuratorFrameworkFactory.builder()
.connectString(address)
.retryPolicy(new RetryNTimes(Integer.MAX_VALUE, 1000))
.connectionTimeoutMs(sessionTimeout).
defaultData(null)
if (basePath.isDefined) {
if(basePath.get.charAt(0) == '/'){
//curator中的namespace前端没有 / 开头
builder.namespace(basePath.get.substring(1))
}else{
builder.namespace(basePath.get)
}
}
val tmpClient = builder.build();
//增加统一的状态监听,方便对watcher进行再次监控
tmpClient.getConnectionStateListenable.addListener(new ConnectionStateListener() {
def stateChanged(client:CuratorFramework, state:ConnectionState) {
try {
//不支持多线程进行watch,避免过多的watch
lock.lock()
doStateChanged(state)
}finally {
lock.unlock()
}
}
})
tmpClient.start()
client = Some(tmpClient)
serviceInitialized()
}
/**
* 启动对异常数据的检测,实现FailBack功能
* @param periodExecutor 定时执行器
*/
def startCheckFailed(periodExecutor:PeriodicExecutor){
if(periodExecutor == null) {
logger.error("periodExecutor is null!")
return
}
//启动定时器
periodExecutor.addJob(new IntervalSchedule(1L * 60 * 1000),"check-zk",new Runnable {
def run() {
retry()
}
})
}
/**
* 关闭对象
*/
def shutdown() {
logger.debug("closing zk client....")
client.foreach(_.close)
}
private def doStateChanged(state:ConnectionState){
if(state == ConnectionState.CONNECTED){ //第一次连接
//connectedFun.apply(this)
}else if(state == ConnectionState.RECONNECTED){ //重新连接上,通常是session过期造成的
logger.info("cloud server reconnected")
//针对临时节点的再次创建
recreateEphemeralNodes
rewatchNodeData
rewatchChildren
//connectedFun.apply(this)
}
}
//尝试修正失败的数据
private[nirvana] def retry(){
retryFailedEphemeralNodes()
retryFailedWatchNodeData()
retryFailedChildrenWatcher()
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy