简介:
本篇文章是我个人最近学习rabbitMq的一次总结,通过实际框架中的项目配置和代码,来实现rpc风格的rabbitMq的使用,主要分为两个项目,分别实现发送,回复和接受回复的功能。
本篇文章不是rabbitMq的入门篇,所有对于新入门的同学,对exchange,queue,routingKey这些概念还不懂的话,不建议看这篇文章。
主要分为两个项目:
1、spring框架的主要实现发送消息和接受回复消息的功能,以下简称生产者
2、spring boot框架的项目主要实现接受消息和回复消息的功能,以下简称消费者
废话不多说,直接上代码
1、生产者pom.xml片段,主要在原有框架中,添加spring-rabbit的依赖
org.springframework.amqp
spring-rabbit
1.6.5.RELEASE
2、生产者配置文件,在resources下面新建rabbitMq.properties,内容如下
#rabbitMq
mq.ip=192.168.1.100
mq.port=5672
mq.userName=rabbitmq_producer
mq.password=123456
mq.virtualHost=test_vhosts
3、rabbit的spring配置文件,在resources下面新建spring-rabbitMq.xml,同时在web.xml中,像加载别的spring
配置文件一样配置一下。具体内容如下
需要注意的是,springReplyMessageQueue是专门用来回复的队列
4、SysRabbitProductTestController.java. 是写的一个用来测试发送消息并接收回复的测试类,这里面需要注意的是
rabbitTemplate.sendAndReceive() 这个方法是默认等待5秒钟,如果在5秒内没有接收到回复的话,会返回一个空的message,这个默认的时间,实在spring-rabbit.xml中的rabbittemplete的配置的replyTimeout 来设置.
另外:使用sendAndReceive 这个方法发送消息时,消息的
correlationId会变成系统动编制的1,2,3这个样子,而不是我们想要的
uuid的格式。
import com.rabbitmq.client.AMQP;
import com.sime.controller.base.BaseController;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.MessagePropertiesConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.UUID;
/*
*
* rabbitMq 发送测试
*/
@Controller
@RequestMapping("rabbitTest/")
public class SysRabbitProductTestController extends BaseController {
@Autowired
private MessagePropertiesConverter messagePropertiesConverter;
@Autowired
private RabbitTemplate rabbitTemplate;
@RequestMapping("send")
@ResponseBody
public String send(){
String correlationId = UUID.randomUUID().toString();
Date sendTime = new Date();
AMQP.BasicProperties props =
new AMQP.BasicProperties("text/plain",
"UTF-8",
null,
2,
0, correlationId, "springReplyMessageExchange", null,
null, sendTime, null, null,
"SpringProducer", null);
MessageProperties sendMessageProperties =
messagePropertiesConverter.toMessageProperties(props, null,"UTF-8");
sendMessageProperties.setReceivedExchange("springReplyMessageExchange");
sendMessageProperties.setReceivedRoutingKey("springReplyMessage");
sendMessageProperties.setRedelivered(true);
String message = "fa song xiaoxi ------------ 走你";
try {
//发送并接收回执
Message sendMessage = MessageBuilder.withBody(message.getBytes("UTF-8"))
.andProperties(sendMessageProperties)
.build();
Message replyMessage = rabbitTemplate.sendAndReceive("springMessageExchange",
"springMessage", sendMessage);
String replyMessageContent = null;
replyMessageContent = new String(replyMessage.getBody(),"UTF-8");
System.out.println("接收到回执: "+replyMessageContent);
return replyMessageContent;
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
}
6、下面是消费者的pom.xml 的重要片段
org.springframework.boot
spring-boot-starter-amqp
org.springframework.boot
spring-boot-configuration-processor
true
7、application.yml 关于rabbitMq的配置
spring:
rabbitmq:
username: rabbitmq_consumer
host: 192.168.1.100
port: 5672
password: 123456
virtual-host: test_vhosts
8、常量配置类AppConstants
public class AppConstants {
public static final String SEND_QUEUE_NAME = "springMessageQueue";
public static final String SEND_EXCHANGE_NAME = "springMessageExchange";
public static final String SEND_MESSAGE_KEY = "springMessage";
}
9、配置类 RabbitConfig.java
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.sime.constants.AppConstants;
import com.sime.rabbit.FinancMessageListener;
import com.sime.service.UserService;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.config.AbstractRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.MessageListenerContainer;
import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.listener.RabbitListenerEndpoint;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.support.DefaultMessagePropertiesConverter;
import org.springframework.amqp.rabbit.support.MessagePropertiesConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.amqp.support.converter.SimpleMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.amqp.RabbitProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.HashMap;
import java.util.Map;
@Configuration
@EnableConfigurationProperties(RabbitProperties.class)
public class RabbitConfig {
@Autowired
private RabbitProperties rabbitProperties;
@Bean("connectionFactory")
public ConnectionFactory getConnectionFactory() {
com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory =
new com.rabbitmq.client.ConnectionFactory();
rabbitConnectionFactory.setHost(rabbitProperties.getHost());
rabbitConnectionFactory.setPort(rabbitProperties.getPort());
rabbitConnectionFactory.setUsername(rabbitProperties.getUsername());
rabbitConnectionFactory.setPassword(rabbitProperties.getPassword());
rabbitConnectionFactory.setVirtualHost(rabbitProperties.getVirtualHost());
ConnectionFactory connectionFactory = new CachingConnectionFactory(rabbitConnectionFactory);
return connectionFactory;
}
@Bean(name="rabbitAdmin")
public RabbitAdmin getRabbitAdmin() {
RabbitAdmin rabbitAdmin = new RabbitAdmin(getConnectionFactory());
rabbitAdmin.setAutoStartup(true);
return rabbitAdmin;
}
@Bean(name="serializerMessageConverter")
public MessageConverter getMessageConverter(){
return new SimpleMessageConverter();
}
@Bean(name="messagePropertiesConverter")
public MessagePropertiesConverter getMessagePropertiesConverter()
{
return new DefaultMessagePropertiesConverter();
}
@Bean(name="rabbitTemplate")
public RabbitTemplate getRabbitTemplate()
{
RabbitTemplate rabbitTemplate = new RabbitTemplate(getConnectionFactory());
rabbitTemplate.setUseTemporaryReplyQueues(false);
rabbitTemplate.setMessageConverter(getMessageConverter());
rabbitTemplate.setMessagePropertiesConverter(getMessagePropertiesConverter());
return rabbitTemplate;
}
@Bean(name="springMessageQueue")
public Queue createQueue(@Qualifier("rabbitAdmin")RabbitAdmin rabbitAdmin)
{
Queue sendQueue = new Queue(AppConstants.SEND_QUEUE_NAME,true,false,false);
rabbitAdmin.declareQueue(sendQueue);
return sendQueue;
}
@Bean(name="springMessageExchange")
public Exchange createExchange(@Qualifier("rabbitAdmin")RabbitAdmin rabbitAdmin)
{
DirectExchange sendExchange = new DirectExchange(AppConstants.SEND_EXCHANGE_NAME,true,false);
rabbitAdmin.declareExchange(sendExchange);
return sendExchange;
}
@Bean(name="springMessageBinding")
public Binding createMessageBinding(@Qualifier("rabbitAdmin")RabbitAdmin rabbitAdmin)
{
Map arguments = new HashMap();
Binding sendMessageBinding =
new Binding(AppConstants.SEND_QUEUE_NAME, Binding.DestinationType.QUEUE,
AppConstants.SEND_EXCHANGE_NAME, AppConstants.SEND_MESSAGE_KEY, arguments);
rabbitAdmin.declareBinding(sendMessageBinding);
return sendMessageBinding;
}
}
10.消息接收Listener类
public class FinancMessageListener implements ChannelAwareMessageListener {
@Autowired
private MessagePropertiesConverter messagePropertiesConverter;
@Autowired
private UserService userService;
@Autowired
private RabbitTemplate rabbitTemplate;
@Override
public void onMessage(Message message, Channel channel) throws Exception {
System.out.println("+++++++++++++++++++++++++++++接收到消息了+++++++++++++++++++++++++++"+userService);
System.out.println(new String(message.getBody(),"UTF-8"));
try
{
MessageProperties messageProperties = message.getMessageProperties();
AMQP.BasicProperties rabbitMQProperties =
messagePropertiesConverter.fromMessageProperties(messageProperties, "UTF-8");
String messageContent = null;
messageContent = new String(message.getBody(),"UTF-8");
String consumerTag = messageProperties.getConsumerTag();
System.out.println(consumerTag+ " get The message content is:" + messageContent);
/**************************返回消息,5秒以内返回*************************************************/
//RPC回复 ,发送消息
String replyMessageContent = "Consumer1 返回的信息 '" + messageContent +" consumerTag: "+consumerTag+ "'";
String cId = rabbitMQProperties.getCorrelationId();
AMQP.BasicProperties replyRabbitMQProps =
new AMQP.BasicProperties("text/plain",
"UTF-8",
null,
2,
0, cId, null, null,
null, null, null, null,
consumerTag, null);
Envelope replyEnvelope =
new Envelope(messageProperties.getDeliveryTag(), true,
"springReplyMessageExchange", "springReplyMessage");
MessageProperties replyMessageProperties =
messagePropertiesConverter.toMessageProperties(replyRabbitMQProps,
replyEnvelope,"UTF-8");
Message replyMessage = MessageBuilder.withBody(replyMessageContent.getBytes("UTF-8"))
.andProperties(replyMessageProperties)
.build();
rabbitTemplate.send("springReplyMessageExchange","springReplyMessage", replyMessage);
channel.basicAck(messageProperties.getDeliveryTag(), false);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
截止到此,关键的部分的代码就完成了,仅做记录
参考:https://blog.csdn.net/u011126891/article/details/54376179