RabbitMQ学习整理————基于RabbitMQ实现RPC
通过Spring AMQP实现RPC
通过Spring来实现RPC也很简单,主要通过spring提供的一个RabbitTemplate对象中sendAndReceive方法来实现,这个方法是发送消息然后一直等待响应。监听器里面实现的和之前的逻辑大致相同,都需要将response响应消息发送到对应的replyTo回调队列上。下面直接贴一下代码。
首先是服务端,我这边直接是使用配置类的形式,具体一些的配置项可以上网搜一下~
/** * 主配置类 * * @author test * @since 2023/2/11 */ @Configuration public class RabbitMQConfig { private static final Logger log = LoggerFactory.getLogger(RabbitMQConfig.class); // 注入connectionFactory对象 @Bean public ConnectionFactory connectionFactory() { CachingConnectionFactory connectionFactory = new CachingConnectionFactory(); connectionFactory.setAddresses("192.168.1.108:5672"); connectionFactory.setUsername("guest"); connectionFactory.setPassword("guest"); connectionFactory.setVirtualHost("/"); return connectionFactory; } // 声明队列 @Bean public Queue rpcQueue() { return new Queue("test_rpc",false); } @Bean public RabbitTemplate rabbitTemplate() { return new RabbitTemplate(connectionFactory()); } // 创建初始化RabbitAdmin对象 @Bean public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) { RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory); // 只有设置为 true,spring 才会加载 RabbitAdmin 这个类 rabbitAdmin.setAutoStartup(true); return rabbitAdmin; } // 消息监听器 @Bean public SimpleMessageListenerContainer simpleMessageListenerContainer(RabbitTemplate rabbitTemplate) { SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory()); // 监听的队列 container.setQueues(rpcQueue()); MessageListener messageListener = message -> { String receiveMsg = new String(message.getBody(), StandardCharsets.UTF_8); log.info("Receive a message message is {}", receiveMsg); // 执行对应逻辑 String responseMsg = toUpperCase(receiveMsg); MessageProperties messageProperties = MessagePropertiesBuilder.newInstance(). setCorrelationId(message.getMessageProperties().getCorrelationId()). build(); // 响应消息 这边就是如果没有绑定交换机和队列的话 消息应该直接传到对应的队列上面 rabbitTemplate.send("", message.getMessageProperties().getReplyTo(), new Message(responseMsg.getBytes(StandardCharsets.UTF_8), messageProperties)); }; // 设置监听器 container.setMessageListener(messageListener); return container; } // 提供一个大小写转换的方法 private String toUpperCase(String msg) { return msg.toUpperCase(); } }
客户端我采用test单元测试的形式
/** * spring amqp rpc 测试类 * * @author @author test * @since 2023/2/11 */ @ContextConfiguration(classes = {RabbitMQConfig.class}) @RunWith(SpringRunner.class) public class RabbitMQRpcTest { private static final Logger log = LoggerFactory.getLogger(RabbitMQConfig.class); @Autowired private RabbitTemplate rabbitTemplate; // 测试RPC客户端 @Test public void testRpcClient() { // 设置correlationId String corrId = UUID.randomUUID().toString(); String msg = "hello rpc"; MessageProperties messageProperties = MessagePropertiesBuilder.newInstance().setCorrelationId(corrId).build(); // 注意 这边如果使用sendAndReceive不指定replyTo回调队列 spring会默认帮我们添加一个回调队列 // 格式默认 "amq.rabbitmq.reply-to" 前缀 Message message = rabbitTemplate.sendAndReceive("", "test_rpc", new Message(msg.getBytes(StandardCharsets.UTF_8), messageProperties)); log.info("The response is {}", new String(message.getBody(), StandardCharsets.UTF_8));
具体实现可以看下代码的注释,注意这边我的上一篇博客写的基于RabbitMQ实现的RPC框架就是主要使用的Spring AMQP提供的这些方法来实现的。