rabbitmq是什么?
MQ全称为Message Queue,即消息队列, RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message Queue 高级消息队列协议)协议实现的消息队列,它是一种应用程序之间的通信方法,消息队列在分布式系统开 发中应用非常广泛。RabbitMQ就是遵循AMQP(高级消息队列协议)标准协议开发的。MQ服务RabbitMQ官方地址:http://www.rabbitmq.com/
rabbitmq的作用?
1、任务异步处理。 将不需要同步处理的并且耗时长的操作由消息队列通知消息接收方进行异步处理。提高了应用程序的响应时间。
简单来讲就是当消息的发送方需要将消息发送给多个接收方的时候,可以将消息发送到在rabbitmq上,接受方通过监听rabbitmq,分别从rabbitmq上拉取消息
2、应用程序解耦合 MQ相当于一个中介,生产方通过MQ与消费方交互,它将应用程序进行解耦合。
还有哪些消息中间件
ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ、Redis。
安全性对比:ActiveMQ>RabbitMQ>Kafka
效率对比:ActiveMQ<RabbitMQ<Kafka
rabbitmq的工作原理
组成部分说明如下:
Broker:消息队列服务进程,此进程包括两个部分:Exchange和Queue。
Exchange:消息队列交换机,按一定的规则将消息路由转发到某个队列,对消息进行过虑。
Queue:消息队列,存储消息的队列,消息到达队列并转发给指定的消费方。
Producer:消息生产者,即生产方客户端,生产方客户端将消息发送到MQ。
Consumer:消息消费者,即消费方客户端,接收MQ转发的消息。
消息发布接收流程:
-----发送消息-----
1、生产者和Broker建立TCP连接。
2、生产者和Broker建立通道。
3、生产者通过通道消息发送给Broker,由Exchange将消息进行转发。
4、Exchange将消息转发到指定的Queue(队列)
----接收消息-----
1、消费者和Broker建立TCP连接
2、消费者和Broker建立通道
3、消费者监听指定的Queue(队列)
4、当有消息到达Queue时Broker默认将消息推送给消费者。
5、消费者接收到消息。
原生简单测试
1、发动方与接收方都需要导入的依赖如下:
<dependencies>
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
<version>2.3.3.RELEASE</version>
</dependency>
</dependencies>
2、消息发送方:
package com.test.rabbitmq;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Producer {
//队列
public static final String QUEUE="hello myworld";
public static void main(String[] args) {
//生产者通过连接工厂与mq建立连接
ConnectionFactory connectionFactory=new ConnectionFactory();
connectionFactory.setHost("127.0.0.1");
connectionFactory.setPort(5672);//设置的端口号加主机号
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
//设置虚拟机,一个mq可以安装多个虚拟机,一个虚拟机相当于一个独立的mq
connectionFactory.setVirtualHost("/");
Connection connection=null;
try {
connection= connectionFactory.newConnection();
//创建会话通道,生产者与mq之间的消息通信都是在通道中完成的
Channel channel=connection.createChannel();
//声明队列(队列名称,是否持久化持久化之后mq重启队列依然在,是否独占连接独占的只允许队列在该链接中访问连接一旦关闭队列自动删除,自动删除)
channel.queueDeclare(QUEUE,true,false,false,null);
//发送消息
/**参数明细
* 1、exchange,交换机,如果不指定使用默认交换机,使用空字符串表示使用默认交换机
*2、routekey,交换路由key,交换机根据路由key转发到指定的队列,如果使用默认交换机routekey为队列名
* 3、消息属性
* 4、消息内容
*/
String message="hello world 你好";
channel.basicPublish("",QUEUE,null,message.getBytes());
System.out.println("send successful");
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
} finally {
try {
connection.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
接收方程序
package com.test;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.Queue;
import java.util.concurrent.TimeoutException;
public class Consumer {
public static final String QUEUE="hello myworld";
public static void main(String[] args) throws IOException, TimeoutException {
//生产者通过连接工厂与mq建立连接
ConnectionFactory connectionFactory=new ConnectionFactory();
connectionFactory.setHost("127.0.0.1");
connectionFactory.setPort(5672);//设置的端口号加主机号
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
//设置虚拟机,一个mq可以安装多个虚拟机,一个虚拟机相当于一个独立的mq
connectionFactory.setVirtualHost("/");
Connection connection= connectionFactory.newConnection();
//创建会话通道,生产者与mq之间的消息通信都是在通道中完成的
Channel channel=connection.createChannel();
channel.queueDeclare(QUEUE,true,false,false,null);
//实现方法
DefaultConsumer defaultConsumer=new DefaultConsumer(channel){
//当接收到消息之后此方法将会被调用
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
String message=new String(body,"utf-8");
Long id=envelope.getDeliveryTag();
System.out.println("receive"+message+" id="+id);
}
};
/**参数说明
* 1、队列名称
* 2、自动回复,当消费者接收到了消息之后,会告诉mq自己收到消息,如果设置为true的话会自动回复,false需要手动回复,如果不回复的话消息会一直存在
* 3、消费回调方法,当消费者接收到消息之后需要执行的方法
* */
channel.basicConsume(QUEUE,true,defaultConsumer);
//不用关闭连接 因为需要监听
}
}
一旦消费方登录,消费方将会监听到发送方存储或者正在发送的消息。