RabbitMq 学习使用总结(新手入门)

RabbitMq 学习使用总结

最近真的好忙,忙的一有时间就想休息,只是懒惰的借口吧~

RabbitMq 使用,从头开始

RabbitMq 安装下载(Windows版)

一、RabbitMQ采用 Erlang 语言实现消息队列(MQ)服务器,所以在安装RabbitMQ之前,需要先安装Erlang 开发环境;

二、Erlang 官网:http://www.erlang.org/downloads
在这里插入图片描述
1.选用指定的下载版,下载 exe 文件后运行安装
2.安装后配置环境变量,方便使用

三、Erlang环境安装完后,RabbitMq 官网:https://www.rabbitmq.com/download.html
在这里插入图片描述
四、下载解压后,进入 sbin目录,sbin 目录下有各种的 bat 文件,具体详细内容看官网,
rabbitmq-server.bat 启动服务
如果正确启动后,会是这样的界面
在这里插入图片描述

Starting broker... completed with 0 plugins.

五、目前初始化安装之后是没有任何插件的,rabbitmq 提供了插件包可以安装(启用)插件,比如想要看到界面化的消息队列的接收展示情况(下图),需要开启rabbitmq_management ,
在这里插入图片描述
命令行执行(注意,使用到 sbin 目录下的 rabbitmq-plugins.bat ):

 rabbitmq-plugins enable rabbitmq_management 

然后 访问 localhost:15672 进入页面,
rabbitmq 默认的端口占用是5672,页面是 15672,默认的用户名密码是 guest guest
这样基本很简单的 rabbitmq 服务就搭建起来了。

Java集成 RabbitMq

工作中集成mq主要是在两个服务之间、服务和Jenkins之间进行消息传递。
在 spingboot 框架中集成了对mq 的使用,所以操作是很便捷的,
导入依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

在 application.properties 中做基本配置

# 配置 mq 服务基本信息:ip、端口、用户名、密码
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
# 配置 mq 虚拟主机
spring.rabbitmq.virtual-host=/
# 请求心跳超时时间,0为不指定,不指定时间单位默认为 秒
spring.rabbitmq.requested-heartbeat=3
# 启用发布确认消息
spring.rabbitmq.publisher-confirm-type=correlated
# 启用发布失败确认消息
spring.rabbitmq.publisher-returns=true
# 连接服务器超时时间,单位毫秒 0 为永不超时
spring.rabbitmq.connection-timeout=5000
# 启用发送重拾、重拾请求次数
spring.rabbitmq.template.retry.enabled=true
spring.rabbitmq.template.retry.max-attempts=3
spring.rabbitmq.template.mandatory=true
#设置手动消息确认
spring.rabbitmq.listener.simple.acknowledge-mode=manual

在代码中创建了 RabbitMqConfig 类做基本的配置

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@Slf4j
public class RabbitMqConfig {
    @Bean
    public RabbitTemplate initRabbitTemplate(ConnectionFactory connectionFactory){
        RabbitTemplate rabbittemplate = new RabbitTemplate();
        rabbittemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        rabbittemplate.setConnectionFactory(connectionFactory);
        // 消息发送成功的处理,correlationData是当前消息的唯一id,b值为消息是否成功收到,s为失败的原因
        rabbittemplate.setConfirmCallback((((correlationData, b, s) -> 
                log.info("meaasge {} send success!,back {},error {}",correlationData,b,s))));
        //消息发送失败的处理
        rabbittemplate.setReturnsCallback((returnedMessage -> {
            log.error("message {} send to exchange {} ,router {}, error {} ,callback_code {}",
                    returnedMessage.getMessage(),returnedMessage.getExchange(),
                    returnedMessage.getRoutingKey(),returnedMessage.getReplyText(),returnedMessage.getReplyCode()
            );
        }));
        return rabbittemplate;
    }
    
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory){
        SimpleRabbitListenerContainerFactory simpleRabbitListener = new SimpleRabbitListenerContainerFactory();
        simpleRabbitListener.setConnectionFactory(connectionFactory);
        simpleRabbitListener.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        return simpleRabbitListener;
    }

	// 建立交换机,有多种类型:topic、direct、fanout、headers四种类型
	@Bean
    public Exchange setExchange(){
        return ExchangeBuilder.topicExchange("test_exchange").build();
    }
    // 建立队列
    @Bean
    public Queue setQueue(){
        return QueueBuilder.durable("test_queue").build();
    }
    //绑定
    @Bean
    public Binding setBinding(Exchange exchange,Queue queue){
        return BindingBuilder.bind(queue).to(exchange).with("test_routkey").noargs();
    }
}

那至于如何监听到消息做任务处理呢?
springboot 很好的集成了 此操作,我使用的方式是通过注解 @RabbitListener 监听

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;	

	/**
     * 监听某一条队列,可以监听多条噢
     * @param msg   消息实体内容,可以用json 格式解析
     * @param message Message 载体,携带消息的元数据信息
     * @param channel 管道,理解为可以用于通信
     */
	@RabbitListener(queues = "test_queue")
    public void task1(String msg, Message message, Channel channel){
        long deliveryTag = 0;
        try {
        	// 这是传递 消息的 id,在一个队列中,id值是递增的,以此来表示消息的唯一性
            deliveryTag = message.getMessageProperties().getDeliveryTag();
            System.out.println(msg);
            // 如果接收成功,给消息队列返回相应信息,表示消息接收成功,你可以从队列中移除了
            channel.basicAck(deliveryTag,false);
        } catch (IOException e) {
            try {
            	// 如果消息接收过程中出现异常,返回接收失败,看队列的消息处理机制,是直接删除还是回到队列,等待下次接收
                channel.basicNack(deliveryTag,false,false);
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
            e.printStackTrace();
        }
    }

如何发消息呢?这是最简单的发送消息的方式,使用我们上边配置好的 RabbitTemplate 实现消息的发送,此类中包含多个重载方法,可以根据具体情况选择使用。

	@Autowired
    private RabbitTemplate rabbitTemplate;	

	public void send(){
        String msg = "hello";
        // 发送到指定交换机中的指定队列,队列是通过 routkey 匹配的
        rabbitTemplate.convertAndSend("test_exchange","test_routkey",
                msg
        );
    }

一些基本的认识

mq 基本框架
rabbitmq 基于AMQP ( Advanced Message Queuing Protocol)高级消息队列协议
生产者 publisher 将消息发送到 代理 broker 中,也就是队列中,消费者会监听指定的队列,如果队列中有消息了,会从队列中发送给消费者,如果成功发送,队列中的消息删除,此次生产-消费完成,如果发送失败,会有机制设置直接丢弃还是保存在队列中,保存的时间多长等。
一个 broker 中包含多个队列,生产者和消费者能够传递消息是通过指定的 路由 route 确定的,生产者和消费者需要记录相同的路由 key 才能保证消息的正确性。而对队列的关系的消息的转发机制需要有 exchange 交换机管理,一个交换机可以管理多条队列。
对于交换机,有四种数据分发方式: topic、direct、fanout、headers

  • Topic:主题:一个队列与主题类型的交换机绑定时,可以在绑定键中使用通配符
  • direct:直连交换机会把消息路由到那些 BindingKey 和 RoutingKey完全匹配的队列中
  • fanout:(广播)交换机会把所有发送到该交换器的消息路由到所有与该交换器绑定的队列中
  • headers:头交换机 不依赖于路由键的匹配规则来路由消息,而是根据发送的消息内容中的 headers 属性进行 匹配
    其实对于具体的含义,元数据内容的解析,官网更为精准,网上资料也是很多,就不做个人阐述了。

mq 消息队列的特点就是:削锋、异步、解耦

一些多余的话,哈哈
在工作使用的过程中就是体现了 mq 的异步和解耦作用,我们的项目是启动一个较长的分析过程,分析结束后会有一段比较长的时间处理分析数据
使用 mq,一是接收分析结束的消息,开启数据分析任务1,处理数据
二是 分析任务1 结束后,发送给融合任务2,融合任务2接收到消息对数据进行融合
三是 数据融合完成后 发送消息到界面,实现实时刷新,数据展示
等到任务1结束后,发送到消息给消息队列,任务1 就可以休息了(执行其他 build 去),任务2 不需实时紧跟着就分析,等任务2处于在线时,或者监听到任务1的结束消息就可以执行了,实现了异步和解耦。
但是,在客户现场部署时,由于客户现场的局限性,他们在内网环境中开发,而且环境设施比较老旧,所以客户希望在部署时能够一键部署,加入 mq 后我们需要启动多个服务,虽然写了脚本实现一键部署,但是从部署工作量来说,显得削微复杂了些
只是简单的集成操作,存在不足的地方,望改进,希望有机会能够更深入的研究和使用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值