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

com.alibaba.tmq.client.TMQFactory Maven / Gradle / Ivy

package com.alibaba.tmq.client;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.alibaba.tmq.client.context.ClientContext;
import com.alibaba.tmq.client.system.consumer.Consumer;
import com.alibaba.tmq.client.system.consumer.config.ConsumerConfig;
import com.alibaba.tmq.client.system.consumer.executer.ConsumerExecuter;
import com.alibaba.tmq.client.system.producer.NormalProducer;
import com.alibaba.tmq.client.system.producer.config.ProducerConfig;
import com.alibaba.tmq.client.system.producer.executer.NormalProducerExecuter;
import com.alibaba.tmq.client.system.producer.executer.TransactionProducerExecuter;
import com.alibaba.tmq.client.util.StringUtil;
import com.alibaba.tmq.common.constants.PropertyKeyConstants;
import com.alibaba.tmq.common.domain.ConsumerKey;
import com.alibaba.tmq.common.util.RandomUtil;

/**
 * TMQ工厂
 * @author tianyao.myc
 *
 */
@SuppressWarnings("AlibabaClassNamingShouldBeCamel")
public class TMQFactory extends ClientContext {

	private static final Log logger = LogFactory.getLog(TMQFactory.class);
	
//	/**
//	 * 根据diamond中该key找到topics,消费这批topics的上海消费者均自动下线
//	 */
//	private static final String TMQ_SH_FORBIDDEN_TOPIC = "com.alibaba.tmq.sh.forbidden.topic";
//
//	/**
//	 * 根据diamond中该key找到topics,消费这批topics的上海消费者均自动下线
//	 */
//	private static final String TMQ_ZB_FORBIDDEN_TOPIC = "com.alibaba.tmq.zb.forbidden.topic";
//
//	private static boolean isolated = false;
	
	/** 普通Producer映射表 */
	private static final ConcurrentHashMap> normalProducerTable = 
			new ConcurrentHashMap>();
	
	/** 事务Producer映射表 */
	private static final ConcurrentHashMap> transactionProducerTable = 
			new ConcurrentHashMap>();
	
	/** Consumer映射表 */
	private static final ConcurrentHashMap> consumerTable = 
			new ConcurrentHashMap>();
	
//	private static volatile Set forbiddenTopics = new HashSet();
//
//	private static volatile Set topicsListenedInThisMachine = new HashSet();
	
	/**
	 * 创建普通生产者
	 *  properties
	 *
	 */
	public synchronized static NormalProducer createNormalProducer(Properties properties) {
		
		if(null == properties) {
			throw new RuntimeException("[TMQFactory]: createNormalProducer error, properties is null");
		}
		
		/** 设置各项参数配置 */
		ProducerConfig producerConfig = new ProducerConfig();
		producerConfig.setProducerId(properties.getProperty(PropertyKeyConstants.ProducerId));
		
		if(StringUtil.isBlank(producerConfig.getProducerId())) {
			throw new RuntimeException("[TMQFactory]: createNormalProducer error, ProducerId is empty");
		}
		
		String clusterId = properties.getProperty(PropertyKeyConstants.ClusterId);
		if(StringUtil.isNotBlank(clusterId)) {
			producerConfig.setClusterId(Integer.parseInt(clusterId));
			clientConfig.setClusterId(producerConfig.getClusterId());
		}
		
		String backupClusterId = properties.getProperty(PropertyKeyConstants.BackupClusterId);
		if(StringUtil.isNotBlank(backupClusterId)) {
			clientConfig.setBackupClusterId(Integer.parseInt(backupClusterId));
		}
		
		String produceTimeout = properties.getProperty(PropertyKeyConstants.PRODUCE_TIMEOUT_MS);
		if (StringUtil.isNotBlank(produceTimeout)) {
			clientConfig.setProduceTimeout(Long.valueOf(produceTimeout));
		}
		
		String instanceName = properties.getProperty(PropertyKeyConstants.InstanceName);
		if(StringUtil.isNotBlank(instanceName)) {
			producerConfig.setInstanceName(instanceName);
		}
		
		ConcurrentHashMap producerMap = normalProducerTable.get(producerConfig.getProducerId());
		if(null == producerMap) {
			producerMap = new ConcurrentHashMap();
			normalProducerTable.put(producerConfig.getProducerId(), producerMap);
		}
		
		NormalProducerExecuter producerExecuter = producerMap.get(producerConfig.getInstanceName());
		if(null == producerExecuter) {
			producerExecuter = new NormalProducerExecuter(producerConfig);
			producerMap.put(producerConfig.getInstanceName(), producerExecuter);
		} else {
			throw new RuntimeException("[TMQFactory]: createNormalProducer error"
					+ ", producerId and instanceName is already exists"
					+ ", producerId:" + producerConfig.getProducerId() 
					+ ", instanceName:" + producerConfig.getInstanceName());
		}
		
		return producerExecuter.getProducer();
	}
	
//	/**
//	 * 创建事务生产者
//	 *  properties
//	 *  localTransactionChecker
//	 *
//	 */
//	public synchronized static TransactionProducer createTransactionProducer(Properties properties, LocalTransactionChecker localTransactionChecker) {
//		
//		if(null == properties) {
//			throw new RuntimeException("[TMQFactory]: createTransactionProducer error, properties is null");
//		}
//		
//		//如果localTransactionChecker为空就抛出异常
//		if(null == localTransactionChecker) {
//			throw new RuntimeException("[TMQFactory]: createTransactionProducer error, localTransactionChecker is null");
//		}
//		
//		/** 设置各项参数配置 */
//		ProducerConfig producerConfig = new ProducerConfig();
//		producerConfig.setProducerId(properties.getProperty(PropertyKeyConstants.ProducerId));
//		
//		if(StringUtil.isBlank(producerConfig.getProducerId())) {
//			throw new RuntimeException("[TMQFactory]: createTransactionProducer error, ProducerId is empty");
//		}
//		
//		String clusterId = properties.getProperty(PropertyKeyConstants.ClusterId);
//		if(StringUtil.isNotBlank(clusterId)) {
//			producerConfig.setClusterId(Integer.parseInt(clusterId));
//			clientConfig.setClusterId(producerConfig.getClusterId());
//		}
//		
//		String instanceName = properties.getProperty(PropertyKeyConstants.InstanceName);
//		if(StringUtil.isNotBlank(instanceName)) {
//			producerConfig.setInstanceName(instanceName);
//		}
//		
//		ConcurrentHashMap producerMap = transactionProducerTable.get(producerConfig.getProducerId());
//		if(null == producerMap) {
//			producerMap = new ConcurrentHashMap();
//			transactionProducerTable.put(producerConfig.getProducerId(), producerMap);
//		}
//		
//		TransactionProducerExecuter producerExecuter = producerMap.get(producerConfig.getInstanceName());
//		if(null == producerExecuter) {
//			producerExecuter = new TransactionProducerExecuter(producerConfig, localTransactionChecker);
//			producerMap.put(producerConfig.getInstanceName(), producerExecuter);
//		} else {
//			throw new RuntimeException("[TMQFactory]: createTransactionProducer error"
//					+ ", producerId and instanceName is already exists"
//					+ ", producerId:" + producerConfig.getProducerId() 
//					+ ", instanceName:" + producerConfig.getInstanceName());
//		}
//		
//		return producerExecuter.getProducer();
//	}
	
	/**
	 * 创建消费者
	 *  properties
	 *
	 */
	public synchronized static Consumer createConsumer(Properties properties) {
		
		if(null == properties) {
			throw new RuntimeException("[TMQFactory]: createConsumer error, properties is null");
		}
		
		/** 设置各项参数配置 */
		ConsumerConfig consumerConfig = new ConsumerConfig();
		consumerConfig.setConsumerId(properties.getProperty(PropertyKeyConstants.ConsumerId));
		
		if(StringUtil.isBlank(consumerConfig.getConsumerId())) {
			throw new RuntimeException("[TMQFactory]: createConsumer error, ConsumerId is empty");
		}

		String clusterId = properties.getProperty(PropertyKeyConstants.ClusterId);
		if(StringUtil.isNotBlank(clusterId)) {
			consumerConfig.setClusterId(Integer.parseInt(clusterId));
			clientConfig.setClusterId(consumerConfig.getClusterId());
		}
		
		String backupClusterId = properties.getProperty(PropertyKeyConstants.BackupClusterId);
		if(StringUtil.isNotBlank(backupClusterId)) {
			clientConfig.setBackupClusterId(Integer.parseInt(backupClusterId));
		}
		
		String instanceName = properties.getProperty(PropertyKeyConstants.InstanceName);
		if(StringUtil.isNotBlank(instanceName)) {
			consumerConfig.setInstanceName(instanceName);
		}
		
		ConcurrentHashMap consumerMap = consumerTable.get(consumerConfig.getConsumerId());
		if(null == consumerMap) {
			consumerMap = new ConcurrentHashMap();
			consumerTable.put(consumerConfig.getConsumerId(), consumerMap);
		}
		
		ConsumerExecuter consumerExecuter = consumerMap.get(consumerConfig.getInstanceName());
		if(null == consumerExecuter) {
			consumerExecuter = new ConsumerExecuter(consumerConfig, consumerConfig.getInstanceName());
			consumerMap.put(consumerConfig.getInstanceName(), consumerExecuter);
		} else {
			throw new RuntimeException("[TMQFactory]: createConsumer error"
					+ ", consumerId and instanceName is already exists"
					+ ", consumerId:" + consumerConfig.getConsumerId() 
					+ ", instanceName:" + consumerConfig.getInstanceName());
		}
		
		return consumerExecuter.getConsumer();
	}
	
	/**
	 * 移除普通生产者
	 *  producerId
	 *  instanceName
	 */
	public static void removeNormalProducer(String producerId, String instanceName) {
		
		ConcurrentHashMap producerMap = normalProducerTable.get(producerId);
		if(null == producerMap) {
			return ;
		}
		
		if(StringUtil.isBlank(instanceName)) {
			try {
				normalProducerTable.remove(producerId);
			} catch (Throwable e) {
				logger.error("[TMQFactory]: removeNormalProducer error, producerId:" + producerId, e);
			}
		} else {
			try {
				producerMap.remove(instanceName);
			} catch (Throwable e) {
				logger.error("[TMQFactory]: removeNormalProducer error"
						+ ", producerId:" + producerId 
						+ ", instanceName:" + instanceName, e);
			}
		}
		
	}
	
	/**
	 * 移除事务生产者
	 *  producerId
	 *  instanceName
	 */
	public static void removeTransactionProducer(String producerId, String instanceName) {
		
		ConcurrentHashMap producerMap = transactionProducerTable.get(producerId);
		if(null == producerMap) {
			return ;
		}
		
		if(StringUtil.isBlank(instanceName)) {
			try {
				transactionProducerTable.remove(producerId);
			} catch (Throwable e) {
				logger.error("[TMQFactory]: removeTransactionProducer error, producerId:" + producerId, e);
			}
		} else {
			try {
				producerMap.remove(instanceName);
			} catch (Throwable e) {
				logger.error("[TMQFactory]: removeTransactionProducer error"
						+ ", producerId:" + producerId 
						+ ", instanceName:" + instanceName, e);
			}
		}
	}
	
	/**
	 * 获取事务生产者执行器
	 *  producerId
	 *  instanceName
	 *
	 */
	public static TransactionProducerExecuter aquireTransactionProducerExecuter(String producerId, String instanceName) {
		
		ConcurrentHashMap producerMap = transactionProducerTable.get(producerId);
		if(null == producerMap || producerMap.size() <= 0) {
			return null;
		}
		
		if(StringUtil.isBlank(instanceName)) {
			
			return RandomUtil.getRandomObject4Map(producerMap);
			
		} else {
			return producerMap.get(instanceName);
		}
		
	}
	
	/**
	 * 获取消费者执行器
	 *  consumerKey
	 *  instanceName
	 *
	 */
	public static ConsumerExecuter aquireConsumerExecuter(ConsumerKey consumerKey, String instanceName) {
		
		ConcurrentHashMap consumerMap = consumerTable.get(consumerKey.getConsumerId());
		if(null == consumerMap || consumerMap.size() <= 0) {
			return null;
		}
		
		if(StringUtil.isBlank(instanceName)) {
			
			return RandomUtil.getRandomObject4Map(consumerMap);
			
		} else {
			return consumerMap.get(instanceName);
		}
		
	}
	
	/**
	 * 移除消费者
	 *  consumerId
	 *  instanceName
	 */
	public static void removeConsumer(String consumerId, String instanceName) {
		
		ConcurrentHashMap consumerMap = consumerTable.get(consumerId);
		if(null == consumerMap) {
			return ;
		}
		
		String beforeConsumerMap = consumerMap.toString();
		
		if(StringUtil.isBlank(instanceName)) {
			try {
				consumerTable.remove(consumerId);
			} catch (Throwable e) {
				logger.error("[TMQFactory]: removeConsumer error, consumerId:" + consumerId, e);
			}
		} else {
			try {
				consumerMap.remove(instanceName);
			} catch (Throwable e) {
				logger.error("[TMQFactory]: removeConsumer error"
						+ ", consumerId:" + consumerId 
						+ ", instanceName:" + instanceName, e);
			}
		}
		

		logger.warn("[TMQFactory]: removeConsumer"
				+ ", consumerId:" + consumerId 
				+ ", instanceName:" + instanceName 
				+ ", beforeConsumerMap:" + beforeConsumerMap 
				+ ", afterConsumerMap" + consumerMap);
		
	}
	
	public static ConcurrentHashMap> getNormalproducertable() {
		return normalProducerTable;
	}

	public static ConcurrentHashMap> getTransactionproducertable() {
		return transactionProducerTable;
	}

	public static ConcurrentHashMap> getConsumertable() {
		return consumerTable;
	}
	
	/**
	 * check topic listened by consumers on this machine at init phase
	 * if topic is forbidden, all consumers on this machine will be shutdown
	 * @param topic topic to be checked
	 * @return true is forbidden, otherwise false
	 */
//	public static boolean checkForbiddenTopic(String topic) {
//		boolean isForbidden = false;
//		if (isolated) {
//			//if already isolated, just return true;
//			return true;
//		} else if (forbiddenTopics.contains(topic)) {
//			//if not isolated and forbidden, shutdown all consumers and mark isolated
//			logger.info("[TMQFactory]: topic forbidden check match! topic:" + topic + ", shutdown all consumers...");
//			List allConsumerExecuters = Lists.newArrayList();
//			Collection> consumerExecuters = consumerTable.values();
//			for (ConcurrentHashMap map : consumerExecuters) {
//				allConsumerExecuters.addAll(map.values());
//			}
//			for (ConsumerExecuter consumerExecuter : allConsumerExecuters) {
//				consumerExecuter.getConsumer().shutdown();
//			}
//			logger.info("[TMQFactory]: topic forbidden check match! topic:" + topic + ", shutdown all consumers...");
//			isolated = true;
//			isForbidden = true;
//		} else {
//			//if not isolated and not forbidden, just add topics
//			topicsListenedInThisMachine.add(topic);
//		}
//		return isForbidden;
//	}
	
//	public static boolean isIsolated() {
//		return isolated;
//	}
	
	/**
	 * 监听Diamond配置,为了后面切流
	 */
//	public static void isolateConsumersInit() {
//		boolean isZbMachine = isZbMachine();
//		if (isZbMachine) {
//			logger.info("[TMQFactory]: this machine is zb machine and need isolation, listen zb forbidden topic key:" + TMQ_ZB_FORBIDDEN_TOPIC);
//			addListener(TMQ_ZB_FORBIDDEN_TOPIC);
//		} else {
//			logger.info("[TMQFactory]: this machine is sh machine and need isolation, listen sh forbidden topic key:" + TMQ_SH_FORBIDDEN_TOPIC);
//			addListener(TMQ_SH_FORBIDDEN_TOPIC);
//		}
//
//		//todo:just for test, remove this when make final jar
////		try {
////			String DEFAULT_GROUP = "DEFAULT_GROUP";
////			String value = Diamond.getConfig("com.taobao.taokeeper.tmqZkList", DEFAULT_GROUP, 400);
////			String value1 = Diamond.getConfig("com.alibaba.tmq.serverlist.enable", DEFAULT_GROUP, 400);
////			String value2 = Diamond.getConfig("com.alibaba.tmq.serverlist.log.enable", DEFAULT_GROUP, 400);
////			String value3 = Diamond.getConfig("com.alibaba.tmq.sh.forbidden.topic", DEFAULT_GROUP, 400);
////			StringBuilder sb = new StringBuilder(128);
////			sb.append("com.taobao.taokeeper.tmqZkList:").append(value).append("\n")
////					.append("com.alibaba.tmq.serverlist.enable").append(value1).append("\n")
////					.append("com.alibaba.tmq.serverlist.log.enable").append(value2).append("\n")
////					.append("com.alibaba.tmq.sh.forbidden.topic").append(value3);
////			logger.info("test keys values:\n" + sb.toString());
////		} catch (IOException e) {
////			e.printStackTrace();
////		}
//	}
	
	/**
	 * 检查这台机器是否是张北机房的机器
	 * @return
	 */
//	private static boolean isZbMachine() {
//		boolean isZbMachine = false;
//		String localIp = RemotingUtil.getLocalAddress();
//		logger.info("[TMQFactory]: localIp:" + localIp);
//		List hosts = IPManager.getHostsByIPs(Lists.newArrayList(localIp));
//		if (hosts != null && hosts.size() > 0 && hosts.get(0) != null) {
//			Host localHost = hosts.get(0);
//			String site = localHost.getSite();
//			String unit = localHost.getUnit();
//			logger.info("[TMQFactory]: site:" + site + ", unit:" + unit);
//			isZbMachine = ((site.equalsIgnoreCase("na61") || site.equalsIgnoreCase("na62")) && unit
//					.equalsIgnoreCase("CENTER"));
//		} else {
//			logger.error("[TMQFactory]: can't get host of this machine, localIp:" + localIp);
//		}
//		return isZbMachine;
//	}
//
//	private static void addListener(final String key) {
//		try {
//			String DEFAULT_GROUP = "DEFAULT_GROUP";
//			final String SEPARATOR = ",";
//			String value = Diamond.getConfig(key, DEFAULT_GROUP, 400);
//			if (StringUtils.isNotBlank(value)) {
//				forbiddenTopics = Sets.newHashSet(value.split(SEPARATOR));
//			}
//			logger.info("key:" + key + ", value:" + value);
//			Diamond.addListener(key, DEFAULT_GROUP,
//					new ManagerListenerAdapter() {
//						@Override
//						public void receiveConfigInfo(String configInfo) {
//							logger.warn("diamond config update, dataId=" + key + ", newValue=" + configInfo);
//							if (StringUtils.isBlank(configInfo)) {
//								logger.warn("config is blank.");
//								return;
//							}
//							forbiddenTopics = Sets.newHashSet(configInfo.split(SEPARATOR));
//							checkForbiddenTopics();
//						}
//					});
//			logger.info("add listener success, listen key:" + key);
//		} catch (IOException e) {
//			logger.error("[DiamondUtil]addListener error", e);
//		}
//	}
//
//	/**
//	 * check whether topicsListenedInThisMachine contained in forbidden topics for running phase
//	 * if true, shutdown all consumer, otherwise do nothing.
//	 */
//	private static void checkForbiddenTopics() {
//		Set intersection = Sets.newHashSet(topicsListenedInThisMachine);
//		intersection.retainAll(forbiddenTopics);
//		if (!isolated && !intersection.isEmpty()) {
//			logger.info("[TMQFactory]: topic forbidden check match!" + " shutdown all consumers begins...");
//			List allConsumerExecuters =  Lists.newArrayList();
//			Collection> consumerExecuters = consumerTable.values();
//			for (ConcurrentHashMap map : consumerExecuters) {
//				allConsumerExecuters.addAll(map.values());
//			}
//			for (ConsumerExecuter consumerExecuter : allConsumerExecuters) {
//				consumerExecuter.getConsumer().shutdown();
//			}
//			logger.info("[TMQFactory]: shutdown all consumers success...");
//			isolated = true;
//		}
//	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy