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

com.alibaba.tmq.client.system.producer.implement.DefaultNormalProducer Maven / Gradle / Ivy

package com.alibaba.tmq.client.system.producer.implement;

import java.util.List;

import com.alibaba.tmq.common.exception.IsolationException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.alibaba.tmq.client.TMQFactory;
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.ProducerExecuter;
import com.alibaba.tmq.client.util.StringUtil;
import com.alibaba.tmq.common.constants.Constants;
import com.alibaba.tmq.common.context.InvocationContext;
import com.alibaba.tmq.common.domain.KeyValuePair;
import com.alibaba.tmq.common.domain.Message;
import com.alibaba.tmq.common.domain.MessageStatus;
import com.alibaba.tmq.common.domain.MessageType;
import com.alibaba.tmq.common.domain.remoting.ConnectionChannel;
import com.alibaba.tmq.common.domain.result.*;
import com.alibaba.tmq.common.exception.TMQClientException;
import com.alibaba.tmq.common.exception.TMQException;
import com.alibaba.tmq.common.exception.TMQServerException;
import com.alibaba.tmq.common.service.ServerService;
import com.alibaba.tmq.common.util.ListUtil;
import com.alibaba.tmq.common.util.LoggerUtil;
import com.alibaba.tmq.common.util.MessageUtil;
import com.taobao.eagleeye.EagleEye;

/**
 * 默认普通生产者
 * @author tianyao.myc
 *
 */
public class DefaultNormalProducer extends DefaultProducer implements NormalProducer, Constants {

	private static final Log logger = LogFactory.getLog(DefaultNormalProducer.class);
	
	/** 服务端基础服务 */
	private final ServerService serverService = clientRemoting.proxyInterface(ServerService.class);
	
	/** 各项参数配置 */
	private final ProducerConfig producerConfig;
	
	private final ProducerExecuter producerExecuter;
	
	public DefaultNormalProducer(ProducerConfig producerConfig, ProducerExecuter producerExecuter) {
		
		super(producerConfig, producerExecuter);
		
		this.producerConfig = producerConfig;
		this.producerExecuter = producerExecuter;
	}
	
	/**
	 * 提交消息
	 */
	@Override
	public SubmitResult submit(Message message) throws TMQException, IsolationException {
		if (clientRemoting.isIsolated()) {
			throw new IsolationException("producer has been isolated!!!");
		}

		if(! this.producerExecuter.isStart()) {
			throw new TMQClientException("producer has just create, not start");
		}
		
		long startTime = System.currentTimeMillis();
		
		try {
			//重置参数,防止用户设置参数导致系统运行错误
			if(StringUtil.isNotBlank(clientConfig.getBackupDomainName())) {
				MessageUtil.reset(message, clientConfig.getBackupClusterId());
			} else {
				MessageUtil.reset(message, clientConfig.getClusterId());
			}
		} catch (Throwable e) {
			throw new TMQClientException(e);
		}
		
		//检查消息是否正确
		Result checkResult = null;
		try {
			checkResult = MessageUtil.checkMessage(new MessageUtil(), message);
		} catch (Throwable e) {
			throw new TMQClientException(e);
		}
		
		if(! checkResult.getData().booleanValue()) {
			
			LoggerUtil.info(message, "[TMQ-CLIENT-PRODUCER]-submit-single-check-failed", startTime
					, clientConfig.getLocalAddress());//消息跟踪埋点
			
			return new SubmitResult(checkResult);
		}
		
		//渲染消息
		KeyValuePair messageKeyValue = MessageUtil.renderingMessage(
				this.producerConfig.getProducerId(), message, MessageStatus.READY_TO_FIRE, MessageType.NORMAL_ONCE);
		
		/** 获取该消息要触发的那台Server */
		String server = clientRemoting.acquireFireServer(message.getMessageKey());
		if(StringUtil.isBlank(server)) {
			
			LoggerUtil.info(message, "[TMQ-CLIENT-PRODUCER]-submit-single-server-failed", startTime
					, clientConfig.getLocalAddress());//消息跟踪埋点
			
			throw new TMQServerException(ResultCode.SERVER_ERROR.getInformation());
		}
		
		//提交消息到server
		Result result = submit(message, server);
		
		//如果发送到触发机器失败就往别的机器发送直到尝试完所有机器
		if(null == result) {
			
			List serverList = clientRemoting.getServerListForProducer();
			
			if(StringUtil.isNotBlank(clientConfig.getBackupDomainName())) {
				serverList = clientRemoting.getbackupServerListForProducer();
			}
			
			if(ListUtil.isEmpty(serverList)) {
				
				LoggerUtil.info(message, "[TMQ-CLIENT-PRODUCER]-submit-single-server-empty", startTime
						, clientConfig.getLocalAddress());//消息跟踪埋点
				
				throw new TMQServerException(ResultCode.SERVER_ERROR.getInformation());
			}
			
			//循环尝试其他服务器
			for(String otherServer : serverList) {
				
				//提交消息到其他server
				result = submit(message, otherServer);
				if(result != null) {
					break ;//如果有返回结果就退出循环
				}
			}
		}

		if(null == result) {
			
			LoggerUtil.info(message, "[TMQ-CLIENT-PRODUCER]-submit-single-result-failed", startTime
					, clientConfig.getLocalAddress());//消息跟踪埋点
			
			throw new TMQClientException(ResultCode.TIMEOUT.getInformation());
		}
		
		LoggerUtil.info(message, "[TMQ-CLIENT-PRODUCER]-submit-single-" + result, startTime
				, clientConfig.getLocalAddress());//消息跟踪埋点
		
		if(ResultCode.CONNECTION_PRODUCER_IS_NULL_ERROR.equals(result.getResultCode())) {
			throw new TMQServerException(ResultCode.CONNECTION_PRODUCER_IS_NULL_ERROR.getInformation());
		}
		
		return new SubmitResult(result.getData(), result.getResultCode(), messageKeyValue);
	}
	
	/**
	 * 提交消息
	 *  message
	 *  server
	 *
	 */
	private Result submit(Message message, String server) {
		
		Result result = null;
		try {
			ConnectionChannel connectionChannel = new ConnectionChannel(server, ROLE_TYPE_PRODUCER, this.producerConfig.getProducerId());
			connectionChannel.setTimeout(clientConfig.getProduceTimeout());
			InvocationContext.setConnectionChannel(connectionChannel);
			result = serverService.submit(message);
		} catch (Throwable e) {
			logger.error("[DefaultNormalProducer]: submit message error"
					+ ", message:" + message 
					+ ", server:" + server, e);
		}
		
		return result;
	}

	/**
	 * 发送非事物消息
	 */
	public SendResult send(Message message) throws TMQException, IsolationException{
		if (clientRemoting.isIsolated()) {
			throw new IsolationException("producer has been isolated!!!");
		}
		
		if(! this.producerExecuter.isStart()) {
			throw new TMQClientException("producer has just create, not start");
		}
		
		long startTime = System.currentTimeMillis();
		
		try {
			//重置参数,防止用户设置参数导致系统运行错误
			if(StringUtil.isNotBlank(clientConfig.getBackupDomainName())) {
				MessageUtil.reset(message, clientConfig.getBackupClusterId());
			} else {
				MessageUtil.reset(message, clientConfig.getClusterId());
			}
		} catch (Throwable e) {
			throw new TMQClientException(e);
		}
		
		//检查消息是否正确
		Result checkResult = null;
		try {
			checkResult = MessageUtil.check4Send(message);
		} catch (Throwable e) {
			throw new TMQClientException(e);
		}
		
		if(! checkResult.getData().booleanValue()) {
			
			LoggerUtil.info(message, "[TMQ-CLIENT-PRODUCER]-send-single-check-failed", startTime
					, clientConfig.getLocalAddress());//消息跟踪埋点
			
			return new SendResult(checkResult);
		}
		
		//渲染消息
		KeyValuePair messageKeyValue = MessageUtil.renderingMessage(
				this.producerConfig.getProducerId(), message, MessageStatus.READY_TO_FIRE, MessageType.NORMAL_ONCE);
		
		/** 获取该消息要触发的那台Server */
		String server = clientRemoting.acquireFireServer(message.getMessageKey());
		if(StringUtil.isBlank(server)) {
			
			LoggerUtil.info(message, "[TMQ-CLIENT-PRODUCER]-send-single-server-failed", startTime
					, clientConfig.getLocalAddress());//消息跟踪埋点
			
			throw new TMQServerException(ResultCode.SERVER_ERROR.getInformation());
		}

		//全链路压测标记打入
		if (EagleEye.getUserData("t")!=null){
			if(EagleEye.getUserData("t").equals("1")){
				message.setTb_eagleeyex_t("1");
				logger.warn("[DefaultNormalProducer]: set tb_eagleeyex_t, message:" + message);
			}
		}

		//发送消息到server
		Result result = send(message, server);
		
		//如果发送到触发机器失败就往别的机器发送直到尝试完所有机器
		if(null == result) {
			
			List serverList = clientRemoting.getServerListForProducer();
			
			if(StringUtil.isNotBlank(clientConfig.getBackupDomainName())) {
				serverList = clientRemoting.getbackupServerListForProducer();
			}
			
			if(ListUtil.isEmpty(serverList)) {
				
				LoggerUtil.info(message, "[TMQ-CLIENT-PRODUCER]-send-single-server-empty", startTime
						, clientConfig.getLocalAddress());//消息跟踪埋点
				
				throw new TMQServerException(ResultCode.SERVER_ERROR.getInformation());
			}
			
			//循环尝试其他服务器
			for(String otherServer : serverList) {
				
				//发送消息到其他server
				result = send(message, otherServer);
				if(result != null) {
					break ;//如果有返回结果就退出循环
				}
			}
		}
		
		if(null == result) {
			
			LoggerUtil.info(message, "[TMQ-CLIENT-PRODUCER]-send-single-result-failed", startTime
					, clientConfig.getLocalAddress());//消息跟踪埋点
			
			throw new TMQClientException(ResultCode.TIMEOUT.getInformation());
		}
		
		LoggerUtil.info(message, "[TMQ-CLIENT-PRODUCER]-send-single-" + result, startTime
				, clientConfig.getLocalAddress());//消息跟踪埋点
		
		if(ResultCode.CONNECTION_PRODUCER_IS_NULL_ERROR.equals(result.getResultCode())) {
			throw new TMQServerException(ResultCode.CONNECTION_PRODUCER_IS_NULL_ERROR.getInformation());
		}
		
		return new SendResult(result.getData(), result.getResultCode(), messageKeyValue);
	}
	
	/**
	 * 发送消息到server
	 *  message
	 *  server
	 *
	 */
	private Result send(Message message, String server) {
		
		Result result = null;
		try {
			ConnectionChannel connectionChannel = new ConnectionChannel(server, ROLE_TYPE_PRODUCER, this.producerConfig.getProducerId());
			connectionChannel.setTimeout(clientConfig.getProduceTimeout());
			InvocationContext.setConnectionChannel(connectionChannel);
			result = serverService.send(message);
		} catch (Throwable e) {
			logger.error("[DefaultNormalProducer]: send message error, message:" + message, e);
		}
		
		return result;
	}

	/**
	 * 批量提交消息
	 */
	@Override
	public SubmitResult submit(List messageList) throws TMQException, IsolationException {
		if (clientRemoting.isIsolated()) {
			throw new IsolationException("producer has been isolated!!!");
		}

		if(! this.producerExecuter.isStart()) {
			throw new TMQClientException("producer has just create, not start");
		}

		long startTime = System.currentTimeMillis();

		try {
			//重置参数,防止用户设置参数导致系统运行错误
			if(StringUtil.isNotBlank(clientConfig.getBackupDomainName())) {
				MessageUtil.reset(messageList, clientConfig.getBackupClusterId());
			} else {
				MessageUtil.reset(messageList, clientConfig.getClusterId());
			}
		} catch (Throwable e) {
			throw new TMQClientException(e);
		}

		//检查消息是否正确
		Result checkResult = null;
		try {
			checkResult = MessageUtil.checkMessage(new MessageUtil(), messageList);
		} catch (Throwable e) {
			throw new TMQClientException(e);
		}
		
		if(! checkResult.getData().booleanValue()) {
			
			LoggerUtil.info(messageList, "[TMQ-CLIENT-PRODUCER]-submit-mulit-check-failed", startTime
					, clientConfig.getLocalAddress());//消息跟踪埋点
			
			return new SubmitResult(checkResult);
		}

		//渲染消息列表
		List> messageKeyValueList = MessageUtil.rendering(
				this.producerConfig.getProducerId(), messageList, MessageStatus.READY_TO_FIRE, MessageType.NORMAL_ONCE);
		
		/** 获取该消息要触发的那台Server */
		String server = clientRemoting.acquireFireServer(messageList.get(0).getMessageKey());
		if(StringUtil.isBlank(server)) {
			
			LoggerUtil.info(messageList, "[TMQ-CLIENT-PRODUCER]-submit-mulit-server-failed", startTime
					, clientConfig.getLocalAddress());//消息跟踪埋点
			
			throw new TMQServerException(ResultCode.SERVER_ERROR.getInformation());
		}
		
		//提交批量消息到server
		Result result = submit(messageList, server);
		
		//如果提交到触发机器失败就往别的机器提交直到尝试完所有机器
		if(null == result) {
			
			List serverList = clientRemoting.getServerListForProducer();
			
			if(StringUtil.isNotBlank(clientConfig.getBackupDomainName())) {
				serverList = clientRemoting.getbackupServerListForProducer();
			}
			
			if(ListUtil.isEmpty(serverList)) {
				
				LoggerUtil.info(messageList, "[TMQ-CLIENT-PRODUCER]-submit-mulit-server-empty", startTime
						, clientConfig.getLocalAddress());//消息跟踪埋点
				
				throw new TMQServerException(ResultCode.SERVER_ERROR.getInformation());
			}
			
			//循环尝试其他服务器
			for(String otherServer : serverList) {
				
				//提交消息到其他server
				result = submit(messageList, otherServer);
				if(result != null) {
					break ;//如果有返回结果就退出循环
				}
			}
		}
		
		if(null == result) {
			
			LoggerUtil.info(messageList, "[TMQ-CLIENT-PRODUCER]-submit-mulit-result-failed", startTime
					, clientConfig.getLocalAddress());//消息跟踪埋点
			
			throw new TMQClientException(ResultCode.TIMEOUT.getInformation());
		}
		
		LoggerUtil.info(messageList, "[TMQ-CLIENT-PRODUCER]-submit-mulit-" + result, startTime
				, clientConfig.getLocalAddress());//消息跟踪埋点
		
		if(ResultCode.CONNECTION_PRODUCER_IS_NULL_ERROR.equals(result.getResultCode())) {
			throw new TMQServerException(ResultCode.CONNECTION_PRODUCER_IS_NULL_ERROR.getInformation());
		}
		
		return new SubmitResult(result.getData(), result.getResultCode(), messageKeyValueList);
	}
	
	/**
	 * 批量提交消息到server
	 *  messageList
	 *  server
	 *
	 */
	public Result submit(List messageList, String server) {
		
		Result result = null;
		try {
			ConnectionChannel connectionChannel = new ConnectionChannel(server, ROLE_TYPE_PRODUCER, this.producerConfig.getProducerId());
			connectionChannel.setTimeout(clientConfig.getProduceTimeout());
			InvocationContext.setConnectionChannel(connectionChannel);
			result = serverService.submit(messageList);
		} catch (Throwable e) {
			logger.error("[DefaultNormalProducer]: submit messageList error"
					+ ", messageList:" + messageList 
					+ ", server:" + server, e);
		}
		
		return result;
	}

	/**
	 * 批量发送非事物消息
	 */
	public SendResult send(List messageList) throws TMQException, IsolationException {
		if (clientRemoting.isIsolated()) {
			throw new IsolationException("producer has been isolated!!!");
		}
		
		if(! this.producerExecuter.isStart()) {
			throw new TMQClientException("producer has just create, not start");
		}

		long startTime = System.currentTimeMillis();
		
		try {
			//重置参数,防止用户设置参数导致系统运行错误
			if(StringUtil.isNotBlank(clientConfig.getBackupDomainName())) {
				MessageUtil.reset(messageList, clientConfig.getBackupClusterId());
			} else {
				MessageUtil.reset(messageList, clientConfig.getClusterId());
			}
		} catch (Throwable e) {
			throw new TMQClientException(e);
		}

		//检查消息是否正确
		Result checkResult = null;
		try {
			checkResult = MessageUtil.check4Send(messageList);
		} catch (Throwable e) {
			throw new TMQClientException(e);
		}
		
		if(! checkResult.getData().booleanValue()) {
			
			LoggerUtil.info(messageList, "[TMQ-CLIENT-PRODUCER]-send-mulit-check-failed", startTime
					, clientConfig.getLocalAddress());//消息跟踪埋点
			
			return new SendResult(checkResult);
		}
		
		//渲染消息列表
		List> messageKeyValueList = MessageUtil.renderingMessage(
				this.producerConfig.getProducerId(), messageList, MessageStatus.READY_TO_FIRE, MessageType.NORMAL_ONCE);
		
		/** 获取该消息要触发的那台Server */
		String server = clientRemoting.acquireFireServer(messageList.get(0).getMessageKey());
		if(StringUtil.isBlank(server)) {
			
			LoggerUtil.info(messageList, "[TMQ-CLIENT-PRODUCER]-send-mulit-server-failed", startTime
					, clientConfig.getLocalAddress());//消息跟踪埋点
			
			throw new TMQServerException(ResultCode.SERVER_ERROR.getInformation());
		}
		
		//发送批量消息到server
		Result result = send(messageList, server);

		//如果发送到触发机器失败就往别的机器发送直到尝试完所有机器
		if(null == result) {
			
			List serverList = clientRemoting.getServerListForProducer();
			
			if(StringUtil.isNotBlank(clientConfig.getBackupDomainName())) {
				serverList = clientRemoting.getbackupServerListForProducer();
			}
			
			if(ListUtil.isEmpty(serverList)) {
				
				LoggerUtil.info(messageList, "[TMQ-CLIENT-PRODUCER]-send-mulit-server-empty", startTime
						, clientConfig.getLocalAddress());//消息跟踪埋点
				
				throw new TMQServerException(ResultCode.SERVER_ERROR.getInformation());
			}
			
			//循环尝试其他服务器
			for(String otherServer : serverList) {
				
				//发送消息到其他server
				result = send(messageList, otherServer);
				if(result != null) {
					break ;//如果有返回结果就退出循环
				}
			}
		}
		
		if(null == result) {
			
			LoggerUtil.info(messageList, "[TMQ-CLIENT-PRODUCER]-send-mulit-result-failed", startTime
					, clientConfig.getLocalAddress());//消息跟踪埋点
			
			throw new TMQClientException(ResultCode.TIMEOUT.getInformation());
		}
		
		LoggerUtil.info(messageList, "[TMQ-CLIENT-PRODUCER]-send-mulit-" + result, startTime
				, clientConfig.getLocalAddress());//消息跟踪埋点
		
		if(ResultCode.CONNECTION_PRODUCER_IS_NULL_ERROR.equals(result.getResultCode())) {
			throw new TMQServerException(ResultCode.CONNECTION_PRODUCER_IS_NULL_ERROR.getInformation());
		}
		
		return new SendResult(result.getData(), result.getResultCode(), messageKeyValueList);
	}
	
	/**
	 * 发送批量消息到server
	 *  messageList
	 *  server
	 *
	 */
	private Result send(List messageList, String server) {
		
		Result result = null;
		try {
			ConnectionChannel connectionChannel = new ConnectionChannel(server, ROLE_TYPE_PRODUCER, this.producerConfig.getProducerId());
			connectionChannel.setTimeout(clientConfig.getProduceTimeout());
			InvocationContext.setConnectionChannel(connectionChannel);
			result = serverService.send(messageList);
		} catch (Throwable e) {
			logger.error("[DefaultNormalProducer]: send messageList error, messageList:" + messageList, e);
		}
		
		return result;
	}
	
	/**
	 * 批量更新消息
	 */
	public UpdateResult update(List messageList) throws TMQException, IsolationException {
		if (clientRemoting.isIsolated()) {
			throw new IsolationException("producer has been isolated!!!");
		}
		
		if(! this.producerExecuter.isStart()) {
			throw new TMQClientException("producer has just create, not start");
		}
		
		long startTime = System.currentTimeMillis();
		
		try {
			//重置参数,防止用户设置参数导致系统运行错误
			if(StringUtil.isNotBlank(clientConfig.getBackupDomainName())) {
				MessageUtil.reset(messageList, clientConfig.getBackupClusterId());
			} else {
				MessageUtil.reset(messageList, clientConfig.getClusterId());
			}
		} catch (Throwable e) {
			throw new TMQClientException(e);
		}

		//检查消息是否正确
		Result checkResult = null;
		try {
			checkResult = MessageUtil.check4Send(messageList);
		} catch (Throwable e) {
			throw new TMQClientException(e);
		}
		
		if(! checkResult.getData().booleanValue()) {
			
			LoggerUtil.info(messageList, "[TMQ-CLIENT-PRODUCER]-update-mulit-check-failed", startTime
					, clientConfig.getLocalAddress());//消息跟踪埋点
			
			return new UpdateResult(checkResult);
		}
		
		//渲染消息列表
		List> messageKeyValueList = MessageUtil.renderingMessage(
				this.producerConfig.getProducerId(), messageList, MessageStatus.READY_TO_FIRE, MessageType.NORMAL_ONCE);
		
		//批量更新消息
		UpdateResult updateResult = super.updateMessageList(messageList);
		
		updateResult.setMessageKeyValueList(messageKeyValueList);
		
		LoggerUtil.info(messageList, "[TMQ-CLIENT-PRODUCER]-update-mulit-" + updateResult, startTime
				, clientConfig.getLocalAddress());//消息跟踪埋点
		
		if(ResultCode.CONNECTION_PRODUCER_IS_NULL_ERROR.equals(updateResult.getResultCode())) {
			throw new TMQServerException(ResultCode.CONNECTION_PRODUCER_IS_NULL_ERROR.getInformation());
		}
		
		return updateResult;
	}
	
	/**
	 * 关闭
	 */
	public void shutdown() {

		//设置Producer状态为停止
		this.producerExecuter.setStart(false);
		
		//移除普通生产者
		TMQFactory.removeNormalProducer(this.producerConfig.getProducerId(), this.producerConfig.getInstanceName());
		
		/** 断开连接 */
		try {
			clientRemoting.removeConnection(producerConfig.getInstanceName(), 
					ROLE_TYPE_PRODUCER, this.producerConfig.getProducerId(), NULL, NULL);
		} catch (Throwable e) {
			logger.error("[DefaultNormalProducer]: shutdown removeConnection error"
					+ ", clientConfig:" + clientConfig 
					+ ", producerConfig:" + producerConfig, e);
		}
		
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy