动态注册卸载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);
        }
    }


}
相关推荐
测开小菜鸟6 分钟前
使用python向钉钉群聊发送消息
java·python·钉钉
P.H. Infinity1 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq
生命几十年3万天1 小时前
java的threadlocal为何内存泄漏
java
caridle1 小时前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express
^velpro^1 小时前
数据库连接池的创建
java·开发语言·数据库
苹果醋31 小时前
Java8->Java19的初步探索
java·运维·spring boot·mysql·nginx
秋の花2 小时前
【JAVA基础】Java集合基础
java·开发语言·windows
小松学前端2 小时前
第六章 7.0 LinkList
java·开发语言·网络
Wx-bishekaifayuan2 小时前
django电商易购系统-计算机设计毕业源码61059
java·spring boot·spring·spring cloud·django·sqlite·guava
customer082 小时前
【开源免费】基于SpringBoot+Vue.JS周边产品销售网站(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·java-ee·开源