说明
1、此例前提条件:你已实现rabbitmq消息的手动确认模式相关代码,已完成消息监听类和队列的绑定。
2、此例解决:实现ChannelAwareMessageListener接口进行消息监听,消息生产者发送同步消息,阻塞等待接收返回结果。参考官方文档:https://www.rabbitmq.com/tutorials/tutorial-six-java.html
3、使用@RabbitListener注解进行消息监听的同步消息处理更简单,可查看官方文档:https://www.rabbitmq.com/tutorials/tutorial-six-spring-amqp.html
4、依赖引入、初始化MQ配置 这两项为后来补充的内容,只提供思路和参考,具体还要自己看情况实现;
依赖引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
初始化MQ配置
@Configuration
public class RabbitmqContent {
@Autowired
private MyReceiver myReceiver ;
@Bean
public RabbitTemplate rabbitTemplate {
//创建连接,参数自行添加
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses(addresses);
connectionFactory.setUsername(username);
connectionFactory.setPassword(password);
connectionFactory.setVirtualHost(virtualHost);
//connectionFactory.setPublisherReturns(publisherReturns); //回调配置不知道可以去查
//connectionFactory.setPublisherConfirmType(publisherConfirmType);//回调配置
RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
//exchange创建
TopicExchange topicExchange = new TopicExchange("exchange");
rabbitAdmin.declareExchange(topicExchange);
//创建队列
Queue queue = new Queue("queue", true, false, false, arguments);
rabbitAdmin.declareQueue(queue);
//绑定交换机和队列
rabbitAdmin.declareBinding(BindingBuilder.bind(queue).to(topicExchange).with("routingKey"));
//创建监听容器
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
container.addQueueNames("query");
container.setMessageListener(myReceiver);
container.setAutoStartup(true);
container.setExposeListenerChannel(true);
//container.setPrefetchCount(1);//设置每个消费者获取的最大的消息数量
//container.setConcurrentConsumers(1);//消费者个数
container.setAcknowledgeMode(AcknowledgeMode.MANUAL);//设置确认模式为手工确认
container.start();
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
return rabbitTemplate;
}
}
消息生产者
public class RabbitmqServiceImpl implements IRabbitmqService {
@Autowired
private RabbitTemplate rabbitTemplate;
private Object sendMsgSync (String rgn, String topic, String msg) {
String msg = ""; //要发送的信息
try {
MessageProperties messageProperties = new MessageProperties();
Object message = rabbitTemplate.convertSendAndReceive("exchange", "routingKey", new Message(msg.getBytes(Charset.defaultCharset()), messageProperties));
return message;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
消息监听类
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.stereotype.Component;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
@Slf4j
@Component
@AllArgsConstructor
public class MyReceiver implements ChannelAwareMessageListener{
/**
* 接收消息
*/
@Override
public void onMessage(Message message, Channel channel) {
MessageProperties messageProperties = message.getMessageProperties();
try {
String msg = new String(message.getBody(), Charset.defaultCharset());
if (StringUtils.isBlank(msg)) {
return;
}
//TODO 接收到消息业务处理
String json = ""; //业务返回的结果
//RPC模式返回结果
AMQP.BasicProperties props = new AMQP.BasicProperties
.Builder()
.correlationId(messageProperties.getCorrelationId()) //重要
.build();
String replyTo = messageProperties.getReplyTo(); //重要
channel.basicPublish("", replyTo, props, json.getBytes(Charset.defaultCharset())); //这里的交换机为空
} catch (Exception e) {
e.printStackTrace();
}
}
}
相关配置
springBoot整合rabbitMq配置网上很多可以去查;
同步消息发送者超时时间配置
通过springboot的yml配置文件配置
spring:
rabbitmq:
template:
reply-timeout: 10s
通过代码配置
rabbitTemplate.setReplyTimeout(10000L);