RabbitMQ基础介绍与在java中使用-入门「建议收藏」

2022-11-10 11:34:06 浏览数 (2)

大家好,又见面了,我是你们的朋友全栈君。

前言:MQ做应用解耦,流量削峰 这些是常识,RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)。RabbitMQ服务器是用Erlang语言编写的,而集群和故障转移是构建在开放电信平台框架上的。所有主要的编程语言均有与代理接口通讯的客户端库 常用的主流的MQ有四个 ActiveMQ: Apache下的一个子项目。使用Java完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现,少量代码就可以高效地实现高级应用场景。可插拔的传输协议支持,比如:in-VM, TCP, SSL, NIO, UDP, multicast, JGroups and JXTA transports。ActiveMQ支持常用的多种语言客户端 C 、Java、.Net,、Python、 Php、 Ruby等。 Kafka: Apache下的一个子项目,使用scala实现的一个高性能分布式Publish/Subscribe消息队列系统,具有以下特性:

快速持久化:通过磁盘顺序读写与零拷贝机制,可以在O(1)的系统开销下进行消息持久化;

高吞吐:在一台普通的服务器上既可以达到10W/s的吞吐速率;

高堆积:支持topic下消费者较长时间离线,消息堆积量大;

完全的分布式系统:Broker、Producer、Consumer都原生自动支持分布式,依赖zookeeper自动实现复杂均衡;

支持Hadoop数据并行加载:对于像Hadoop的一样的日志数据和离线分析系统,但又要求实时处理的限制,这是一个可行的解决方案。 RocketMQ: 阿里系下开源的一款分布式、队列模型的消息中间件,原名Metaq,3.0版本名称改为RocketMQ,是阿里参照kafka设计思想使用java实现的一套mq。同时将阿里系内部多款mq产品(Notify、metaq)进行整合,只维护核心功能,去除了所有其他运行时依赖,保证核心功能最简化,在此基础上配合阿里上述其他开源产品实现不同场景下mq的架构,目前主要多用于订单交易系统。 具有以下特点:

能够保证严格的消息顺序

提供针对消息的过滤功能

提供丰富的消息拉取模式

高效的订阅者水平扩展能力

实时的消息订阅机制

亿级消息堆积能力

RabbitMQ: 使用Erlang编写的一个开源的消息队列,本身支持很多的协议:AMQP,XMPP, SMTP,STOMP,也正是如此,使的它变的非常重量级,更适合于企业级的开发。同时实现了Broker架构,核心思想是生产者不会将消息直接发送给队列,消息在发送给客户端时先在中心队列排队。对路由(Routing),负载均衡(Load balance)、数据持久化都有很好的支持。多用于进行企业级的ESB整合。

RabbitMQ支持AMQP协议:

本次是是使用RabbitMQ 安装两种方式 Linux 和win 第一种: 我把Erlang的安装包和rabbitmq都放到网盘了下载不下来的自提 网盘:https://pan.baidu.com/s/17mwHs3mupk16VhMkTTicrg 密码:sbl1

安装需要Erlang语言 下载地址: https://www.erlang.org/downloads

下载不来去git下载 github:https://github.com/erlang/otp/releases/tag/OTP-23.2.3 win64位

安装

rabbitmq 安装 下载地址 https://github.com/rabbitmq/rabbitmq-server/releases/tag/v3.8.12-beta.1

安装一路下一步

安装好之后到安装sbin的目录下 打开cmd命名 安装可视化插件

命令

代码语言:javascript复制
rabbitmq-plugins enable rabbitmq_management

安装之后 本地启动:

代码语言:javascript复制
http://localhost:15672/

可视化页面的端口默认就是:15672 操作端口是:5672

账号:guest 密码:guest

第二种Linux安装 大致跟win一致

我个人就用Docker了安装简单比较快:

拉取镜像 指定版本,该版本包含了web控制页面

代码语言:javascript复制
docker pull rabbitmq:management

启动镜像:

代码语言:javascript复制
docker run -d --hostname my-rabbit --name rabbit -p 15672:15672 -p 5672:5672 rabbitmq:management

查看容器

账号密码都是默认:guest

页面概要: overview Ready:待消费的消息总数。 Unacked:待应答的消息总数。 Total:总数 Ready Unacked。

所有队列的消费情况。速率=(num1-num0)/(s1-s0) num1:s1时刻的个数。num0:s0时刻的个数。

Publish:producter pub消息的速率。 Publisher confirm:broker确认pub消息的速率。 Deliver(manual ack):customer手动确认的速率。 Deliver( auto ack):customer自动确认的速率。 Consumer ack:customer正在确认的速率。 Redelivered:正在传递’redelivered’标志集的消息的速率。 Get (manual ack):响应basic.get而要求确认的消息的传输速率。 Get (auto ack):响应于basic.get而发送不需要确认的消息的速率。 Return:将basic.return发送给producter的速率。 Disk read:queue从磁盘读取消息的速率。 Disk write:queue从磁盘写入消息的速率。

Connections Virtual host:所属的虚拟主机。 Name:名称。 User name:使用的用户名。 State:当前的状态,running:运行中;idle:空闲。 SSL/TLS:是否使用ssl进行连接。 Protocol:使用的协议。 Channels:创建的channel的总数。 From client:每秒发出的数据包。 To client:每秒收到的数据包。

Channels channel:名称。 Virtual host:所属的虚拟主机。 User name:使用的用户名。 Mode:渠道保证模式。 可以是以下之一,或者不是:C: confirm。T:transactional(事务)。 State :当前的状态,running:运行中;idle:空闲。 Unconfirmed:待confirm的消息总数。 Prefetch:设置的prefetch的个数。 Unacker:待ack的消息总数。 publish:producter pub消息的速率。 confirm:producter confirm消息的速率。 deliver/get:consumer 获取消息的速率。 ack:consumer ack消息的速率。

Exchanges Virtual host:所属的虚拟主机。 Name:名称。 Type:exchange type,具体的type可以查看RabbitMq系列之一:基础概念。 Features:功能。 可以是以下之一,或者不是:D: 持久化。T:Internal,存在改功能表示这个exchange不可以被client用来推送消息,仅用来进行exchange和exchange之间的绑定,否则可以推送消息也可以绑定。 Message rate in:消息进入的速率。 Message rate out:消息出去的速率。

Queues Virtual host:所属的虚拟主机。 Name:名称。 Features:功能。 可以是以下之一,或者不是:D: 持久化。 State:当前的状态,running:运行中;idle:空闲。 Ready:待消费的消息总数。 Unacked:待应答的消息总数。 Total:总数 Ready Unacked。 incoming:消息进入的速率。 deliver/get:消息获取的速率。 ack:消息应答的速率。

Admin Name:名称。 Tags:角色标签,只能选取一个。 Can access virtual hosts:允许进入的vhost。 Has password:设置了密码。 administrator (超级管理员) 可登陆管理控制台(启用management plugin的情况下),可查看所有的信息,并且可以对用户,策略(policy)进行操作。 monitoring(监控者) 可登陆管理控制台(启用management plugin的情况下),同时可以查看rabbitmq节点的相关信息(进程数,内存使用情况,磁盘使用情况等) policymaker(策略制定者) 可登陆管理控制台(启用management plugin的情况下), 同时可以对policy进行管理。 management(普通管理者) 仅可登陆管理控制台(启用management plugin的情况下),无法看到节点信息,也无法对策略进行管理。 none(其他) 无法登陆管理控制台,通常就是普通的生产者和消费者。

创建交换器 direct :点对点 direct :比如是Exchanges 交换器是 名字test.direct 的也是路由的key,如果和Binding中的Binding的名字一样的话,消息就会发送到对应的对应的队列中,路由的键与队列的名字完全一致,就是完全匹配,如果一个队列绑定的到交换机要求键为test.direct 的话,那交换器只转发名字为test.direct 的消息别的队列不会受到 ,别的是接受不到了 这是单波模式

fanout:广播模式 fanout:每个发到fanout类型交换器的消息都会分到所有的绑定的对列上去,fanout交换器不处路由键,只是简单的将队列绑定到交换器上,每个发发送到交换器的消息都会被转发到与该交换器绑定的所有队列上,fanout发送消息是最快的

topic:主题模式 topic:topic交换器通过模式匹配分配消息的路由键属性,将路由键和某个模式进行匹配,此时队列需要绑定到一个模式上。它将路由键和绑定键的字符串切分成单词,这些单词之间用点隔开它同样也会识别两个通配符:符号“#和符号*”。#匹配个或多个单词,*匹配一个单词。

交换机添加好 创建消息队列 Queues 穿件消息前先了解一下Exchanges和Binding的角色 首先生产者把消息发送到Exchanges上消息最终消息到队列呗消费者消费,而Binding决定交换器的消息应该发送给那个队列

创建队列

我这里创建了4个队列分是

接下来劲行绑定 Exchanges交换机绑定

测试direct 绑定可四个队列

测试 发送消息

结果:只有一个符合

test.fanout:也绑定这四个

测试:发送消息

结果:四个同事都被满足了

test.topic:绑定规则

测试:

结果

测试

结果:

和项目结合: 使用boot pom依赖

代码语言:javascript复制
     <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>

yml 现在代码操作的端口就是5672了不是15672切记

代码语言:javascript复制
server:
  port: 8081
spring:
  rabbitmq:
    host: localhost
    username: guest
    password: guest
    port: 5672

当然要在主启动类加上rabbitmq开启注解

代码语言:javascript复制
@EnableRabbit
代码语言:javascript复制
@SpringBootApplication
@EnableRabbit
public class SpringBootRabbitmq { 
   

    public static void main(String[] args) { 
   
        SpringApplication.run(SpringBootRabbitmq.class,args);
    }

}

使用rabbitmq的话要对消息序列化不然可能会乱编码 需要一个RabbitmqConfig 解决

代码语言:javascript复制
@Configuration
public class RabbitmqConfig { 
   

    //Rabbitmq json序列化
    @Bean
    public MessageConverter  messageConverter(){ 
   

        return new Jackson2JsonMessageConverter();
    }

}

rabbitmq封装了一个工具类RabbitTemplate 点进去就可以看到这个方法,这个就经常用的发送消息的方法

我就用点对点测试

代码语言:javascript复制
public void test(User user){ 
   

        rabbitTemplate.convertAndSend("test.direct","mrtang",user);
    }

接受:

代码语言:javascript复制
   public void test1(){ 
   
        Object test = rabbitTemplate.receiveAndConvert("mrtang");
        System.out.println(test);
    }

当然一注解就可以搞定的 queues=“路由规则” 就可以实时接受信息了 客户端发送,消费端就可以拿到消息了

代码语言:javascript复制
 @RabbitListener(queues = "mrtang")

创建广播模式 路由不用写 因为他绑定的全有队列都能收到,接受和单点一样

代码语言:javascript复制
  public void testFanout(User user){ 
   
     
        rabbitTemplate.convertAndSend("test.fanout","",user);
    }

创建交换器和队列代码创建 AmqpAdmin创建 交换器 路由绑定 和队列

代码语言:javascript复制
   @Autowired
    private AmqpAdmin amqpAdmin;

创建Exchange规则

代码语言:javascript复制
public  void exchanges(){ 
   
      //创建单点
      amqpAdmin.declareExchange(new DirectExchange("directExchange"));
      //创建广播
      amqpAdmin.declareExchange(new FanoutExchange("fanoutExchange"));
      //创建 主题
      amqpAdmin.declareExchange(new TopicExchange("topicExchange"));


  }

创建队列

代码语言:javascript复制
  public void  queue(){ 
   
         //创建队列 testQueue名称 true 持久化
        amqpAdmin.declareQueue(new Queue("testQueue",true));
  }

绑定

代码语言:javascript复制
  public void  binding(){ 
   
        //绑定规则 
      /** * testQueue 队列名称 * Binding.DestinationType.QUEUE 是绑定队列类型 * fanoutExchange 交换器 名称 * testQueue 路由key */
      amqpAdmin.declareBinding(new Binding("testQueue",Binding.DestinationType.QUEUE,"fanoutExchange","testQueue",null));
  }

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/186421.html原文链接:https://javaforall.cn

0 人点赞