上篇文章传送门:【springCloud搭建】五、集成mybatis-plus
一、所需jar包
<spring-boot.version>2.3.0.RELEASE</spring-boot.version>
<!--rabbitmq-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
<version>${spring-boot.version}</version>
</dependency>
二、yml配置
默认账户密码guest,默认虚拟机 /,默认端口号5672,web管理端默认端口是15672
因为guest用户只是被容许从localhost访问 所以http://127.0.0.1:15672/ 登录管理端新增用户
spring:
#rabbitMq的配置
rabbitmq:
host: 10.100.2.129
port: 5672
username: wcy
password: wcy123
virtual-host: /
connection-timeout: 6000
三、结构
四、用来传输的消息的对象
package org.wcy.serviceOne;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true)
public class TestMO {
private String msg;
}
五、rabbitMQ 交互机 路由key 队列名等常量类
package org.wcy.common;
public class RabbitMQ {
public static final String SERVICE_ONE_EXCHANGE = "SERVICE_ONE_EXCHANGE";
//生产者发送的消息将会被路由到绑定相同的路由key的队列上
public static final String TEST_KEY_ROUTER = SERVICE_ONE_EXCHANGE+":TEST:ROUTER";
//队列key,队列key必须要唯一否则启动时会报队列已经存在
public static final String TEST_KEY_QUEUE = SERVICE_ONE_EXCHANGE+":TEST:QUEUE";
}
六、rabbitMQ 发送消息到队列
package org.wcy.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.wcy.common.RabbitMQ;
import org.wcy.mapper.TestMapper;
import org.wcy.model.Test;
import org.wcy.service.TestService;
import org.wcy.serviceOne.TestMO;
import java.util.UUID;
@Service
public class TestServiceImpl extends ServiceImpl<TestMapper, Test> implements TestService {
@Autowired
private RabbitTemplate rabbitTemplate;
@Autowired
private ObjectMapper mapper;
@Override
public boolean rabbitMqSend() {
//发送消息到队列
//第一个参数交换机,第二个参数路由key,第三个参数需要发送的消息,第四个参数CorrelationData消息唯一编号
//真正使用过程中可以根据需求将发送消息的代码封装进Util模块内
MessageProperties messageProperties = new MessageProperties();
messageProperties.setType("application/json");
String json;
try {
json = mapper.writeValueAsString(new TestMO().setMsg("发送消息"));
} catch (Exception e) {
throw new IllegalArgumentException("json 序列化 异常");
}
//设置 messageId
if (StringUtils.isEmpty(messageProperties.getMessageId())) {
messageProperties.setMessageId(UUID.randomUUID().toString().replace("-", ""));
}
if (StringUtils.isEmpty(messageProperties.getCorrelationId())) {
// 设置 关联 id
messageProperties.setCorrelationId(UUID.randomUUID().toString().replace("-", ""));
}
Message message = new Message(json.getBytes(), messageProperties);
rabbitTemplate.convertAndSend(RabbitMQ.SERVICE_ONE_EXCHANGE, RabbitMQ.TEST_KEY_ROUTER, message,
new CorrelationData(messageProperties.getCorrelationId()));
return true;
}
}
七、rabbitMQ 监听队列
package org.wcy.rabbitmq;
import com.alibaba.fastjson.JSONObject;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;
import com.rabbitmq.client.Channel;
import org.wcy.common.RabbitMQ;
import org.wcy.serviceOne.TestMO;
import java.io.IOException;
/**
* @Description: 队列监听
* @Author: 王晨阳
* @Date: 2021/6/2-16:17
*/
@Component
public class TestListener {
/**
* @Description: 动态创建队列
* bindings为绑定路由key和队列和交换机, @QueueBinding内配置路由key,队列,交换机
* key:路由key名称,生产者根据这个发送消息
* value:@Queue 队列配置
* -value:队列名
* -durable:是否持久化,ps:必须和exchange内的durable都为true时才是真正的持久化
* -arguments:配置死信队列,x-dead-letter-exchange私信队列交换机名称,x-dead-letter-routing-key私信队列路由key名称/也可以时队列名
* exchange:交换机配置
* -value:交换机名称
* -durable:是否持久化,ps:必须和queue内的durable都为true时才是真正的持久化
* -type:队列类型,默认为直连direct
* -ignoreDeclarationExceptions:当任何异常发生时,RabbitAdmin将立即停止处理所有声明,会导致侦听器容器无法初始化,这个选项设置为true指示RabbitAdmin记录异常,并继续声明其他元素
* 主键@Payload可以自动将消息转换为对象
* @Author: 王晨阳
* @Date: 2021/6/2-16:17
*/
@RabbitListener(bindings = @QueueBinding(
key = RabbitMQ.TEST_KEY_ROUTER,
value = @Queue(value = RabbitMQ.TEST_KEY_QUEUE,
durable="true",
arguments = {@Argument(name = "x-dead-letter-exchange", value = "dead-exchange-test")
, @Argument(name = "x-dead-letter-routing-key", value = "dead-queue-test")}),
exchange = @Exchange(value = RabbitMQ.SERVICE_ONE_EXCHANGE,
durable="true",
type= "direct",
ignoreDeclarationExceptions = "true")))
public void test(@Payload TestMO testMO, Message message, Channel channel) {
try {
//处理业务。。。。。
//应答:第一个参数deliveryTag:该消息的index,第二个参数multiple:是否批量.true:将一次性ack所有小于deliveryTag的消息。
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
// channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
} catch (Exception e){
//拒绝:basicReject方法拒绝deliveryTag对应的消息,第二个参数是否requeue,true则重新入队列,否则丢弃或者进入死信队列
try {
channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
/**
* @Description: 死信队列
* @Author: 王晨阳
* @Date: 2021/6/2-16:17
*/
@RabbitListener(bindings = @QueueBinding(
key = "dead-queue-test",
value = @Queue(value = "dead-queue", durable="true"),
exchange = @Exchange(value = "dead-exchange-test",
durable="true",
type= "direct",
ignoreDeclarationExceptions = "true")))
public void dead(@Payload TestMO testMO, Message message){
System.out.println("dead:" + testMO.toString());
}
}
八、配置监听者序列化
package org.wcy.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component
public class RabbitMQConfig {
/**
* 添加这个类进行序列化解析,会自动识别
* @param objectMapper json序列化实现类
* @author 王晨阳
* @date 2021/5/16-18:26
* @version 0.0.1
*/
@Bean
public MessageConverter jsonMessageConverter(ObjectMapper objectMapper) {
return new Jackson2JsonMessageConverter(objectMapper);
}
}
启动后我们可以通过管理后台看到创建的队列和交换机