Advanced Message Queuing Protocol高级消息队列协议,也是一个消息代理的规范,兼容JMS
RabbitMQ是AMQP的实现
Publisher
消息的生产者,也是一个向交换器发布消息的客户端应用程序
Message
消息头:相当于信封的上的收件地址routing-key(路由键)、priority(相对于其他消息的优先权)、delivery-mode(指出该消息可能需要持久性存储)
消息体:信的内容
Connection
Publisher/Consumer和broker之间的TCP连接
Connnection内部建立的逻辑连接,通常每个线程创建单独的channel 信道,多路复用连接中的一条独立的双向数据流通道。信道是建立在真实的TCP连接内的虚拟连接,AMQP命令都是通过信道发出去的,不管是发布消息、订阅队列还是接收消息,这些动作都是通过信道完成。因为对于操作系统来说建立和销毁TCP都是非常昂贵的开销,所以引入了信道的概念,以复用一条TCP 连接。
Message Broker
接收和发送消息的应用,比如 RabbitMQ,RocketMQ
Broker: 代理商,处理,分发消息
Virtual Host
虚拟的Broker,将多个单元分开
表示一批交换器、消息队列和相关对象。虚拟主机是共享相同的身份认证和加密环境的独立服务器域。每个vhost 本质上就是一个 mini 版的 RabbitMQ 服务器,拥有自己的队列、交换器、绑定和权限机制。vhost 是 AMQP 概念的基础,必须在连接时指定,RabbitMQ 默认的 vhost 是 / 。
Binding
Exchange和queue之间的虚拟连接,用于消息分发的依据
Queue
相当于菜鸟驿站
用来保存消息直到发送给消费者。它是消息的容器,也是消息的终点。一个消息可投入一个或多个队列。消息一直在队列里面,等待消费者连接到这个队列将其取走。
Exchange
相当于快递的分发中心,用来接收生产者发送的消息并将这些消息路由给服务器中的队列
direct(默认)
Message中的Routing Key如果和Binding Key一致,Direct Exchage则将message发送到对应的queue中。完全匹配、单播的模式。
public class Direct {
@Test
public void createInfo(){
//使用默认的用户名
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.0.113");
try( Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel()
) {
channel.exchangeDeclare("exchange_testDirect", BuiltinExchangeType.DIRECT,true);
channel.queueDeclare("queue.direct1",true,false,false,null);
channel.queueDeclare("queue.direct2",true,false,false,null);
channel.queueDeclare("queue.direct3",true,false,false,null);
channel.queueDeclare("queue.direct4",true,false,false,null);
channel.queueBind("queue.direct1","exchange_testDirect","key_direct1");
channel.queueBind("queue.direct2","exchange_testDirect","key_direct2");
channel.queueBind("queue.direct3","exchange_testDirect","key_direct3");
channel.queueBind("queue.direct4","exchange_testDirect","key_direct3");
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void sendMessageDirect(){
ObjectMapper objectMapper = new ObjectMapper();
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.0.113");
try( Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel()
) {
Book book = new Book("cj", "mysql");
String s = objectMapper.writeValueAsString(book);
channel.basicPublish("spring_DirectExchage","spring_direct",null,s.getBytes(StandardCharsets.UTF_8));
channel.basicPublish("exchange_testDirect","key_direct2",null,s.getBytes(StandardCharsets.UTF_8));
channel.basicPublish("exchange_testDirect","key_direct3",null,s.getBytes(StandardCharsets.UTF_8));
} catch (TimeoutException | IOException e) {
e.printStackTrace();
}
}
@Test
public void consumeDirect() {
ObjectMapper objectMapper = new ObjectMapper();
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.0.113");
try( Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel()
) {
channel.basicConsume("queue.order", true, (tag,message)->{
String s = new String(message.getBody(), StandardCharsets.UTF_8);
Book book = objectMapper.readValue(s, Book.class);
}, System.out::println);
} catch (TimeoutException | IOException e) {
e.printStackTrace();
}
}
}
Fanout
Fanout交换机 会将接收到的消息广播到每一个与其绑定的queue上
转发消息是最快的
public class Fanout {
@Test
public void createInfo(){
//使用默认的用户名
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.0.113");
try( Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel()
) {
channel.exchangeDeclare("exchange_testFanout", BuiltinExchangeType.FANOUT,true);
channel.queueDeclare("fanout_01", true,false,false,null);
channel.queueDeclare("fanout_02", true,false,false,null);
channel.queueDeclare("fanout_03", true,false,false,null);
channel.queueDeclare("fanout_04", true,false,false,null);
channel.queueBind("fanout_01","exchange_testFanout","key_fanout");
channel.queueBind("fanout_02","exchange_testFanout","key_fanout");
channel.queueBind("fanout_03","exchange_testFanout","key_fanout");
channel.queueBind("fanout_04","exchange_testFanout","key_fanout");
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void sendMessageDirect(){
ObjectMapper objectMapper = new ObjectMapper();
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.0.113");
try( Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel()
) {
Book book = new Book("cj", "mysql");
String s = objectMapper.writeValueAsString(book);
channel.basicPublish("spring_DirectExchage","spring_direct",null,s.getBytes(StandardCharsets.UTF_8));
channel.basicPublish("exchange_testDirect","key_direct2",null,s.getBytes(StandardCharsets.UTF_8));
channel.basicPublish("exchange_testDirect","key_direct3",null,s.getBytes(StandardCharsets.UTF_8));
} catch (TimeoutException | IOException e) {
e.printStackTrace();
}
}
@Test
public void consumeDirect() {
ObjectMapper objectMapper = new ObjectMapper();
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.0.113");
try(Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel()
) {
channel.basicConsume("fanout_01", true, (tag,message)->{
String s = new String(message.getBody(), StandardCharsets.UTF_8);
Book book = objectMapper.readValue(s, Book.class);
}, System.out::println);
} catch (TimeoutException | IOException e) {
e.printStackTrace();
}
}
}
Topic
全匹配:和direct一致
#:匹配0个或者多个 单词
*:匹配一个单词
public class Topic {
@Test
public void consumeDirect() {
ObjectMapper objectMapper = new ObjectMapper();
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.0.113");
try(Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel()
) {
channel.basicConsume("Topic_java", true, (tag,message)->{
String s = new String(message.getBody(), StandardCharsets.UTF_8);
Book book = objectMapper.readValue(s, Book.class);
}, System.out::println);
} catch (TimeoutException | IOException e) {
e.printStackTrace();
}
}
@Test
public void sendMessageDirect(){
ObjectMapper objectMapper = new ObjectMapper();
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.0.113");
try( Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel()
) {
Book book = new Book("cj", "mysql");
String s = objectMapper.writeValueAsString(book);
channel.basicPublish("exchange_testTopic","L.i.e",null,s.getBytes(StandardCharsets.UTF_8));
} catch (TimeoutException | IOException e) {
e.printStackTrace();
}
}
@Test
public void createInfo(){
//使用默认的用户名
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.0.113");
try( Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel()
) {
channel.exchangeDeclare("exchange_testTopic", BuiltinExchangeType.TOPIC,true);
channel.queueDeclare("Topic_java", true,false,false,null);
channel.queueDeclare("Topic_python", true,false,false,null);
channel.queueDeclare("Topic_docker", true,false,false,null);
channel.queueDeclare("Topic_tomcat", true,false,false,null);
channel.queueBind("Topic_java","exchange_testTopic","L.#");
channel.queueBind("Topic_python","exchange_testTopic","L.#");
channel.queueBind("Topic_docker","exchange_testTopic","F.*");
channel.queueBind("Topic_tomcat","exchange_testTopic","F.*");
} catch (Exception e) {
e.printStackTrace();
}
}
}
Consumer
消息的消费者,表示一个从消息队列中取得消息的客户端应用程序