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


}
相关推荐
FrankYoou1 小时前
Jenkins 与 GitLab CI/CD 的核心对比
java·docker
麦兜*1 小时前
Spring Boot启动优化7板斧(延迟初始化、组件扫描精准打击、JVM参数调优):砍掉70%启动时间的魔鬼实践
java·jvm·spring boot·后端·spring·spring cloud·系统架构
KK溜了溜了2 小时前
JAVA-springboot 整合Redis
java·spring boot·redis
天河归来2 小时前
使用idea创建springboot单体项目
java·spring boot·intellij-idea
weixin_478689762 小时前
十大排序算法汇总
java·算法·排序算法
码荼2 小时前
学习开发之hashmap
java·python·学习·哈希算法·个人开发·小白学开发·不花钱不花时间crud
IT_10242 小时前
Spring Boot项目开发实战销售管理系统——数据库设计!
java·开发语言·数据库·spring boot·后端·oracle
ye903 小时前
银河麒麟V10服务器版 + openGuass + JDK +Tomcat
java·开发语言·tomcat
武昌库里写JAVA3 小时前
Oracle如何使用序列 Oracle序列使用教程
java·开发语言·spring boot·学习·课程设计
做题不NG4 小时前
大模型应用开发-LangChain4j
java