在学习RabbitMQ的工作模式之前,必须先了解Exchange的类型,因为工作模式与交换机类型的基本对应的,
1.Direct:直接交换机通过消息上的路由键直接对消息进行分发,相当于精确匹配,一对一
2.Topic:这个交换机会将路由键和绑定上的模式进行通配符匹配,相当于模糊匹配,一对多
3.Fanout:一个扇出交换机会将消息发送到所有和它进行绑定的队列上,广播,群发
4.Headers:消息头交换机使用消息头的属性进行消息路由,相当于模糊匹配(like header%),一对多
再接着学习工作模式,原先是6种,现在是7种,见官网:https://www.rabbitmq.com/getstarted.html,如下:
如上,总共七种
1.简单模式(simple)
2.工作模式(work)
3.发布/订阅模式(publisher/subscribe):对应Fanout
4.路由模式(routing):对应Direct
5.主题模式(topic):对应Topic/Headers
6.RPC
7.发布确认模式(publisher confirms)
1.简单模式
简单模式:一个生产者,一个消费者,不涉及Exchange
根据官网给出的样例:
pom.xml:
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.9.0</version>
</dependency>
消息生产者:
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.nio.charset.StandardCharsets;
/**
* @author Becolette
* @description 消息产生者
* @datetime 2020/9/24 13:53
*/
public class Send {
/** 定义了一个Queue */
private final static String QUEUE_NAME = "hello";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
/**
* 此处是采用了默认的配置,可以ctrl + F3进入ConnectionFactory配置连接参数查看
* 下列的factory.setHost("localhost")相当于
* factory.setHost("localhost")
* factory.setPort(5672)
* factory.setUsername("guest")
* factory.setPassword("guest")
* factory.setVirtualHost("/")
*/
factory.setHost("localhost");
/** 创建通道channel */
try (Connection connection = factory.newConnection();
Channel channel = connection.createChannel()) {
/**
* @param queue the name of the queue
* 用于存储消息的队列
* @param durable true if we are declaring a durable queue (the queue will survive a server restart)
* 是否持久化,true则服务器启动一直存在
* @param exclusive true if we are declaring an exclusive queue (restricted to this connection)
* 是否排外,true则一个channel只能用于一个消费者消费
* @param autoDelete true if we are declaring an autodelete queue (server will delete it when no longer in use)
* 是否自动删除,true表示消费完自动删除
* @param arguments other properties (construction arguments) for the queue
* 其他属性
*/
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
String message = "Hello World!";
/**
* @param exchange the exchange to publish the message to
* 交换机,发布消息
* @param routingKey the routing key
* 路由键,也就是绑定的queue队列
* @param props other properties for the message - routing headers etc
* 其他参数,例如:路由头
* @param body the message body
* 消息实体
*/
channel.basicPublish("", QUEUE_NAME, null, message.getBytes(StandardCharsets.UTF_8));
System.out.println(" [x] Sent '" + message + "'");
}
}
}
消息消费者:
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;
/**
* @author Becolette
* @description 消息消费者
* @datetime 2020/9/24 13:50
*/
public class Recv {
private final static String QUEUE_NAME = "hello";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
/** 创建通道开始可以接收消息了 */
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
/**
* DeliverCallback ==> while(true)
*/
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), "UTF-8");
System.out.println(" [x] Received '" + message + "'");
};
/**
* @param queue the name of the queue
* 队列名称,也即RouteKey
* @param autoAck true if the server should consider messages
* acknowledged once delivered;
* false if the server should expect explicit acknowledgements
* 消息消费后是否自动反馈
* @param deliverCallback callback when a message is delivered
* 消息获取到就反馈
* @param cancelCallback callback when the consumer is cancelled
* 当消费者退出就退出
*/
channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> { });
}
}