环境:spring boot 和 rabbitMQ
关于sping boot 和 rabbitMQ 的知识,这里简单说下,详细的还是请看官方文档
rabbitMQ,是个消息队列,用于接收和发送消息,下面演示即从这两个方面入手
一:接收
1.首先在pom.xml中加入 rabbitMQ的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
<exclusions>
<exclusion>
<artifactId>log4j-over-slf4j</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
创建一个rabbitMQ的配置文件 RabbitConfig,
@Configuration
@EnableRabbit
public class RabbitConfig{
private String host = “”; //地址
private int port = “”; //端口号
private String username=“”; //用户名
private String password=“”;//密码
public static final String EXCHANE = "product" //交换机
public static final String ROUTINGKEY = "" //路由键
public static final String QUEUE = "product_queue"; //消息队列名称
//创建连接工厂
@Bean
public ConnectionFactory connectionFactory() {
//把基本参数带入,创建连接工厂
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setHost(host);
connectionFactory.setPort(port);
connectionFactory.setUsername(username);
connectionFactory.setPassword(password);
connectionFactory.setPublisherConfirms(true); // enable confirm mode
return connectionFactory;
}
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
//声明作用域prototype类型
public RabbitTemplate rabbitTemplate() {
RabbitTemplate template = new RabbitTemplate(connectionFactory());
return template;
}
//创建队列
@Bean
Queue queueproduct() {
return new Queue(QUEUE, true);
}
//声明交换机接收方式为广播模式
@Bean
FanoutExchange exchangeproduct() {
return new FanoutExchange(EXCHANGE);
}
//将交换机和队列进行绑定
@Bean
Binding bindingproduct() {
return BindingBuilder.bind(queueproduct()).to(exchangeproduct());
}
//创建监听容器
@Bean
public SimpleMessageListenerContainer messageContainer() {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory());
container.setQueues(queueproduct()); //将队列放入监听容器
container.setExposeListenerChannel(true); //监听通道打开
container.setMaxConcurrentConsumers(3);//最大消费者也就是接收者设置为3
container.setConcurrentConsumers(1);//每次消费者接收时,都是当前的消费者去接
container.setAcknowledgeMode(AcknowledgeMode.MANUAL); //设置确认模式手工确认
//设置监听通道
container.setMessageListener(new ChannelAwareMessageListener() {
@Override
public void onMessage(Message message, Channel channel) throws Exception {
byte[] body = message.getBody();
try {
//将json字符串转换为json对象
JSONObject obj = new JSONObject(new String(body));
String data = obj.getString("data");
//定义消息接受处理类,针对接收到的json数据进行解析
MainMessage messageBean = new MainMessage(data);
mainMessageProcess.process(messageBean);
} catch (Exception e) {
log.error(e.getMessage());
}
//确认消息成功消费
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
}
});
return container;
}
}
总结:上面接收方式为 Fanout 模式,简单来说,发送方发数据只要发到交换机上面就行了,而,交换机上面,可以绑定多个队列,这些队列上都会接受到消息,这就是广播模式,因此上面配置的 路由键,就用不到,还有另一种方式,就是direct 模式,就是点对点,这时,需要设置路由建,发送方发数据时,也要明确,发给哪个路由建,接受方就根据路由建来接受消息。 各个场景不同,接受的方式也就不同。
二:发送
同样新建一个类,RabbitSendConfig
@Configuration
public class RabbitSendConfig{
//定义交换机
public static final String SEND_EXCHANGE = "product_exchange";
//定义队列
public static final String SEND_QUEUE = "product_queue" ;
//定义路由建
public static final String SEND_ROUTINGKEY ="product_routekey";
//创建队列
@Bean
Queue sendQueue() {
return new Queue(SEND_QUEUE, true);
}
//创建交换机,并且为广播模式
@Bean
FanoutExchange sendExchange() {
return new FanoutExchange(SEND_EXCHANGE);
}
//队列和交换机进行绑定
@Bean
Binding sendBinding() {
return BindingBuilder.bind(sendQueue()).to(sendExchange());
}
}
到这里,配置已经OK,下面就开始发送
执行下面语句:
//这是开始声明rabbitConfig
private RabbitConfig commonRabbit ;
RabbitTemplate template = commonRabbit.rabbitTemplate();
//第一个参数,交换机的名称,第二个是路由建,为null,最后一个是需要发送的消息,toJSONString 里面是调用了阿里的fastjson 去除空格的方法
template.convertAndSend(exchange,null, JSONObject.toJSONString(message, SerializerFeature.WriteMapNullValue));
//如果发送方式是位direct
则修改发送的方式为
@Bean
DirectExchange sendExchange()
{
return new DirectExchange(SEND_EXCHANGE,true,true);
}
那最后发送的第二个参数,修改为 你需要发送给的路由建