动态注册卸载RabbitMq队列和监听

  • 需求: 需求中会有插件的动态安装和卸载,需求需要安装一个插件动态的创建(初始化MQ的队列),并同时对初始化的队列设置MQ的消费监听,卸载一个插件的时候会动态删除MQ的队列,并卸载掉MQ的队列的消费监听

  • 创建MQ队列使用RabbitAdmin

  • MQ的消费监听动态手动注册bean,一个消费监听注册一个新的bean,就是多个不同的MQ队列消费是不同的bean,这样做有利于MQ消费的速率,都是一个bean消费所有的MQ队列,消费速率提不上去。

  • MQ的配置类

java 复制代码
@Slf4j
@Configuration
public class RabbitMqConfig implements BeanFactoryAware {

    @Resource
    private ConnectionFactory connectionFactory;
    private DefaultListableBeanFactory beanFactory;


    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        if (beanFactory instanceof DefaultListableBeanFactory) {
            this.beanFactory = (DefaultListableBeanFactory) beanFactory;
        }
    }

    @Bean
    public RabbitAdmin rabbitAdmin() {
        RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
        rabbitAdmin.setAutoStartup(true);
        return rabbitAdmin;
    }

    @Bean
    @ConditionalOnMissingBean(MessageConverter.class)
    public MessageConverter messageConverter() {
        return new Jackson2JsonMessageConverter();
    }

   @Bean
    DirectExchange pluginExchange() {
        return new DirectExchange("plugin-queue-exchange");
    }

}
  • MQ队列的初始化,卸载类
typescript 复制代码
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.stereotype.Service;
import webber.aiservice.processer.mq.entity.RabbitMq;
import webber.aiservice.processer.mq.listener.PluginQueueListener;

import javax.annotation.Resource;


@Service
@Slf4j
public class PluginQueueService implements BeanFactoryAware {
    @Resource
    private RabbitAdmin rabbitAdmin;

    @Resource
    private DirectExchange pluginExchange;

    @Resource
    private ConnectionFactory connectionFactory;
    
    private DefaultListableBeanFactory beanFactory;
    
    @Resource
    private PluginQueueListener pluginQueueListener;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        if (beanFactory instanceof DefaultListableBeanFactory) {
            this.beanFactory = (DefaultListableBeanFactory) beanFactory;
        }
    }


    /**
     * 初始化队列、交换机、监听
     *
     * @param queueName    队列名称
     * @param key          绑定KEY
     * @author leixiaohong
     */
    public void initMq(String queueName, String key) {
        //自动初始化监听
        registerListener(queueName, key);
    }

    /**
     * 删除队列和交换机
     *
     * @param queueName 队列名称
     * @author leixiaohong
     */
    public void deleteMq(String queueName, String routingKey) {

        //删除监听
        removeListener(queueName, routingKey);
        deleteQueue(queueName);
    }



    /**
     * 初始化队列
     *
     * @author leixiaohong
     */
    private void registerListener(String queueName, String routingKey) {
        Queue queue = QueueBuilder.durable(queueName).build();
        rabbitAdmin.declareExchange(pluginExchange);
        rabbitAdmin.declareQueue(queue);
        rabbitAdmin.declareBinding(BindingBuilder.bind(queue).to(pluginExchange).with(routingKey));
        
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.setQueueNames(queueName);
        container.setMessageListener(pluginQueueListener);
        container.setPrefetchCount(5);
        container.setConcurrentConsumers(5);
        container.setMaxConcurrentConsumers(10);
        container.initialize();
        container.start();
        this.beanFactory.registerSingleton(queueName + routingKey, container);
        log.info("MQ队列初始化中>>>>>>>>RabbitMQ create new Queue '" + queueName + "' in '" + ExchangeTypes.DIRECT  + "' with '" + routingKey + "'");
    }
    

    /**
     * 卸载监听
     *
     * @param queueName 队列名称
     * @author leixiaohong
     */
    private void removeListener(String queueName, String routingKey) {
        SimpleMessageListenerContainer listenerContainer = beanFactory.getBean(queueName + routingKey, SimpleMessageListenerContainer.class);
        listenerContainer.shutdown();
        ////销毁bean
        this.beanFactory.destroySingleton(queueName + routingKey);

    }

    /**
     * 删除队列
     *
     * @param queueName 队列名称
     * @author leixiaohong
     */
    private void deleteQueue(String queueName) {
        QueueInformation queueInfo = rabbitAdmin.getQueueInfo(queueName);
        if (queueInfo != null) {
            rabbitAdmin.deleteQueue(queueName);
        }
    }

    /**
     * 删除交换机
     *
     * @param exchangeName 交换机
     * @author leixiaohong
     */
    private void deleteExchange(String exchangeName) {
        rabbitAdmin.deleteQueue(exchangeName);
    }


}
  • MQ的监听类
java 复制代码
import cn.hutool.core.convert.Convert;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageListener;
import org.springframework.stereotype.Component;
import webber.aiservice.processer.engine.plugin.bus.ProcessBus;
import webber.aiservice.processer.engine.plugin.manager.ProcessManagerHelper;
import webber.aiservice.processer.plugin.PluginDesc;
import webber.aiservice.processer.plugin.SourceContent;
import webber.aiservice.processer.plugin.util.JacksonUtil;

import java.nio.charset.StandardCharsets;

/**
 * 监听方法类
 **/
@Slf4j
@Component
public class PluginQueueListener implements MessageListener {
    @Override
    public void onMessage(Message message) {
        try {
            String msg = new String(message.getBody(), StandardCharsets.UTF_8);
            log.info("msg:{}",msg)
        } catch (Exception e) {
            log.error("mq处理异常:{}, 插件信息: {}", ExceptionUtils.getStackTrace(e), pluginId);
        }
    }


}
相关推荐
java_heartLake几秒前
设计模式之建造者模式
java·设计模式·建造者模式
G皮T几秒前
【设计模式】创建型模式(四):建造者模式
java·设计模式·编程·建造者模式·builder·建造者
niceffking5 分钟前
JVM HotSpot 虚拟机: 对象的创建, 内存布局和访问定位
java·jvm
菜鸟求带飞_8 分钟前
算法打卡:第十一章 图论part01
java·数据结构·算法
骆晨学长24 分钟前
基于springboot的智慧社区微信小程序
java·数据库·spring boot·后端·微信小程序·小程序
AskHarries29 分钟前
利用反射实现动态代理
java·后端·reflect
@月落30 分钟前
alibaba获得店铺的所有商品 API接口
java·大数据·数据库·人工智能·学习
liuyang-neu35 分钟前
力扣 42.接雨水
java·算法·leetcode
z千鑫39 分钟前
【人工智能】如何利用AI轻松将java,c++等代码转换为Python语言?程序员必读
java·c++·人工智能·gpt·agent·ai编程·ai工具
王彬泽40 分钟前
【RabbitMQ】重试机制、TTL
rabbitmq·ttl·重试机制