@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. 【PyTorch】state_dict详解

    这篇博客来自csdn,完全用于学习. Introduce 在pytorch中,torch.nn.Module模块中的state_dict变量存放训练过程中需要学习的权重和偏执系数,state_dict ...

  2. 2022年最新数据库经典面试题及答案汇总(含PostgreSQL、Oracle、MySQL)

    随着企业数字化需求的增加,数据库行业发展日益壮大,企业对DBA岗位的需求也处于逐步增加中.我们梳理了墨天轮平台上2022年最新的一批数据库经典面试题,主要包含PostgreSQL.MySQL和Orac ...

  3. .Net 中带有 ? 的运算符

    // 带 ? 的表达式 // 1. 三元表达式 // 2. ?? 双问号 // obj1 ?? obj2 如果 obj1 为 空(null) 返回 obj2 // Configure the HTTP ...

  4. .Net 使用JWT验证接口

    // jwt 的生成和接口的验证 // 需要使用的包 // 1. System.IdentityModel.Tokens.Jwt 生成 Token的 // 2. Microsoft.AspNetCor ...

  5. 封装JWT - 生成 jwt 和解析 jwt

    1. ASP.NET Core 身份验证和授权验证的功能由Authentication,Authorization中间件提供 :app.UseAuthentication(),app.UseAutho ...

  6. 谈一谈 vuex 的运行机制

    Vuex提供数据(state)来驱动视图(vue components),通过dispath派发actions,在其中可以做一些异步的操作,然后通过commit来提交mutations,最后mutat ...

  7. 016 Python 中的基本运算符

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

  8. 15 Transformer 框架概述

    博客配套视频链接: https://space.bilibili.com/383551518?spm_id_from=333.1007.0.0 b 站直接看 配套 github 链接:https:// ...

  9. 5.15 相约上海!2021 年度首届云原生 Meetup | KubeSphere & Friends

    时至今日,Kubernetes 虽然变成了云原生这套系统化方法论和开源技术的核心一环,但已经无法独立存在,而是与云原生生态中所有的技术形态息息相关.为了将云原生生态中的各个技术形态结合起来,帮助企业最 ...

  10. costmap代价地图

    1 什么是costmap代价地图 在机器人进行路径规划时,我们需要明白规划算法是依靠什么在地图上来计算出来一条路径的.依靠的是gmapping扫描构建的一张环境全局地图,但是仅仅依靠一张原始的全局地图 ...