说到RPC(RemoteProcedureCallProtocol远程过程调用协议),小伙伴们脑海中浮现的估计有RESTfulAPI、Dubbo、WebService、JavaRMI、CORBA等。其实RabbitMQ也为我们提供了RPC功能,使用起来非常简单。今天宋哥就通过一个简单的案例和大家分享一下SpringBoot+RabbitMQ是如何实现一个简单的RPC调用的。注意,有些小伙伴可能对RabbitMQ实现RPC调用有一些误解,认为这不简单?创建两个消息队列queue_1和queue_2。首先,client向queue_1发送消息,server在queue_1上监听消息。收到后,进行处理;处理完成后,服务端向queue_2队列发送消息,然后客户端监听queue_2队列上的消息,这样就知道服务端的处理结果了。这个方法也不是不行,就是有点麻烦!RabbitMQ提供了现成的解决方案,可以直接使用,非常方便。接下来我们一起学习吧。1.架构首先我们来看一个简单的架构图:这个图把问题说的很清楚了:首先,Client发送消息。与普通消息相比,这条消息多了两个关键内容:一是correlation_id,表示这条消息的唯一id,内容是reply_to,表示消息回复队列的名称。服务器从消息发送队列中获取消息,并处理相应的业务逻辑。处理完成后,将处理结果发送到reply_to指定的回调队列。客户端从回调队列中读取消息以了解消息的执行情况。这种情况其实很适合处理异步调用。2.实践接下来我们通过一个具体的例子来看看这是如何实现的。2.1客户端开发首先,我们创建一个名为producer的SpringBoot项目。作为消息生产者,在创建时添加web和rabbitmq依赖,如下图:项目创建成功后,首先在application.properties中配置RabbitMQ的基本信息,如下:spring.rabbitmq.host=localhostspring.rabbitmq.port=5672spring.rabbitmq.username=guestspring.rabbitmq.password=guestspring.rabbitmq.publisher-confirm-type=correlatedspring.rabbitmq.publisher-returns=true这个配置的前四行很容易理解,所以我不会详细介绍。接下来两行:首先,配置消息确认方式。我们通过相关确认。只有启用此配置后,correlation_id才会包含在以后的消息中。只有通过correlation_id才能发送消息和链接返回值。最后一行配置是开启发送失败返回。接下来我们提供一个配置类,如下:www.javaboy.org*@微信a_java_boy*@GitHubhttps://github.com/lenve*@Giteehttps://gitee.com/lenve*/@ConfigurationpublicclassRabbitConfig{publicstaticfinalStringRPC_QUEUE1="queue_1";publicstaticfinalStringRPC_QUEUE2="queue_2";publicstaticfinalStringRPC_EXCHANGE="rpc_exchange";/***设置消息发送RPC队列*/@BeanQueuemsgQueue(){returnnewQueue(RPC_QUEUE1);}/***设置返回队列*/@BeanQueuereplyQueue(){returnnewQueue(RPC_QUEUE2);}/***设置交换*/@BeanTopicExchangeexchange(){returnnewTopicExchange(RPC_EXCHANGE);}/***请求队列和交换绑定*/@BeanBindingmsgBinding(){returnBindingBuilder.bind(msgQueue()).to(exchange()).with(RPC_QUEUE1);}/***返回队列和交换绑定*/@BeanBindingreplyBinding(){returnBindingBuilder.bind(replyQueue()).to(exchange()).with(RPC_QUEUE2);}/***使用RabbitTemplate发送接收消息*并设置回调队列地址s*/@BeanRabbitTemplaterabbitTemplate(ConnectionFactoryconnectionFactory){RabbitTemplatetemplate=newRabbitTemplate(connectionFactory);template.setReplyAddress(RPC_QUEUE2);template.setReplyTimeout(6000);returntemplate;}/***设置返回队列的监听器*/@BeanSimpleMessageListenerContainerreplyContainer(ConnectionFactoryconnectionFactory){SimpleMessageListenerContainerContainercontainer=newSimpleMessengactory(Listen)connectionFactory);container.setQueueNames(RPC_QUEUE2);container.setMessageListener(rabbitTemplate(connectionFactory));返回容器;绑定开关是RabbitMQ的常规操作,所以没什么好说的。在SpringBoot中,我们负责发送消息的工具是RabbitTemplate。默认情况下,系统会自动提供这个工具,但是这里我们需要重新自定义这个工具,主要是添加消息发送的返回队列,最后我们需要给返回队列设置一个监听器。好了,那我们就可以开始发具体消息了:javaboy.org*@微信a_java_boy*@GitHubhttps://github.com/lenve*@Giteehttps://gitee.com/lenve*/@RestControllerpublicclassRpcClientController{privatestaticfinalLoggerlogger=LoggerFactory.getLogger(RpcClientController.class);@AutowiredprivateRabbitTemplaterabbitTemplate;@GetMapping("/send")publicStringsend(Stringmessage){//创建消息对象MessagenewMessage=MessageBuilder.withBody(message.getBytes()).build();logger.info("clientsend:{}",newMessage);//客户端发送消息Messageresult=rabbitTemplate.sendAndReceive(RabbitConfig.RPC_EXCHANGE,RabbitConfig.RPC_QUEUE1,newMessage);Stringresponse="";if(result!=null){//获取发送消息的correlationIdStringcorrelationId=newMessage。getMessageProperties().getCorrelationId();logger.info("correlationId:{}",correlationId);//获取响应头信息HashMap
