package com.easyooo.framework.support.rocketmq;
import static org.springframework.util.Assert.notNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import com.alibaba.fastjson.JSON;
import com.alibaba.rocketmq.client.producer.DefaultMQProducer;
import com.alibaba.rocketmq.client.producer.SendResult;
import com.alibaba.rocketmq.client.producer.SendStatus;
import com.alibaba.rocketmq.common.message.Message;
import com.easyooo.framework.support.redis.RedisTemplate;
import com.easyooo.framework.support.transaction.RemoteSenderOrderly;
/**
* JMS消息发送器,依赖 DefaultMQProducer
*
* @author Killer
*/
public class RocketMQSender implements RemoteSenderOrderly<Message>, InitializingBean{
Logger logger = LoggerFactory.getLogger(getClass());
private static final String PROVIDER_NAME = "ROCKETMQ";
@Autowired(required = true)
private DefaultMQProducer producer;
static final String DEFAULT_RMQ_ERROR_QUEUE = "__rmqErrorQueue";
private String rmqErrorQueueKey = DEFAULT_RMQ_ERROR_QUEUE;
private RedisTemplate redisTemplate;
/** 容错标记, 标记为true时,发送失败则发送至redis队列 */
private boolean needFaultTolerant = false;
public RocketMQSender(){
}
public RocketMQSender(DefaultMQProducer producer){
this.producer = producer;
}
@Override
public boolean send(Message data) throws Exception {
if(data == null){
return false;
}
try{
SendResult sr = producer.send(data);
if(sr.getSendStatus() != SendStatus.SEND_OK){
logger.warn(String.format("Message(%s) has been sent successfully, but send status is %s.",
data.getTopic(), sr.getSendStatus()));
}
}catch(Exception e){
if(needFaultTolerant){
putInErrorQueue(data);
}
throw e;
}
return true;
}
/**
* 将消息发送至错误消息队列
*/
protected void putInErrorQueue(Message msg){
String msgString = JSON.toJSONString(msg);
redisTemplate.rpush(rmqErrorQueueKey, msgString);
logger.warn("消息{}发送至RMQ失败,已rpush至{}缓存", msgString, rmqErrorQueueKey);
}
@Override
public void afterPropertiesSet() throws Exception {
notNull(producer, "Property 'producer' is required");
if(needFaultTolerant){
notNull(redisTemplate, "Property 'redisTemplate' is required");
}
}
@Override
public String getProviderInfo() {
return PROVIDER_NAME;
}
public void setRmqErrorQueueKey(String rmqErrorQueueKey) {
this.rmqErrorQueueKey = rmqErrorQueueKey;
}
public void setRedisTemplate(RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
public void setNeedFaultTolerant(boolean needFaultTolerant) {
this.needFaultTolerant = needFaultTolerant;
}
}