RabbitMQ
一、主流消息中间件介绍
一、ActiveMQ
- ActiveMQ是Apache出品,最流行的,能力强劲的开源消息总线,并且他是一个完全支持JMS规范的消息中间件。
- 七丰富的API,多种集群构建模式使得他称为业界老牌消息中间件,在中小型企业广泛应用!
- MQ衡量指标:服务性能、数据存储、集群架构
二、Kafka
- Kafka是LinkedIn开源的分布式发布-订阅消息系统,目前归属于Apache顶级项目。Kafka主要特点是基于Pull的模式来处理消息消费,追求高吞吐量,一开始的目的就是用于日志收集和传输。0.8版本开始支持复制,不支持事务,对消息的重复、丢失、错误没有严格要求,适合产生大量数据的互联网服务的数据收集业务。
三、RocketMQ
- RocketMQ是阿里开源的消息中间件,目前也已经孵化为Apache顶级项目,他是纯Java开发,具有高吞吐量、高可用性、适合大规模分布式系统应用的特点。RocketMQ思路起源于Kafka,它对消息的可靠传输及事务性做了优化,目前在阿里集团被广泛应用于交易、充值、流计算、消息推送、日志流式处理、binglog分发等场景。
四、RabbitMQ
- RabbitMQ是使用Erlang语言开发的开源消息队列系统,基于AMQP协议来实现。AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。AMQP协议更多用在企业系统内,对数据一致性、稳定性和可靠性要求很高的场景,对性能和吞吐量的要求还在其次。
二、RabbitMQ核心概念及AMQP协议
一、RabbitMQ的核心概念
一、初始RabbitMQ
- RabbitMQ是一个开源的消息代理和队列服务器,用来通过普通协议在完全不同的应用之间共享数据,RabbitMQ是使用Erlang语言来编写的,并且RabbitMQ是基于AMQP协议的。
二、RabbitMQ优势
- 开源、性能优秀,稳定性保障
- 提供可靠性消息投递模式(confirm)、返回模式(return)
- 与SpringAMQP完美的整合。
- 集群模式丰富,表达式配置,HA模式,镜像队列模型
- 保证数据不丢失的前提做到高可靠性、可用性
三、RabbitMQ高性能的原因
- Erlang语言最初在于交换机领域的架构模式,这样使得RabbitMQ在Broker之间进行数据交互的性能是非常优秀的。
- Erlang的优点:Erlang有着和原生Socket一样的延迟
四、什么是AMQP高级消息队列协议
- AMQP全称:Advanced Message Queuing Protocol
- AMQP翻译:高级消息队列协议
- AMQP定义:是具有现代特征的二进制协议。是一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。
五、AMQP协议模型
六、AMQP核心概念
-
Server:又称Broker,接受客户端的连接,实现AMQP实体服务。
-
Connection:连接,应用程序与Broker的网络连接
-
Channel:网络信道,几乎所有的操作都是在Channel中进行,Channel是进行消息读写的通道。客户端可建立多个Channel,每个Channel代表一个会话任务。
-
Message:消息,服务器和应用程序之间传送的数据,由Properties和Body组成。Properties可以对消息进行修饰,比如消息的优先级、延迟等高级特性;Body则就是消息体内容。
-
Virtual host:虚拟地址,用于进行逻辑隔离,最上层的消息路由。一个Virtual Host里面可以有若干个Exchange和Queue,同一个Virtual Host里面不能有相同名称的Exchange或Queue。
-
Exchange:交换机,接收消息,根据路由键转发消息到绑定的队列。
-
Binding:Exchange和Queue之间的虚拟连接,binding中可以包含routing key
-
Routing key:一个路由规则,虚拟机可用它来确定如何路由一个特定消息。
-
Queue:也称为MessageQueue,消息队列,保存消息并将它们转发给消费者。
七、RabbitMQ的整体架构是什么样子的
八、RabbitMQ消息是如何流转的
二、命令行与管控台
一、基础操作
- rabbitmqctl stop_app:关闭应用
- rabbitmqctl start_app:启动应用
- rabbitmqctl status:节点状态
- rabbitmqctl add_user username password:添加用户
- rabbitmqctl list_user:列出所有用户
- rabbitmqctl delete_user username:删除用户
- rabbitmqctl clear_permissions -p vhostpath username:清除用户权限
- rabbitmqctl list_user_permissions username:列出用户权限
- rabbitmqctl change_password username newpassword:修改密码
- rabbitmqctl set_permissions -p vhostpath username “." " .” “.*”:设置用户权限
- rabbitmqctl add_vhost vhostpath:创建虚拟主机
- rabbitmqctl list_vhost:列出所有虚拟主机
- rabbitmqctl list_permissions -p vhostppath:列出虚拟主机上所有权限
- rabbitmqctl list_queues:查看所有队列信息
- rabbitmqctl -p vhostpath purge_queue blue:清除队列里的消息
二、高级操作
- rabbitmqctl reset:移除所有数据,要在rabbitmqctl stop_app 之后使用
- rabbitmqctl join_cluster [–ram] :组成集群命令
- rabbitmqctl cluster_status:查看集群状态
- rabbitmqctl change_cluster_node_type disc | ram :修改集群节点的存储形式
- rabbitmqctl forger_cluster_node [–offline] :忘记节点(摘除节点)
- rabbitmqctl rename_cluster_node oldnode1 newnode1 [oldnode2] [newnode2…](修改节点名称)
三、生产者与消费者
-
ConnectionFactory:获取连接工厂
-
Connection:一个连接
-
Channel:数据通信信道,可发送和接收消息
-
Queue:具体的消息存储队列
-
Producer & Consumer 生产者和消费者
-
Consumer:
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Consumer {
public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
// 创建一个ConnectionFactory并进行配置
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("101.37.156.238");
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("/");
//通过连接工厂创建连接
Connection connection = connectionFactory.newConnection();
// 通过connection创建一个Channel
Channel channel = connection.createChannel();
// 声明一个队列
String queueName = "test001";
channel.queueDeclare(queueName, true,false, false, null);
// 创建消费者
QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
// 设置Channel
channel.basicConsume(queueName, true, queueingConsumer);
while (true) {
// 获取消息
QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
String msg = new String(delivery.getBody());
System.out.println("消费端:" + msg);
//Envelope envelope = delivery.getEnvelope();
}
}
}
- Producer:
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 void main(String[] args) throws IOException, TimeoutException {
// 创建一个ConnectionFactory并进行配置
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("101.37.156.238");
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("/");
//通过连接工厂创建连接
Connection connection = connectionFactory.newConnection();
// 通过connection创建一个Channel
Channel channel = connection.createChannel();
// 通过Channel发送数据
for (int i = 0; i < 5; i++) {
String msg = "Hello RabbitMQ!";
channel.basicPublish("", "test001", null, msg.getBytes());
}
// 记得关闭相关的连接
channel.close();
connection.close();
}
}
四、Exchange交换机
- Exchange:接收消息,并根据路由键转发消息所绑定的队列