@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. 强化学习笔记之【SAC算法】

    强化学习笔记之[SAC算法] 前言: 本文为强化学习笔记第四篇,第一篇讲的是Q-learning和DQN,第二篇DDPG,第三篇TD3 TD3比DDPG少了一个target_actor网络,其它地方有 ...

  2. 云原生周刊:Kubernetes v1.27 发布 | 2023.4.17

    开源项目推荐 Palaemon Palaemon 是一个开源开发工具,用于监控 Kubernetes 集群的健康状况和资源指标并分析内存不足 (OOMKill) 错误. Gitkube Gitkube ...

  3. 记一次pip/pip3安装uwsgi报错

    背景 本来是想着在centos 7.9的主机上面部署一个flask应用,采用的方式是linux+nginx+uwsgi来进行发布,其他的都没有问题,但是在使用pip安装uwsgi时报错了,安装不成功, ...

  4. JavaScript初始化对象数组

    一.{} 我们都知道JavaScript的数据结构是松散的,比如说你定义一个变量 var temp; 那么你可以随手这样定义temp.attr1 =  "参数1",因为对于Java ...

  5. SDUT 2021 Autumn Team Contest 36th G - Alice’s Stamps(补)

    队友做出的这个题,赛后补的=.= G - Alice's Stamps (一般DP) 题目大意 :给你m个区间,选k个,求k个区间并集 1≤T≤100 1≤K≤M 1≤N,M≤2000 1≤Li≤ R ...

  6. Git命令缩写

    g = 'git' ga = 'git add' gaa='git add --all' gapa='git add --patch' gb='git branch' gba='git branch ...

  7. 《JVM第7课》堆区

    1.概念 堆是JVM中最重要的一块区域,JVM规范中规定所有的对象和数组都应该存放在堆中,在执行字节码指令时,会把创建的对象存入堆中,对象的引用地址存入虚拟机栈的栈帧中.不过当方法执行完之后,刚刚所创 ...

  8. 为什么需要[EnumeratorCancellation]?

    为什么需要 [EnumeratorCancellation]? 在使用 C# 编写异步迭代器时,您可能会遇到如下警告: warning CS8425: 异步迭代器"TestConversat ...

  9. php 异步并行

    如果你有一批数据需要调用远程接口处理,而远程接口处理时间很长,比如需要1秒左右,那10条数据就是10秒,你的程序就要10S才能结束,而这样的话一旦接口提供方有点问题,就需要20秒 30秒甚至更久,这样 ...

  10. Solon(Spring 的替代方案)最近半年下载量突破 1200万!

    不断突破 2023年04月,单月破100万(Maven 中央仓库单月下载量) 2023年06月,单月破200万 2023年11月,单月破250万 2024年11月,最近半年下载量突破 1200万 So ...