springboot项目中RabbitMq的使用
springboot项目中RabbitMq的使用
本文结合springboot项目,给出了几种队列的使用。spring版本是2.0.4.RELEASE。
首先需要的在pom中引入如下代码
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
通用设置
- 配置文件 ;需要在application.yml配置文件中添加Mq的连接信息
spring: rabbitmq: addresses: 134.***.**.121:5672 username: admin password: 123456 virtual-host: / connection-timeout: 15000 listener: simple: acknowledge-mode: manual concurrency: 1 max-concurrency: 1
简单队列
-
消费者代码
public class MqListener { //1. 手动创建,需在RabbitMQ中手动创建myQueue1 队列,否则报错 @RabbitListener(queues = "SimpleQueue") //@RabbitHandler @RabbitListener 可以标注在类上面,需配合 @RabbitHandler 注解一起使用 public void process1(String message){ System.out.println("SimpleQueue:"+ message); } //2. 自动创建队列 @RabbitListener(queuesToDeclare = @Queue("myQueue1")) //@RabbitHandler public void process2(String message){ System.out.println("process2:"+ message); } }
-
生产者代码
junit单元测试
@Autowired private AmqpTemplate rabbitTemplate; @Test public void send() { String sendMsg = "hello1 simple queue " + new Date(); System.out.println("Sender1 : " + sendMsg); this.rabbitTemplate.convertAndSend("SimpleQueue", sendMsg); }
单生产者多消费者(work)
一个生产者、2个消费者。
一个消息只能被一个消费者获取。
-
消费者代码
@RabbitListener(queuesToDeclare = @Queue(value = "MyWorkQueue", durable = "true")) //@RabbitHandler public void processWork(Message message, Channel channel){ Map<String, Object> headers=message.getHeaders(); String title=headers.get("title")==null?"":headers.get("title").toString(); try { long deliveryTag = (long) headers.get(AmqpHeaders.DELIVERY_TAG); //当消息处理完毕,执行ACK channel.basicQos(0, 1, false); channel.basicAck(deliveryTag, false); } catch (IOException e) { } System.out.println("process2:"+ title); } //2. 自动创建队列 @RabbitListener(queuesToDeclare = @Queue(value = "MyWorkQueue", durable = "true")) //@RabbitHandler public void processWork2(Message message, Channel channel){ Map<String, Object> headers=message.getHeaders(); String title=headers.get("title")==null?"":headers.get("title").toString(); try { long deliveryTag = (long) headers.get(AmqpHeaders.DELIVERY_TAG); //当消息处理完毕,执行ACK channel.basicQos(0, 1, false); channel.basicAck(deliveryTag, false); } catch (IOException e) { e.printStackTrace(); } System.out.println("process2:"+ title); }
-
生产者代码
@Test public void sendWork() { for(int i=0;i<100;i++){ String message="这是RabbitMq发来的消息: "; Map<String, Object> headers = new HashMap<>(); headers.put("name", "zhangsan"); headers.put("age", "18"); headers.put("title", "苹果"+i); MessageHeaders messageHeaders = new MessageHeaders(headers); Message<Object> msg = MessageBuilder.createMessage(message, messageHeaders); this.rabbitTemplate.convertAndSend("MyWorkQueue",msg); } }
多生产者、多消费者同理。
订阅模式
-
一个生产者对应多个消费者
-
每一个消费者都有自己的队列,这些队列绑定到交换机上。
-
生产者先将消息发送到交换机。
-
生产者发送的消息,经过交换机,到达队列,实现,一个消息被多个消费者获取的目的
-
消费者代码
//消费队列1 @RabbitListener(bindings = @QueueBinding(value = @Queue(value = "subQueue1", durable = "true"), exchange = @Exchange(value = "sub.Exchange", durable = "true", type = "fanout", ignoreDeclarationExceptions = "true"))) @RabbitHandler public void subMessage(Message message, Channel channel) { System.out.println("message:" + message.getPayload()); Map<String, Object> headers=message.getHeaders(); String title=headers.get("title")==null?"":headers.get("title").toString(); try { long deliveryTag = (long) message.getHeaders().get(AmqpHeaders.DELIVERY_TAG); System.out.println("deliveryTag: " + deliveryTag); //当消息处理完毕,执行ACK channel.basicQos(0, 1, false); channel.basicAck(deliveryTag, false); } catch (IOException e) { } System.out.println("订阅模式队列1"); } //消费队列2 @RabbitListener(bindings = @QueueBinding(value = @Queue(value = "subQueue2", durable = "true"), exchange = @Exchange(value = "sub.Exchange", durable = "true", type = "fanout", ignoreDeclarationExceptions = "true"))) @RabbitHandler public void subMessage2(Message message, Channel channel) { System.out.println("message:" + message.getPayload()); Map<String, Object> headers=message.getHeaders(); String title=headers.get("title")==null?"":headers.get("title").toString(); try { long deliveryTag = (long)headers.get(AmqpHeaders.DELIVERY_TAG); System.out.println("deliveryTag: " + deliveryTag); //当消息处理完毕,执行ACK channel.basicQos(0, 1, false); channel.basicAck(deliveryTag, false); } catch (IOException e) { } System.out.println("订阅模式队列2"); }
-
生产者代码
@Test public void sendExchange() { String message="这是RabbitMq发来的消息: "; Map<String, Object> headers = new HashMap<>(); headers.put("name", "北京出版社"); headers.put("title", "杂志订阅"); MessageHeaders messageHeaders = new MessageHeaders(headers); Message<Object> msg = MessageBuilder.createMessage(message, messageHeaders); rabbitTemplate.convertAndSend("sub.Exchange","fanout",msg);//订阅模式 }
路由模式
- 消费者代码
//第一种规则 key 为red @RabbitListener(bindings = @QueueBinding(value = @Queue(value = "routeQueue1", durable = "true"), exchange = @Exchange(value = "route.Exchange", durable = "true", type = "direct", ignoreDeclarationExceptions = "true"),key = "red")) @RabbitHandler public void routeMessage1(Message message, Channel channel) { System.out.println("message:" + message.getPayload()); Map<String, Object> headers=message.getHeaders(); String title=headers.get("title")==null?"":headers.get("title").toString(); try { long deliveryTag = (long)headers.get(AmqpHeaders.DELIVERY_TAG); System.out.println("deliveryTag: " + deliveryTag); //当消息处理完毕,执行ACK channel.basicQos(0, 1, false); channel.basicAck(deliveryTag, false); } catch (IOException e) { } System.out.println("路由模式1"); } //第二种规则 有三种key @RabbitListener(bindings = @QueueBinding(value = @Queue(value = "routeQueue1", durable = "true"), exchange = @Exchange(value = "route.Exchange", durable = "true", type = "direct", ignoreDeclarationExceptions = "true"),key ={"blue","green","black"})) @RabbitHandler public void routeMessage2(Message message, Channel channel) { System.out.println("message:" + message.getPayload()); Map<String, Object> headers=message.getHeaders(); String title=headers.get("title")==null?"":headers.get("title").toString(); try { long deliveryTag = (long)headers.get(AmqpHeaders.DELIVERY_TAG); System.out.println("deliveryTag: " + deliveryTag); //当消息处理完毕,执行ACK channel.basicQos(0, 1, false); channel.basicAck(deliveryTag, false); } catch (IOException e) { } System.out.println("路由模式2"); }
- 生产者代码
@Test public void sendRouteExchange() { String message="这是RabbitMq发来的消息: "; Map<String, Object> headers = new HashMap<>(); headers.put("level", "等级一"); headers.put("title", "红色"); MessageHeaders messageHeaders = new MessageHeaders(headers); Message<Object> msg = MessageBuilder.createMessage(message, messageHeaders); rabbitTemplate.convertAndSend("route.Exchange","red",msg);//路由模式 rabbitTemplate.convertAndSend("route.Exchange","blue",msg);//路由模式 rabbitTemplate.convertAndSend("route.Exchange","black",msg);//路由模式 }
主题模式
- 消费者代码
@RabbitListener(bindings = @QueueBinding(value = @Queue(value = "hd.toutiao.Queue", durable = "true"), exchange = @Exchange(value = "hd.toutiao.Exchange", durable = "true", type = "topic", ignoreDeclarationExceptions = "true"), key = "hd.toutiao.*")) @RabbitHandler public void onMessage(Message message, Channel channel) { System.out.println("message:" + message.getPayload()); Map<String, Object> headers=message.getHeaders(); String title=headers.get("title")==null?"":headers.get("title").toString(); System.out.println(headers); System.out.println("channel:" + channel); try { long deliveryTag = (long) message.getHeaders().get(AmqpHeaders.DELIVERY_TAG); System.out.println("deliveryTag: " + deliveryTag); //当消息处理完毕,执行ACK logger.info("onMessage1:消息执行完毕准备ACK"); channel.basicQos(0, 1, false); channel.basicAck(deliveryTag, false); } catch (IOException e) { e.printStackTrace(); } }
- 生产者代码
public void send(Object message, Map<String, Object> properties) { MessageHeaders messageHeaders = new MessageHeaders(properties); Message<Object> msg = MessageBuilder.createMessage(message, messageHeaders); rabbitTemplate.convertAndSend("hd.toutiao.Exchange", "hd.toutiao.北京市", msg); }