@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的更多相关文章

  1. 46.ActiveMQ开篇(Hello World、安全认证、Connection、Session、MessageProducer、MessageConsumer)

    要给有能力的人足够的发挥空间,公司可以养一些能力平平甚至是混日子的人,但绝不能让这些人妨碍有能力的人,否则这样的环境不留也罢. 一.背景介绍 CORBA\DCOM\RMI等RPC中间件技术已经广泛应用 ...

  2. Java消息队列--ActiveMq 实战

    1.下载安装ActiveMQ ActiveMQ官网下载地址:http://activemq.apache.org/download.html ActiveMQ 提供了Windows 和Linux.Un ...

  3. Java消息队列--JMS概述

    1.什么是JMS JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送 ...

  4. (jms)ActiveMQ 安装配置.

    前言 ActiveMQ他是Apache出品的一个JMS提供者,管理会话和队列,运行在JVM下,支持多种语言,如JAVA,C++,C#,应用协议: OpenWire,Stomp REST,WS Noti ...

  5. ActiveMQ消息队列的使用及应用

    这里就不说怎么安装了,直接解压出来就行了. 谢绝转载,作者保留所有权力 目录:  一:JMQ的两种消息模式 1.1:点对点的消息模式 1.2:订阅模式 二:点对点的实现代码 2.1:点对点的发送端 2 ...

  6. ActiveMQ(li)

    一.ActiveMQ 首先,ActiveMQ不是一个框架,它不是struct,webx,netty这种框架,它更像是tomcat服务器,因为你使用它之前必须启动它,activeMQ和JMS的关系有点类 ...

  7. ActiveMQ笔记(1):编译、安装、示例代码

    一.编译 虽然ActiveMQ提供了发布版本,但是建议同学们自己下载源代码编译,以后万一有坑,还可以尝试自己改改源码. 1.1 https://github.com/apache/activemq/r ...

  8. ActiveMQ入门实例Demo

    前面我们已经搭建和配置好了ActiveMQ,下面来看一个Demo,体验一下MQ. JMS 消息模型 JMS消息服务应用程序结构支持两种模型:点对点模型,发布者/订阅者模型. (1)点对点模型(Queu ...

  9. ActiveMQ入门

    ActiveMQ简介 概要 开源 JMS-compliant 消息中间件message-oriented middleware(MOM) 松耦合,相对于RPC的紧耦合 发送消息fire-and-for ...

  10. ActiveMQ中的Destination高级特性(一)

    ---------------------------------------------------------------------------------------- Destination ...

随机推荐

  1. torch和numpy的相互转换

    import torch x = torch.rand(2,2) x1 = x.numpy() # torch转换到numpy x2 = torch.from_numpy(x1) #numpy转换to ...

  2. 016 Python 中的基本运算符

    #!/usr/bin/env python # -*- coding:utf-8 -*- # Datatime:2022/7/28 15:01 # Filename:016 Python 中的基本运算 ...

  3. 【转】sqlplus/RMAN/lsnrctl 等工具连接缓慢

    AIX上sqlplus /as sysdba rman target / 或者lsnrctl start时或者通过sqlplus system/oracle@orcl这样通过监听连接等方式来登陆时非常 ...

  4. KubeSphere 在直播应用中的实践

    本文是上海站 Meetup 讲师唐明根据其分享内容整理的文章. 引言 目前媒体的主流传播渠道已从传统的报纸.广播.电视转向了互联网,各种视频及社交 App 成为了人们获取资讯的首选途径.苏州市广播电视 ...

  5. KubeSphere 社区双周报 | OpenFunction 发布 v1.1.1 | 2023.6.9-6.22

    KubeSphere 社区双周报主要整理展示新增的贡献者名单和证书.新增的讲师证书以及两周内提交过 commit 的贡献者,并对近期重要的 PR 进行解析,同时还包含了线上/线下活动和布道推广等一系列 ...

  6. KubeSphere Cloud 月刊|灾备支持 K8s 1.22+,轻量集群支持安装灾备和巡检组件

    功能升级 备份容灾服务支持 K8s v1.22+ 版本集群 随着 Kubernetes 近一年频繁的发版.升级,越来越多的用户开始部署并使用高版本的 Kubernetes 集群.备份容灾服务支持 Ku ...

  7. css flex布局的使用

    felx弹性布局 display:flex; 属性值 flex-direction 属性定义容器要在哪个方向上堆叠 flex 项目.默认为水平方向 row, column 值设置垂直方向.如:flex ...

  8. mysql重置id排列重新排序

    1.删除表中的原有的主键字段 ALTER TABLE table2 DROP id 2.表中重新创建一个字段 ALTER TABLE table2 ADD id int NOT NULL FIRST; ...

  9. 每日学学Java开发规范,编程规约(附阿里巴巴Java开发手册(终极版))

    前言 每次去不同的公司,码不同的代码,适应不同的规范,经常被老大教育规范问题,我都有点走火入魔的感觉,还是要去看看阿里巴巴Java开发规范,从中熟悉一下,纠正自己,码出高效,码出质量. 想细看的可以去 ...

  10. 题解:洛谷P1119 灾后重建

    题解:洛谷P1119 灾后重建 题目传送门 前言:没有掌握floyed求最短路的精髓是每次增加选一个中转点,导致写了2h才勉强卡过 法1:最暴力的想法就是开个三维数组把前i个点的dis状态全部存下来, ...