1、引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
2、配置连接
#rabbitmq
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=
spring.rabbitmq.password=
spring.rabbitmq.virtual-host=/
spring.rabbitmq.publisher-confirms=true
3、定义消息对象
/**
* 消息通知
*
* @author kou
*/
@Data
public class MessageNotificationVO {
/**
* 系统消息类型
*/
private SystemMessageType type;
/**
* 用户id
*/
private List<Long> userIds;
/**
* 消息内容
*/
private String subject;
/**
* 发送所有人,true是,false否
*/
private boolean sendAll;
}
4、定义消息队列交换机等
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Arrays;
import java.util.List;
/**
* mq 消息通知配置
*
* @author kou
*/
@Slf4j
@Configuration
public class MessageNotificationMqConfig {
@Autowired
private RabbitTemplate rabbitTemplate;
/**
* 创建消息通知队列
*
* @return 队列
*/
@Bean
public Queue systemMessageQueue() {
return new Queue("message.notification.queue");
}
/**
* 声明消息通知交换机
*
* @return 交换机
*/
@Bean
public Exchange systemMessageExchange() {
return ExchangeBuilder.topicExchange("message.notification.exchange").durable(true).build();
}
/**
* 将队列和交换机绑定
*
* @param systemMessageQueue 系统消息队列
* @param systemMessageExchange 系统消息交换机
* @return 绑定
*/
@Bean
public Binding systemMessageBind(Queue systemMessageQueue, Exchange systemMessageExchange) {
return BindingBuilder.bind(systemMessageQueue).to(systemMessageExchange).with("message.notification").noargs();
}
/**
* 发送消息通知
*
* @param userId 用户id
* @param type 消息类型
* @param msg 消息内容
*/
public void sendSystemMessage(Long userId, SystemMessageType type, String msg) {
sendSystemMessage(Arrays.asList(userId), type, msg, false);
}
/**
* 发送消息通知
*
* @param userId 用户id
* @param type 消息类型
* @param msg 消息内容
* @param sendAll 是否发送所有人,false否,true 是
*/
public void sendSystemMessage(Long userId, SystemMessageType type, String msg, boolean sendAll) {
sendSystemMessage(Arrays.asList(userId), type, msg, sendAll);
}
/**
* 发送消息通知
*
* @param userIds 用户id
* @param type 消息类型
* @param msg 消息内容
*/
public void sendSystemMessage(List<Long> userIds, SystemMessageType type, String msg) {
sendSystemMessage(userIds, type, msg, false);
}
/**
* 发送消息通知
*
* @param userIds 用户id
* @param type 消息类型
* @param msg 消息内容
* @param sendAll 是否发送所有人,false否,true 是
*/
public void sendSystemMessage(List<Long> userIds, SystemMessageType type, String msg, boolean sendAll) {
MessageNotificationVO messageNotification = new MessageNotificationVO();
messageNotification.setUserIds(userIds);
messageNotification.setType(type);
messageNotification.setSubject(msg);
messageNotification.setSendAll(sendAll);
//消息发送处理
sendMessage(messageNotification);
}
/**
* 消息发送处理
*
* @param message 系统消息内容
*/
private void sendMessage(MessageNotificationVO message) {
try {
ObjectMapper mapper = new ObjectMapper();
// 使用消息队列发送
rabbitTemplate.convertAndSend("message.notification.exchange", "message.notification", mapper.writeValueAsString(message));
log.info("消息已发送,消息内容: {}", message.getSubject());
} catch (JsonProcessingException e) {
log.info("消息已发送,消息内容: {}", message.getSubject());
log.error("发送消息失败", e);
}
}
}
5、定义消费者
/**
* 消息通知
*
* @author kou
*/
@Slf4j
@Component
public class MessageNotificationHandler {
/**
* concurrency 启用数量
*/
@RabbitListener(queues = "message.notification.queue", concurrency = "10")
public void sendMessage(Message massage, @Headers Map<String, Object> headers, Channel channel) {
// 唯一标识 ID
Long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
try {
String msg = new String(massage.getBody(), StandardCharsets.UTF_8);
log.info("消息通知接收到的消息: {}", msg);
ObjectMapper mapper = new ObjectMapper();
// 获取消息内容
MessageNotificationVO sysMsg = mapper.readValue(msg, MessageNotificationVO.class);
// todo 处理消息
} catch (IOException e) {
log.error(e.getMessage(), e);
} finally {
try {
// 确认消息,deliveryTag 唯一标识 ID, multiple 第二个参数为true时表示则可以一次性确认 delivery_tag 小于等于传入值的所有消息
channel.basicAck(deliveryTag, false);
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
}
}
6、生产者
// 系统消息发送
systemMessageMqConfig.sendSystemMessage(Arrays.asList(notifyUserId.toString()), SystemMessageType.COMMENT, "我生成了一条消息");