1. Préparation de l'environnement
1. Introduisez les dépendances correspondantes dans le fichier pom :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2. Configurez RabbitMQ dans le fichier de configuration application.yml :
spring:
#rabbitmq配置
rabbitmq:
host: 192.168.150.152#rabbitMq的服务器地址
port: 5672
username: root #用户名
password: 123456 #密码
virtual-host: /hjl #虚拟主机
2. Intégration
- Mode simple point à point
① Déclarez la file d'attente dans le fichier de configuration
@SpringBootConfiguration
public class RabbitMqConfig {
/**
* hello队列名称
*/
public static final String HELLO_MSG_QUEUE = "hello.msg.queue";
/**
* 声明hello队列
*
* @return
*/
@Bean
public Queue getHelloQueue() {
//参数一:队列名;参数二:是否持久化队列
return new Queue(HELLO_MSG_QUEUE, true);
}
}
②Créer un producteur
@SpringBootTest
@RunWith(SpringRunner.class)
public class RabbitMqTest {
@Resource
private RabbitTemplate rabbitTemplate;
@Test
public void sendHello() {
for (int i = 0; i < 10; i++) {
rabbitTemplate.convertAndSend(RabbitMqConfig.HELLO_MSG_QUEUE, "hello world" + i);
}
}
}
Une fois le message envoyé avec succès, vérifiez-le sur la page de gestion web :
vous pouvez voir que le message est généré dans la file d'attente correspondante
③ Créer un consommateur
@Component
public class RabbitMqConsumer {
@RabbitListener(queues = RabbitMqConfig.HELLO_MSG_QUEUE)
public void listenHelloMsg(String message) {
System.out.println("接受时间:"+System.currentTimeMillis());
System.out.println("转发消息是:" + message);
}
}
Démarrez le projet et vous pouvez voir que le message est consommé avec succès :
- File d'attente de travail (plusieurs consommateurs correspondent à une file d'attente)
①Déclarez la file d'attente
@SpringBootConfiguration
public class RabbitMqConfig {
/**
* work队列名称
*/
public static final String WORK_MSG_QUEUE = "work.msg.queue";
/**
* 声明work队列
*
* @return
*/
@Bean
public Queue getWorkQueue() {
//参数一:队列名;参数二:是否持久化队列
return new Queue(WORK_MSG_QUEUE, true);
}
}
②Créer un producteur
@SpringBootTest
@RunWith(SpringRunner.class)
public class WorkMqTest {
@Resource
private RabbitTemplate rabbitTemplate;
@Test
public void send() {
for (int i = 0; i < 10; i++) {
rabbitTemplate.convertAndSend(RabbitMqConfig.WORK_MSG_QUEUE, "这是一条工作队列消息" + i);
}
}
}
③Créer des consommateurs (plusieurs)
@Component
public class RabbitMqConsumer {
@RabbitListener(queues = RabbitMqConfig.WORK_MSG_QUEUE)
public void listenWork1(String message) {
System.out.println("消费者一转发消息是:" + message);
}
@RabbitListener(queues = RabbitMqConfig.WORK_MSG_QUEUE)
public void listenWork2(String message) {
System.out.println("消费者二转发消息是:" + message);
}
}
Vous pouvez voir que les deux consommateurs ont réussi à consommer les messages dans la file d'attente de mots.
- Mode de publication et d'abonnement
① déclarer la file d'attente, changer et lier
@SpringBootConfiguration
public class RabbitMqConfig {
/**
* publish队列1
*/
public static final String PUBLISH_MSG_QUEUE1 = "publish.msg.queue1";
/**
* publish队列2
*/
public static final String PUBLISH_MSG_QUEUE2 = "publish.msg.queue2";
/**
* publish交换机
*/
public static final String PUBLISH_EXCHANGE = "publish.exchange";
/**
* Publish队列
*
* @return
*/
@Bean
public Queue getPublishQueue1() {
return new Queue(PUBLISH_MSG_QUEUE1, true);
}
/**
* Publish队列
*
* @return
*/
@Bean
public Queue getPublishQueue2() {
return new Queue(PUBLISH_MSG_QUEUE2, true);
}
/**
* Publish交换机
*
* @return
*/
@Bean
public FanoutExchange publishExchange() {
FanoutExchange exchange = new FanoutExchange(PUBLISH_EXCHANGE, true, false);
return exchange;
}
/**
* 绑定队列和交换机
*
* @return
*/
@Bean
public Binding bindPublishExchangeQueue1() {
Binding binding = BindingBuilder.bind(getPublishQueue1()).to(publishExchange());
return binding;
}
/**
* 绑定队列和交换机
*
* @return
*/
@Bean
public Binding bindPublishExchangeQueue2() {
Binding binding = BindingBuilder.bind(getPublishQueue2()).to(publishExchange());
return binding;
}
②Créer un producteur
@SpringBootTest
@RunWith(SpringRunner.class)
public class PublishMqTest {
@Resource
private RabbitTemplate rabbitTemplate;
@Test
public void send() {
for (int i = 0; i < 10; i++) {
//参数一:交换机名称;参数二:routingKey(广播模式不传);参数三:消息体
rabbitTemplate.convertAndSend(RabbitMqConfig.PUBLISH_EXCHANGE, null, "这是一条工作队列消息" + i);
}
}
}
③Créer des consommateurs (plusieurs)
@Component
public class PublishConsumer {
@RabbitListener(queues = RabbitMqConfig.PUBLISH_MSG_QUEUE1)
public void listenDead1(String message) {
System.out.println("消费者一接收消息:" + message);
}
@RabbitListener(queues = RabbitMqConfig.PUBLISH_MSG_QUEUE2)
public void listenDead2(String message) {
System.out.println("消费者二接收消息:" + message);
}
}
On voit que les deux centres de consommation reçoivent tous les messages du producteur ; contrairement à la file d'attente de travail, le consommateur de la file d'attente de travail ne consomme que quelques messages, alors que ce mode consomme tous les messages.
- mode de routage
①Déclarez la file d'attente
@SpringBootConfiguration
public class RabbitMqConfig {
/**
* routing交换机
*/
public static final String ROUTING_EXCHANGE = "routing.exchange";
/**
* routing队列1
*/
public static final String ROUTING_MSG_QUEUE1 = "routing.msg.queue1";
/**
* routing队列2
*/
public static final String ROUTING_MSG_QUEUE2 = "routing.msg.queue2";
/**
* routing队列
*
* @return
*/
@Bean
public Queue getRoutingQueue1() {
return new Queue(ROUTING_MSG_QUEUE1, true);
}
/**
* routing队列
*
* @return
*/
@Bean
public Queue getRoutingQueue2() {
return new Queue(ROUTING_MSG_QUEUE2, true);
}
/**
* Publish交换机
*
* @return
*/
@Bean
public DirectExchange routingExchange() {
DirectExchange exchange = new DirectExchange(ROUTING_EXCHANGE, true, false);
return exchange;
}
/**
* 绑定队列和交换机
*
* @return
*/
@Bean
public Binding bindRoutingExchangeQueue1() {
Binding binding = BindingBuilder.bind(getRoutingQueue1()).to(routingExchange()).with("routingKey1");
return binding;
}
/**
* 绑定队列和交换机
*
* @return
*/
@Bean
public Binding bindRoutingExchangeQueue2() {
Binding binding = BindingBuilder.bind(getRoutingQueue2()).to(routingExchange()).with("routingKey2");
return binding;
}
}
②Créer un producteur
@SpringBootTest
@RunWith(SpringRunner.class)
public class RoutingMqTest {
@Resource
private RabbitTemplate rabbitTemplate;
@Test
public void send() {
//参数一:交换机名称;参数二:routingKey(交换机与队列绑定的key);参数三:消息体
rabbitTemplate.convertAndSend(RabbitMqConfig.ROUTING_EXCHANGE, "routingKey1", "队列一:这是一条路由消息消息");
rabbitTemplate.convertAndSend(RabbitMqConfig.ROUTING_EXCHANGE, "routingKey2", "队列二:这是一条路由消息消息");
}
}
③Créer des consommateurs
@Component
public class RoutingConsumer {
@RabbitListener(queues = RabbitMqConfig.ROUTING_MSG_QUEUE1)
public void listenDead1(String message) {
System.out.println("消费者一接收消息:" + message);
}
@RabbitListener(queues = RabbitMqConfig.ROUTING_MSG_QUEUE2)
public void listenDead2(String message) {
System.out.println("消费者二接收消息:" + message);
}
}
Résultats d'exécution :
x est évident : contrairement au mode publication-abonnement, ce mode nécessite que le commutateur et la file d'attente soient liés via routerKey, et le producteur peut envoyer des messages à la file d'attente spécifiée en spécifiant routerKey.
- Mode joker
① déclarer la file d'attente, changer
@SpringBootConfiguration
public class RabbitConfig {
/**
* topic交换机
*/
public static final String TOPIC_EXCHANGE = "topic.exchange";
/**
* topic队列1
*/
public static final String TOPIC_MSG_QUEUE1 = "topic.msg.queue1";
/**
*topic队列2
*/
public static final String TOPIC_MSG_QUEUE2 = "topic.msg.queue2";
/**
* routing队列
*
* @return
*/
@Bean
public Queue getTopicQueue1() {
return new Queue(TOPIC_MSG_QUEUE1, true);
}
/**
* routing队列
*
* @return
*/
@Bean
public Queue getTopicQueue2() {
return new Queue(TOPIC_MSG_QUEUE2, true);
}
/**
* Publish交换机
*
* @return
*/
@Bean
public TopicExchange topIcExchange() {
TopicExchange exchange = new TopicExchange(TOPIC_EXCHANGE, true, false);
return exchange;
}
/**
* 绑定队列和交换机
*
* @return
*/
@Bean
public Binding bindTopicExchangeQueue1() {
Binding binding = BindingBuilder.bind(getTopicQueue1()).to(topIcExchange()).with("topKey.*");
return binding;
}
/**
* 绑定队列和交换机
*
* @return
*/
@Bean
public Binding bindTopicExchangeQueue2() {
Binding binding = BindingBuilder.bind(getTopicQueue2()).to(topIcExchange()).with("topKey.#");
return binding;
}
}
②Créer un producteur
@SpringBootTest
@RunWith(SpringRunner.class)
public class TopicMqTest {
@Resource
private RabbitTemplate rabbitTemplate;
@Test
public void send() {
//参数一:交换机名称;参数二:routingKey(广播模式不传);参数三:消息体
rabbitTemplate.convertAndSend(RabbitConfig.TOPIC_EXCHANGE, "topic.key1", "这是一条通配符模式消息一");
rabbitTemplate.convertAndSend(RabbitConfig.TOPIC_EXCHANGE, "topic.key1.key2", "这是一条通配符模式消息二");
}
}
③Créer des consommateurs
@Component
public class TopicConsumer {
@RabbitListener(queues = RabbitConfig.TOPIC_MSG_QUEUE1)
public void listenDead1(String message) {
System.out.println("消费者一接收消息:" + message);
}
@RabbitListener(queues = RabbitConfig.TOPIC_MSG_QUEUE2)
public void listenDead2(String message) {
System.out.println("消费者二接收消息:" + message);
}
}
Les résultats d'exécution sont les suivants :
Vous pouvez voir que : contrairement au mode de routage, le sujet prend en charge les clés de routage en mode générique ; en particulier, "*" ne peut remplacer qu'un seul mot ; et "#" peut en remplacer plusieurs ;