一)pom.xml文件和上一篇章保持不变
二)application.properties增加几个确认机制的配置
server.port=8080
spring.application.name=spring-boot-rabbitmq
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=rabbitmq
spring.rabbitmq.password=rabbitmq
spring.rabbitmq.publisher-confirms=true
spring.rabbitmq.publisher-returns=true
# ACK
spring.rabbitmq.listener.direct.acknowledge-mode=manual
spring.rabbitmq.listener.simple.acknowledge-mode=manual
第三步:改造一下Fanout模式的代码
package com.oysept.springboot.fanout.config;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Fanout Exchange: 广播模式或者订阅模式,给Fanout交换机发送消息,绑定了这个交换机的所有队列都收到这个消息。
* @author ouyangjun
*/
@Configuration
public class FanoutRabbitMQConfig {
@Bean
public Queue AMsg() {
return new Queue("fanout.A");
}
@Bean
public Queue BMsg() {
return new Queue("fanout.B");
}
@Bean
public Queue CMsg() {
return new Queue("fanout.C");
}
@Bean
FanoutExchange fanoutExchange() {
return new FanoutExchange("fanoutExchange");
}
@Bean
Binding bindingExchangeA(Queue AMsg,FanoutExchange fanoutExchange) {
return BindingBuilder.bind(AMsg).to(fanoutExchange);
}
@Bean
Binding bindingExchangeB(Queue BMsg, FanoutExchange fanoutExchange) {
return BindingBuilder.bind(BMsg).to(fanoutExchange);
}
@Bean
Binding bindingExchangeC(Queue CMsg, FanoutExchange fanoutExchange) {
return BindingBuilder.bind(CMsg).to(fanoutExchange);
}
}
package com.oysept.springboot.fanout.receiver;
import java.io.IOException;
import java.util.Date;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import com.rabbitmq.client.Channel;
/**
* 给fanout.A队列推送消息
* @author ouyangjun
*/
@Component
@RabbitListener(queues = "fanout.A")
public class HelloAMsgReceiver {
// 接收字符串消息,确认消息收到之后,把消息从队列中移除,如未移除,项目重启之后还会继续推送消息
@RabbitHandler
public void process(String str, Channel channel, Message message) {
System.out.println("-->HelloAMsgReceiver AAAA Println: " + str +", 收到时间: " + new Date());
try {
// 告诉服务器收到这条消息 已经被我消费了 可以在队列删掉 这样以后就不会再发了 否则消息服务器以为这条消息没处理掉 后续还会在发
// 消息的标识,false只确认当前一个消息收到,true确认所有consumer获得的消息
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
System.out.println("-->HelloAMsgReceiver AAAA SUCCESS!");
} catch (IOException e) {
e.printStackTrace();
// ack返回false,并重新回到队列
// channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
// 拒绝消息
// channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
System.out.println("-->HelloAMsgReceiver AAAA FAIL!");
}
}
}
package com.oysept.springboot.fanout.receiver;
import java.io.IOException;
import java.util.Date;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import com.rabbitmq.client.Channel;
/**
* 给fanout.B队列推送消息
* @author ouyangjun
*/
@Component
@RabbitListener(queues = "fanout.B")
public class HelloBMsgReceiver {
// 接收字符串消息,确认消息收到之后,把消息从队列中移除,如未移除,项目重启之后还会继续推送消息
@RabbitHandler
public void process(String str, Channel channel, Message message) {
System.out.println("-->HelloBMsgReceiver BBBB Println: " + str +", 收到时间: " + new Date());
try {
// 告诉服务器收到这条消息 已经被我消费了 可以在队列删掉 这样以后就不会再发了 否则消息服务器以为这条消息没处理掉 后续还会在发
// 消息的标识,false只确认当前一个消息收到,true确认所有consumer获得的消息
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
System.out.println("-->HelloBMsgReceiver BBBB SUCCESS!");
} catch (IOException e) {
e.printStackTrace();
// ack返回false,并重新回到队列
// channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
// 拒绝消息
// channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
System.out.println("-->HelloBMsgReceiver BBBB FAIL!");
}
}
}
package com.oysept.springboot.fanout.receiver;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import com.rabbitmq.client.Channel;
/**
* 给fanout.C队列推送消息
* @author ouyangjun
*/
@Component
@RabbitListener(queues = "fanout.C")
public class HelloCMsgReceiver {
// 接收字符串消息,确认消息收到之后,把消息从队列中移除,如未移除,项目重启之后还会继续推送消息
@RabbitHandler
public void process(String str, Channel channel, Message message) {
System.out.println("-->HelloCMsgReceiver CCCC Println: " + str);
}
}
package com.oysept.springboot.fanout.sender;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Fanout Exchange模式, @Component中的命名主要是为了避免冲突
* @author ouyangjun
*/
@Component(value="fanoutSenderConfirm")
public class HelloSenderConfrim implements RabbitTemplate.ConfirmCallback {
// 用RabbitTemplate,而不用AmqpTemplate
@Autowired
private RabbitTemplate rabbitTemplate;
public void send() {
String str = "Hello Fanout Exchange Msgs Confirm!";
this.rabbitTemplate.setConfirmCallback(this);
// 调用
this.rabbitTemplate.convertAndSend("fanoutExchange", "", str);
}
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
if (!ack) {
System.out.println("HelloSenderConfrim Confirm 消息发送失败。" + cause + correlationData.toString());
} else {
System.out.println("HelloSenderConfrim Confirm 消息发送成功。 ");
}
}
}
package com.oysept.springboot.fanout.sender;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Fanout Exchange模式, @Component中的命名主要是为了避免冲突
* @author ouyangjun
*/
@Component(value="fanoutSenderReturn")
public class HelloSenderReturn implements RabbitTemplate.ReturnCallback {
// 用RabbitTemplate,而不用AmqpTemplate
@Autowired
private RabbitTemplate rabbitTemplate;
public void send() {
String str = "Hello Fanout Exchange Msgs Return!";
this.rabbitTemplate.setReturnCallback(this);
this.rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
if (!ack) {
System.out.println("HelloSenderReturn Return 消息发送失败。" + cause + correlationData.toString());
} else {
System.out.println("HelloSenderReturn Return 消息发送成功。 ");
}
});
// 调用
this.rabbitTemplate.convertAndSend("fanoutExchange", "", str);
}
@Override
public void returnedMessage(Message message, int i, String s, String s1, String s2) {
System.out.println("-->HelloSenderReturn return success" + message.toString()+"==="+i+"==="+s1+"==="+s2);
}
}
先启动springboot项目,再运行测试工具类
package com.oysept.springboot.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.oysept.springboot.fanout.sender.HelloSenderConfrim;
import com.oysept.springboot.fanout.sender.HelloSenderReturn;
@RunWith(SpringRunner.class)
@SpringBootTest
public class FanoutHelloTest {
@Autowired
private HelloSenderReturn helloSenderReturn;
@Autowired
private HelloSenderConfrim helloSenderConfrim;
// 测试
@Test
public void helloMsgReturn() throws Exception {
helloSenderReturn.send();
}
// 测试
@Test
public void helloMsgConfirm() throws Exception {
helloSenderConfrim.send();
}
}
识别二维码关注个人微信公众号
本章完结,待续,欢迎转载!
本文说明:该文章属于原创,如需转载,请标明文章转载来源!