wang.moshu.message.AbstarctMessageHandler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mt-framework Show documentation
Show all versions of mt-framework Show documentation
message-trunk is a lightweight high performance message bus (queue) based on redis.
The newest version!
package wang.moshu.message;
import javax.annotation.PostConstruct;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.TaskRejectedException;
/**
* 消息监听器
*
* @author dingxiangyong 2016年7月28日 下午2:12:08
*/
public abstract class AbstarctMessageHandler implements Runnable
{
private static Log logger = LogFactory.getLog(AbstarctMessageHandler.class);
@Autowired
protected MessageTrunk messageTrunk;
/**
* 初始化启动本监听器
*/
@PostConstruct
public void startListen()
{
// 启动监听
new Thread(this).start();
}
@Autowired
private RedisUtil redisUtil;
/**
* 监听的消息类型
*/
private String messageType;
/**
* 消息的class对象
*/
private Class clazz;
private boolean monitor;
// 默认为3
private int retryTimes = 3;
public AbstarctMessageHandler(String messageType, Class clazz, int retryTimes)
{
this.messageType = messageType;
this.clazz = clazz;
this.retryTimes = 3;
}
public AbstarctMessageHandler(String messageType, Class clazz)
{
this.messageType = messageType;
this.clazz = clazz;
}
public void run()
{
while (true)
{
listen();
}
}
/**
* 监听消息
*/
@SuppressWarnings("unchecked")
public void listen()
{
// 阻塞获取redis列表值
final Object obj = redisUtil.blpop(messageType, Integer.MAX_VALUE, Message.class);
// 如果获取失败,以为着redis连接有问题
if (obj == null)
{
monitor = false;
logger.warn("消息分发器获取redis连接失败");
// 暂停5秒钟,防止线程空跑,打印无数日志
try
{
Thread.sleep(5000);
}
catch (InterruptedException e)
{
logger.warn("消息分发器线程暂停失败");
}
return;
}
if (!monitor)
{
logger.warn("消息分发开始");
monitor = true;
}
try
{
messageTrunk.getThreadPool().submit(new Runnable()
{
public void run()
{
Message message = (Message) obj;
try
{
// 如果获取成功,则交给子类做业务处理
handle((T) message.getContent());
}
catch (Exception ex)
{
logger.error(ex);
// 处理失败,判断是否需要重试
if (message.getFailTimes().intValue() >= retryTimes)
{
handleFailed((T) message.getContent());
}
else
{
message.setFailTimes(message.getFailTimes().intValue() + 1);
// 再次put回消息总线,等待下次重试
messageTrunk.put(message);
if (logger.isDebugEnabled())
{
StringBuilder sb = new StringBuilder();
sb.append("msg:[").append(message).append("], 执行失败,准备重试。");
logger.debug(sb.toString());
}
}
}
}
});
}
catch (TaskRejectedException ex)
{
logger.warn("线程池已满,准备回写任务,暂停本线程");
// 如果发生任务拒绝加入线程池,则回写任务到redis,等待重试
messageTrunk.put((Message) obj);
// 暂停指定时间
try
{
Thread.sleep(messageTrunk.getThreadPoolFullSleepSeconds() * 1000);
}
catch (InterruptedException e)
{
logger.warn("生产者暂停异常", ex);
}
}
catch (Exception ex)
{
logger.error("消息总线发生异常", ex);
}
}
/**
* 获取到消息后做业务处理
*/
public abstract void handle(T obj);
/**
* 消息多次重试处理失败
*/
public abstract void handleFailed(T obj);
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy