MessageConsumer
@Slf4j
@Component
public class MessageConsumer {
@Autowired
private PpcRequestMessageListener ppcRequestMessageListener; @Autowired
private RabbitTemplate rabbitTemplate; @Autowired
private MessageConverter messageConverter; @Value("${app.rabbitmq.schedule.queue.ppc-request}")
private String ppcRequestQueue; private ExecutorService executor = new ThreadPoolExecutor(1, 4, 60, TimeUnit.SECONDS,
new SynchronousQueue<>(), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy()); public void start() {
Executors.newSingleThreadExecutor().execute(() -> {
try {
while (true) {
ChannelCallbackImpl<PpcRequestMessage> callback = new ChannelCallbackImpl<>(ppcRequestQueue, 4);
List<PpcRequestMessage> list = rabbitTemplate.execute(callback);
if (list == null || list.isEmpty()) {
TimeUnit.MILLISECONDS.sleep(1000);
}
}
} catch (Exception e) {
log.error("MessageConsumer handle error", e);
}
});
} private class ChannelCallbackImpl<T> implements ChannelCallback<List<T>> {
private final MessagePropertiesConverter messagePropertiesConverter = new DefaultMessagePropertiesConverter(); private final String queueName; private final int maxCount; public ChannelCallbackImpl(String queueName, int maxCount) {
this.queueName = queueName;
this.maxCount = maxCount;
} @Override
public List<T> doInRabbit(Channel channel) throws Exception {
GetResponse response = channel.basicGet(queueName, false);
if(response == null){
return null;
}
//如果没有空闲进程,睡眠直至有可用线程
Integer tid = getSetIdleTid(); int total = response.getMessageCount() + 1;
if(total > maxCount){
total = maxCount;
} long[] tags = new long[total];
List<T> messages = new ArrayList<>(total); for (int i = 0; i < total; i++) {
MessageProperties props = messagePropertiesConverter.toMessageProperties(response.getProps(), response.getEnvelope(), "UTF-8");
if (response.getMessageCount() >= 0) {
props.setMessageCount(response.getMessageCount());
}
Message message = new Message(response.getBody(), props);
T t = (T) messageConverter.fromMessage(message);
messages.add(t);
tags[i] = response.getEnvelope().getDeliveryTag();
response = channel.basicGet(queueName, false);
} //accept
for (int i = 0; i < messages.size(); i++) {
executor.execute(new ConsumerAcceptRunnable(tid, channel, tags[i], messages.get(i)));
tid = getSetIdleTid();
} //ack
for (long tag : tags){
channel.basicAck(tag, false);
}
return messages;
} private Integer getSetIdleTid() throws Exception {
Integer tid = PpcProcessStatus.getSetIdleTid();
while (tid == null) {
log.info("ppc process has no idle thread, sleep");
TimeUnit.MILLISECONDS.sleep(500);
continue;
}
return tid;
} public class ConsumerAcceptRunnable implements Runnable{
private final Integer tid;
private final Channel channel;
private final long tag;
private final T t; public ConsumerAcceptRunnable(Integer tid, Channel channel, long tag, T t) {
this.tid = tid;
this.channel = channel;
this.tag = tag;
this.t = t;
} @Override
public void run() {
try {
ppcRequestMessageListener.handleMessage(tid, t);
} catch (Exception e) {
log.error("accept message error {}", t, e);
try {
channel.basicNack(tag, false, true);
} catch (Exception ioe) {
log.error("basicNack error", ioe);
}
}
}
}
}
}
MessageConsumer的更多相关文章
- 46.ActiveMQ开篇(Hello World、安全认证、Connection、Session、MessageProducer、MessageConsumer)
要给有能力的人足够的发挥空间,公司可以养一些能力平平甚至是混日子的人,但绝不能让这些人妨碍有能力的人,否则这样的环境不留也罢. 一.背景介绍 CORBA\DCOM\RMI等RPC中间件技术已经广泛应用 ...
- Java消息队列--ActiveMq 实战
1.下载安装ActiveMQ ActiveMQ官网下载地址:http://activemq.apache.org/download.html ActiveMQ 提供了Windows 和Linux.Un ...
- Java消息队列--JMS概述
1.什么是JMS JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送 ...
- (jms)ActiveMQ 安装配置.
前言 ActiveMQ他是Apache出品的一个JMS提供者,管理会话和队列,运行在JVM下,支持多种语言,如JAVA,C++,C#,应用协议: OpenWire,Stomp REST,WS Noti ...
- ActiveMQ消息队列的使用及应用
这里就不说怎么安装了,直接解压出来就行了. 谢绝转载,作者保留所有权力 目录: 一:JMQ的两种消息模式 1.1:点对点的消息模式 1.2:订阅模式 二:点对点的实现代码 2.1:点对点的发送端 2 ...
- ActiveMQ(li)
一.ActiveMQ 首先,ActiveMQ不是一个框架,它不是struct,webx,netty这种框架,它更像是tomcat服务器,因为你使用它之前必须启动它,activeMQ和JMS的关系有点类 ...
- ActiveMQ笔记(1):编译、安装、示例代码
一.编译 虽然ActiveMQ提供了发布版本,但是建议同学们自己下载源代码编译,以后万一有坑,还可以尝试自己改改源码. 1.1 https://github.com/apache/activemq/r ...
- ActiveMQ入门实例Demo
前面我们已经搭建和配置好了ActiveMQ,下面来看一个Demo,体验一下MQ. JMS 消息模型 JMS消息服务应用程序结构支持两种模型:点对点模型,发布者/订阅者模型. (1)点对点模型(Queu ...
- ActiveMQ入门
ActiveMQ简介 概要 开源 JMS-compliant 消息中间件message-oriented middleware(MOM) 松耦合,相对于RPC的紧耦合 发送消息fire-and-for ...
- ActiveMQ中的Destination高级特性(一)
---------------------------------------------------------------------------------------- Destination ...
随机推荐
- 说一下tcp三次握手
1. 客户端发送syn请求连接 : 2. 服务器检验syn,然后发送syn和ack确认连接: 3. 客户端接收ack和syn,然后发送ack建立连接 :
- Android复习(二)应用资源 --> 动画
没什么好总结的 复制自 https://developer.android.google.cn/guide/topics/resources/animation-resource 有需要的可以查看官方 ...
- HTB打靶记录-Infiltrator
nmap scan nmap -A 10.10.11.31 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-10-15 13:18 CST Nma ...
- Python面向对象小备忘
最近学到面向对象了,感觉到Python这方面的语法也有点神奇,这里专门归纳一下Python面向对象中我觉得比较重要的笔记. 本文目前有的内容:实例属性和类属性的访问,使用@property修饰器 实例 ...
- 工作中的技术总结_ form表单使用注意事项之form触发后台提交事件 _20220127
工作中的技术总结_ form表单使用注意事项之form触发后台提交事件 _20220127 如无必要不要使用 form标签 来作为组件的父节点 事件过程: 项目使用的是 spring + jsp 的框 ...
- BeautifulSoup优化测试报告
一.是什么 Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库. 中文官方文档:https://beautifulsoup.readthedocs.io/zh_C ...
- [离线计算-Spark|Hive] HDFS小文件处理
背景 HDFS 小文件过多会对hadoop 扩展性以及稳定性造成影响, 因为要在namenode 上存储维护大量元信息. 大量的小文件也会导致很差的查询分析性能,因为查询引擎执行查询时需要进行太多次文 ...
- k8s集群环境下kubesphere部署
安装kubernetes 1.环境配置 每个机器使用内网ip互通 每个机器配置自己的hostname,不能用localhost 所有机器均操作 #设置每个机器自己的hostname hostnamec ...
- 记录个Java/Groovy的小问题:空字符串调用split函数返回非空数组
问题复现 最近写了一个groovy替换程序增量流水线脚本(会Java也能看懂),示意脚本如下: //获取文件列表方法 def listFiles(folder) { def output = sh(s ...
- ubuntu如何安装redis
在终端下输入 sudo apt search redis 查找一下发现了 redis-server 如果找不到 你可能需要使用 update 更新一下了 sudo apt-get update 然后就 ...