All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hc360.rsf.registry.RecoveryHandler Maven / Gradle / Ivy

The newest version!
package com.hc360.rsf.registry;

import java.text.MessageFormat;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.hc360.rsf.common.utils.CollectionUtils;
import com.hc360.rsf.common.utils.NamedThreadFactory;
import com.hc360.rsf.config.GlobalManager;
import com.hc360.rsf.remoting.Channel;
import com.hc360.rsf.remoting.Client;
import com.hc360.rsf.remoting.RemotingException;

/**
 * 从不可用服务列表中恢复节点数据到可用服务列表的线程
 * 
 * @author liuhe
 * @version 4.0 2013-8-1
 * @since 4.0	
 */
public class RecoveryHandler {
	
	private static Logger logger = LoggerFactory.getLogger(RecoveryHandler.class);
	private static final int RUN_INTERVAL=5*60*1000;//5分钟,执行定任务的时间间隔
	private static final int INIT_DELAY = 1000;  //初始化延迟
	
	private ScheduledFuture recoveryFuture;
	
	//执行定时任务的线程,守护线程
	private final ScheduledExecutorService scheduledRecovery = Executors.newScheduledThreadPool(1,
			new NamedThreadFactory("rsf-recovery", true));
	
	/**
	 * 构造方法 这样是不是不太好
	 */
	public RecoveryHandler(){
		//启动任务
		startRecoveryTask();
	}
	
	/**
	 * 启动任务
	 * 
	 */
	private void startRecoveryTask() {
		
		// 每heartbeat毫秒执行一次任务,两次任务的执行间隔是heartbeat毫秒+任务执行用时
		recoveryFuture = scheduledRecovery.scheduleWithFixedDelay(new Runnable() {
			public void run() {
				try {
					//得到所有的不可用列表
					List allIdleProviderList = ServiceProviderIdelList.findAllServiceList();
					
					//如果不可用列表为空,不做任何处理
					if(CollectionUtils.isEmpty(allIdleProviderList))
						return ;
					
					logger.debug("本次要恢复的源allIdleProviderList大小是{},明细是:{},",allIdleProviderList.size(),allIdleProviderList);
					Client client = GlobalManager.getClient();
					Channel channel = null;
					boolean isRecovery = false;
					for(Provider provider:allIdleProviderList){
						try{
							//可能从channelMap中得到一个,这样说明它用的端口已经叫其他服务占用了
							channel = client.getOrCreateChannel(provider.getIp(),provider.getPort());		
						}catch(Exception e){
							logger.error("恢复时,创建连接时异常",e);
						}
						
						if(channel != null && channel.isConnected()){
							try {
								isRecovery = channel.isContainService(provider.getServiceName());
								if(isRecovery){
									//将从不可用列表中找到的可用提供者恢复到可用列表中,并从不可用列表中移除
									ServiceProviderList.addNode(provider);
									ServiceProviderIdelList.romveNode(provider);
									logger.info("通过RecoveryHandler线程,{}从ServiceProviderIdelList恢复到ServiceProviderList里。",provider);
								}
							} catch (RemotingException e) {
						        logger.warn(MessageFormat.format("在RecoveryHandler线程中,{0}回声测试{1}出现异常",channel,provider.getServiceName()),e);
							}
						}
					}
				} catch (Throwable e) {
					logger.error("RecoveryHandler 执行恢复时出现异常",e);
				}
			}
		}, INIT_DELAY, RUN_INTERVAL,TimeUnit.MILLISECONDS);
	}
	
	/**
	 * 关闭
	 * 1、停止任务
	 * 2、停止线程池中的线程  
	 */
	public void close(){
		stopRecoveryFuture();
		if(scheduledRecovery!=null){
			scheduledRecovery.shutdownNow();
		}
	}
	
	/**
	 * 停止 任务
	 */
	private void stopRecoveryFuture() {
		if (recoveryFuture != null && !recoveryFuture.isCancelled()) {
			try {
				recoveryFuture.cancel(true);
				logger.info("关闭recovery定时任务");
			} catch (Throwable e) {
				logger.error("stopRecoveryFuture 异常",e);
			}
		}
		recoveryFuture = null;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy