Rabbitmq

Rabbitmq

rabbitmq安装

​ docker 安装 rabbitmq

  • 下载镜像

docker pull rabbitmq:3.7.7-management

  • 启动镜像(用户名和密码设置为 guest guest)
docker run -dit --name rabbitmq3.8.0 -e RABBITMQ_DEFAULT_USER=guest -e RABBITMQ_DEFAULT_PASS=guest -p 15672:15672 -p 5672:5672 rabbitmq:3.8.0-management

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KvmoLAsy-1652499874763)(…\up-9de29c6b93228b96111a601d377264d053e.webp)]

docker 安装 rabbitMQ 延时队列插件(delayed_message_exchange)

    1. 查找 Docker 容器中的 RabbitMQ 镜像

    docker ps -a

[root@linux ~]# docker ps -a
CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS              PORTS                                                                                        NAMES
8efd6f3add3c        chenchuxin/dubbo-admin   "catalina.sh run"        6 weeks ago         Up 5 weeks          0.0.0.0:9090->8080/tcp                                                                       dubbo-admin
6939b83d0942        zookeeper                "/docker-entrypoint.…"   6 weeks ago         Up 5 weeks                                                                                                       zookeeper01
2aec2548a9f8        525bd2016729             "docker-entrypoint.s…"   6 weeks ago         Up 5 weeks          0.0.0.0:27017->27017/tcp                                                                     docker_mongodb
    1. 上传 /opt/rabbitmq_delayed_message_exchange-3.8.0.ez 插件到 Linux 文件夹中
    1. 拷贝插件文件到 rabbitMQ 的 Docker 容器中
[root@linux ~]# docker cp opt/rabbitmq_delayed_message_exchange-3.8.0.ez rabbitmq3.8.0:/plugins
    1. 进入 rabbitMQ 的 Docker 容器中 docker exec -it rabbitmq3.8.0 bash
[root@linux ~]# docker exec -it rabbitmq3.8.0 bash
root@myRabbit:/# 
    1. 查看插件列表
rabbitmq-plugins list
    1. 启用插件
rabbitmq-plugins enable rabbitmq_delayed_message_exchange
    1. 创建交换器

    请添加图片描述
    请添加图片描述

请添加图片描述

rabbitmq基本原理

RabbitMQ:我们通常谈到消息队列,就会联想到这其中的三者:生产者、消费者和消息队列,生产者将消息发送到消息队列,消费者从消息队列中获取消息进行处理。对于RabbitMQ,它在此基础上做了一层抽象,引入了交换器exchange的概念,交换器是作用于生产者和消息队列之间的中间桥梁,它起了一种消息路由的作用,也就是说生产者并不和消息队列直接关联,而是先发送给交换器,再由交换器路由到对应的队列,至于它是根据何种规则路由到消息队列的,就是我们下面需要介绍的内容了。这里的生产者并没有直接将消息发送给消息队列,而是通过建立与Exchange(交换器)的Channel(信道),将消息发送给Exchange,Exchange根据路由规则,将消息转发给指定的消息队列。消息队列储存消息,等待消费者取出消息,消费者通过建立与消息队列相连的Channel,从消息队列中获取消息。

AMQP:Advanced Message Queue,高级消息队列协议。它是应用层协议的一个开放标准,为面向消息的中间件设计,基于此协议的客户端与消息中间件可传递消息,并不受产品、开发语言等条件的限制。

rabbitmq代码实现

rabbitmq客户端

1、交换器构造器的创建

/**
 * 交换器构造器
 * @author: lzp
 * @date: 2022/5/10 13:31
 * @description:
 */
public class DelayExchangeBuilder {
    /**
     * 默认延迟消息交换器
     */
    public final static  String DEFAULT_DELAY_EXCHANGE = "secp.delayed.exchange";
    /**
     * 普通交换器
     */
    public final static  String DELAY_EXCHANGE = "secp.direct.exchange";

    /**
     * 构建延迟消息交换器
     * @return
     */
    public static CustomExchange buildExchange() {
        Map<String, Object> args = new HashMap<String, Object>();
        args.put("x-delayed-type", "direct");
        return new CustomExchange(DEFAULT_DELAY_EXCHANGE, "x-delayed-message", true, false, args);
    }

    /**
     * 构建默认消息交换器
     * @return
     */
    public static CustomExchange buildDefaultExchange() {
        return new CustomExchange(DELAY_EXCHANGE, ExchangeTypes.DIRECT, true, false);
    }
}

2、发送默认消息并且创建队列绑定队列

/**
 * 消息队列客户端
 */
@Slf4j
@Configuration
public class RabbitMqClient {

    private static final Logger logger = LoggerFactory.getLogger(RabbitMqClient.class);

    private final RabbitAdmin rabbitAdmin;

    private final RabbitTemplate rabbitTemplate;


    @Resource
    private SimpleMessageListenerContainer messageListenerContainer;

    @Resource
    BusProperties busProperties;
    @Resource
    private ApplicationEventPublisher publisher;


    @Resource
    private ApplicationContext applicationContext;


    @Bean
    public void initQueue() {
        Map<String, Object> beansWithRqbbitComponentMap = this.applicationContext.getBeansWithAnnotation(RabbitComponent.class);
        Class<? extends Object> clazz = null;
        for (Map.Entry<String, Object> entry : beansWithRqbbitComponentMap.entrySet()) {
            log.info("初始化队列............");
            //获取到实例对象的class信息
            clazz = entry.getValue().getClass();
            Method[] methods = clazz.getMethods();
            RabbitListener rabbitListener = clazz.getAnnotation(RabbitListener.class);
            if (ObjectUtil.isNotEmpty(rabbitListener)) {
                createQueue(rabbitListener);
            }
            for (Method method : methods) {
                RabbitListener methodRabbitListener = method.getAnnotation(RabbitListener.class);
                if (ObjectUtil.isNotEmpty(methodRabbitListener)) {
                    createQueue(methodRabbitListener);
                }
            }

       
    }


    private Map sentObj = new HashMap<>();


    @Autowired
    public RabbitMqClient(RabbitAdmin rabbitAdmin, RabbitTemplate rabbitTemplate) {
        this.rabbitAdmin = rabbitAdmin;
        this.rabbitTemplate = rabbitTemplate;
    }




    /**
     * 发送普通消息
     *
     * @param queueName 队列名称
     * @param params    消息内容map
     */
    public void sendMessage(String queueName, Object params) {
        log.info("发送消息到mq");
        try {
            Queue queue = new Queue(queueName);
            addQueue(queue);
            CustomExchange customExchange = DelayExchangeBuilder.buildDefaultExchange();
            rabbitAdmin.declareExchange(customExchange);
            Binding binding = BindingBuilder.bind(queue).to(customExchange).with(queueName).noargs();
            rabbitAdmin.declareBinding(binding);
            messageListenerContainer.setQueueNames(queueName);
            rabbitTemplate.convertAndSend(DelayExchangeBuilder.DELAY_EXCHANGE, queueName, params, message -> {
                return message;
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }




    public RabbitMqClient put(String key, Object value) {
        this.sentObj.put(key, value);
        return this;
    }

    /**
     * 延迟发送消息
     *
     * @param queueName  队列名称
     * @param params     消息内容params
     * @param expiration 延迟时间 单位毫秒
     */
    public void sendMessage(String queueName, Object params, Integer expiration) {
        this.send(queueName, params, expiration);
    }

    private void send(String queueName, Object params, Integer expiration) {
        Queue queue = new Queue(queueName);
        addQueue(queue);
        CustomExchange customExchange = DelayExchangeBuilder.buildExchange();
        rabbitAdmin.declareExchange(customExchange);
        Binding binding = BindingBuilder.bind(queue).to(customExchange).with(queueName).noargs();
        rabbitAdmin.declareBinding(binding);
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        log.debug("发送时间:" + sf.format(new Date()));
        messageListenerContainer.setQueueNames(queueName);
/*        messageListenerContainer.setMessageListener(new MqListener<Message>() {
            @Override
            public void onMessage(Message message, Channel channel) {
                MqListener messageListener = SpringContextHolder.getHandler(queueName + "Listener", MqListener.class);
                if (ObjectUtil.isNotEmpty(messageListener)) {
                    messageListener.onMessage(message, channel);
                }
            }
        });*/
        rabbitTemplate.convertAndSend(DelayExchangeBuilder.DEFAULT_DELAY_EXCHANGE, queueName, params, message -> {
            if (expiration != null && expiration > 0) {
                message.getMessageProperties().setHeader("x-delay", expiration);
            }
            return message;
        });
    }



}
3、发送消息

/**
 * @ClassName
 * @Author lzp
 * @Date 2022/5/16 15:15
 * @Version 1.0
 **/
public class dome {
    @Resource
    private RabbitMqClient rabbitMqClient;

    @Test
    public  void test01(){
        //发送普通消息
        BaseMap map = new BaseMap();
        map.put("orderId", RandomUtil.randomNumbers(10));
        rabbitMqClient.sendMessage("testReceiver2", map);
    }

    @Test
    public  void test02(){
        //发送延迟 例如死队列到点消费 这里发送时间的延迟
        BaseMap map = new BaseMap();
        map.put("orderId", RandomUtil.randomNumbers(10));
        rabbitMqClient.sendMessage("testReceiver2", map,1000*60);
    }
}
4、消费消息


/**
 * (@RabbitListener声明类上,一个类只能监听一个队列)
 */
@Slf4j
@RabbitListener(queues = SecpDataConstant.SECP_DATA_SYNC)
@RabbitComponent(value = "testReceiver2")
public class TestReceiver2 extends BaseRabbiMqHandler<BaseMap> {

    @RabbitHandler
    public void onMessage(BaseMap baseMap, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) {
        super.onMessage(baseMap, deliveryTag, channel, new MqListener<BaseMap>() {
            @Override
            public void handler(BaseMap map, Channel channel) {
                //业务处理
                String orderId = map.get(SecpDataConstant.SECP_DATA_USER_INFO).toString();
                log.info("MQ Receiver2,orderId : " + orderId);
            }
        });
    }

}






  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值