作者 王勇

初步完成发送消息,并异步保存至数据库

@@ -5,6 +5,7 @@ import org.springframework.boot.SpringApplication; @@ -5,6 +5,7 @@ import org.springframework.boot.SpringApplication;
5 import org.springframework.boot.autoconfigure.SpringBootApplication; 5 import org.springframework.boot.autoconfigure.SpringBootApplication;
6 import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 6 import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
7 import org.springframework.cloud.openfeign.EnableFeignClients; 7 import org.springframework.cloud.openfeign.EnableFeignClients;
  8 +import org.springframework.scheduling.annotation.EnableAsync;
8 import org.springframework.scheduling.annotation.EnableScheduling; 9 import org.springframework.scheduling.annotation.EnableScheduling;
9 import org.springframework.transaction.annotation.EnableTransactionManagement; 10 import org.springframework.transaction.annotation.EnableTransactionManagement;
10 11
@@ -17,6 +18,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement; @@ -17,6 +18,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
17 @EnableEurekaClient 18 @EnableEurekaClient
18 @EnableTransactionManagement 19 @EnableTransactionManagement
19 @EnableScheduling 20 @EnableScheduling
  21 +@EnableAsync
20 public class MessageBusServiceApplication { 22 public class MessageBusServiceApplication {
21 23
22 public static void main(String[] args) { 24 public static void main(String[] args) {
@@ -5,8 +5,11 @@ import com.sunyo.wlpt.message.bus.service.exception.CustomExceptionType; @@ -5,8 +5,11 @@ import com.sunyo.wlpt.message.bus.service.exception.CustomExceptionType;
5 import com.sunyo.wlpt.message.bus.service.rabbit.utils.DirectUtils; 5 import com.sunyo.wlpt.message.bus.service.rabbit.utils.DirectUtils;
6 import com.sunyo.wlpt.message.bus.service.rabbit.utils.RabbitUtils; 6 import com.sunyo.wlpt.message.bus.service.rabbit.utils.RabbitUtils;
7 import com.sunyo.wlpt.message.bus.service.response.ResultJson; 7 import com.sunyo.wlpt.message.bus.service.response.ResultJson;
  8 +import com.sunyo.wlpt.message.bus.service.service.AsyncTaskService;
  9 +import com.sunyo.wlpt.message.bus.service.service.MessageNoteService;
8 import com.sunyo.wlpt.message.bus.service.service.UserMessageBindingService; 10 import com.sunyo.wlpt.message.bus.service.service.UserMessageBindingService;
9 import com.sunyo.wlpt.message.bus.service.utils.XmlUtils; 11 import com.sunyo.wlpt.message.bus.service.utils.XmlUtils;
  12 +import lombok.extern.slf4j.Slf4j;
10 import org.dom4j.DocumentException; 13 import org.dom4j.DocumentException;
11 import org.springframework.format.annotation.DateTimeFormat; 14 import org.springframework.format.annotation.DateTimeFormat;
12 import org.springframework.web.bind.annotation.*; 15 import org.springframework.web.bind.annotation.*;
@@ -21,6 +24,7 @@ import java.util.concurrent.TimeoutException; @@ -21,6 +24,7 @@ import java.util.concurrent.TimeoutException;
21 * Description: 24 * Description:
22 * 时间:2020/7/16 14:46 25 * 时间:2020/7/16 14:46
23 */ 26 */
  27 +@Slf4j
24 @CrossOrigin 28 @CrossOrigin
25 @RequestMapping("bus/rabbit") 29 @RequestMapping("bus/rabbit")
26 @RestController 30 @RestController
@@ -32,11 +36,17 @@ public class RabbitController { @@ -32,11 +36,17 @@ public class RabbitController {
32 private XmlUtils xmlUtils; 36 private XmlUtils xmlUtils;
33 37
34 @Resource 38 @Resource
  39 + private MessageNoteService messageNoteService;
  40 +
  41 + @Resource
35 private RabbitUtils rabbitUtils; 42 private RabbitUtils rabbitUtils;
36 43
37 @Resource 44 @Resource
38 private DirectUtils directUtils; 45 private DirectUtils directUtils;
39 46
  47 + @Resource
  48 + private AsyncTaskService asyncTaskService;
  49 +
40 @GetMapping("/test/consumer") 50 @GetMapping("/test/consumer")
41 public void consumer() throws IOException, TimeoutException 51 public void consumer() throws IOException, TimeoutException
42 { 52 {
@@ -103,8 +113,20 @@ public class RabbitController { @@ -103,8 +113,20 @@ public class RabbitController {
103 return ResultJson.error(CustomExceptionType.BINDING_ERROR); 113 return ResultJson.error(CustomExceptionType.BINDING_ERROR);
104 } 114 }
105 // 4、mq发送消息,数据库中保存消息 115 // 4、mq发送消息,数据库中保存消息
106 - ResultJson result = directUtils.sendMessage(sentData); 116 +// ResultJson result = directUtils.sendMessage(sentData);
  117 +// if (CustomExceptionType.MESSAGE_SUCCESS.getCode().equals(result.getCode())) {
  118 +// // mq发送消息成功之后,将消息存储于数据库
  119 +// messageNoteService.insertMessageSelective(sentData);
  120 +// }
  121 + return sendAndSave(sentData);
  122 + }
107 123
  124 + public ResultJson sendAndSave(XmlData sentData) throws Exception
  125 + {
  126 + // 4、mq发送消息,数据库中保存消息
  127 + ResultJson result = directUtils.sendMessage(sentData);
  128 + // 异步,保存消息记录
  129 + asyncTaskService.saveMessage(sentData);
108 return result; 130 return result;
109 } 131 }
110 } 132 }
1 package com.sunyo.wlpt.message.bus.service.mapper; 1 package com.sunyo.wlpt.message.bus.service.mapper;
2 2
3 import com.sunyo.wlpt.message.bus.service.domain.MessageNote; 3 import com.sunyo.wlpt.message.bus.service.domain.MessageNote;
4 -import org.apache.ibatis.annotations.Mapper;import org.apache.ibatis.annotations.Param;import java.util.List; 4 +import org.apache.ibatis.annotations.Mapper;
  5 +import org.apache.ibatis.annotations.Param;
  6 +
  7 +import java.util.List;
5 8
6 /** 9 /**
7 * @author 子诚 10 * @author 子诚
@@ -72,4 +75,5 @@ public interface MessageNoteMapper { @@ -72,4 +75,5 @@ public interface MessageNoteMapper {
72 * @param deleteTime 删除的时间 75 * @param deleteTime 删除的时间
73 */ 76 */
74 void autoDelete(@Param("deleteTime") Integer deleteTime); 77 void autoDelete(@Param("deleteTime") Integer deleteTime);
  78 +
75 } 79 }
@@ -234,9 +234,7 @@ public class DirectUtils { @@ -234,9 +234,7 @@ public class DirectUtils {
234 234
235 public ResultJson directProducer(XmlData xmlData) throws Exception 235 public ResultJson directProducer(XmlData xmlData) throws Exception
236 { 236 {
237 - // 1、创建ConnectionFactory  
238 - // (String hostIp, int hostPort, String vHostName, String userName, String password) throws Exception  
239 - // 237 + // 1、创建Connection
240 Connection connection = getConnection(xmlData.getServerIp(), xmlData.getServerPort(), 238 Connection connection = getConnection(xmlData.getServerIp(), xmlData.getServerPort(),
241 xmlData.getVirtualHostName(), xmlData.getSender(), xmlData.getPassword()); 239 xmlData.getVirtualHostName(), xmlData.getSender(), xmlData.getPassword());
242 // 2、 通过Connection创建一个新的Channel 240 // 2、 通过Connection创建一个新的Channel
@@ -245,8 +243,8 @@ public class DirectUtils { @@ -245,8 +243,8 @@ public class DirectUtils {
245 channel.confirmSelect(); 243 channel.confirmSelect();
246 // 4、避免消息被重复消费 244 // 4、避免消息被重复消费
247 AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder() 245 AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder()
248 - // 指定消息是否需要持久化,1:需要持久化;2:不需要持久化  
249 - .deliveryMode(1) 246 + // 指定消息是否需要持久化,2:持久化;1.非持久化
  247 + .deliveryMode(2)
250 // 设置全局唯一消息机制id(雪花id) 248 // 设置全局唯一消息机制id(雪花id)
251 .messageId(IdUtils.generateId()) 249 .messageId(IdUtils.generateId())
252 .build(); 250 .build();
@@ -263,6 +261,7 @@ public class DirectUtils { @@ -263,6 +261,7 @@ public class DirectUtils {
263 // 6、发送消息,并指定 mandatory 参数为true 261 // 6、发送消息,并指定 mandatory 参数为true
264 channel.basicPublish(xmlData.getExchangeName(), xmlData.getRoutingKeyName(), true, properties, 262 channel.basicPublish(xmlData.getExchangeName(), xmlData.getRoutingKeyName(), true, properties,
265 xmlData.getSendContent().getBytes()); 263 xmlData.getSendContent().getBytes());
  264 +
266 log.info("消息生产者,目标交换机:{};路由键:{};发送信息:{}", xmlData.getExchangeName(), xmlData.getRoutingKeyName(), 265 log.info("消息生产者,目标交换机:{};路由键:{};发送信息:{}", xmlData.getExchangeName(), xmlData.getRoutingKeyName(),
267 xmlData.getSendContent().getBytes()); 266 xmlData.getSendContent().getBytes());
268 // 7、添加一个异步 confirm 确认监听,用于发送消息到Broker端之后,回送消息的监听 267 // 7、添加一个异步 confirm 确认监听,用于发送消息到Broker端之后,回送消息的监听
@@ -24,7 +24,7 @@ public class ResultJson<T> implements Serializable { @@ -24,7 +24,7 @@ public class ResultJson<T> implements Serializable {
24 /** 24 /**
25 * 响应消息 25 * 响应消息
26 */ 26 */
27 - private String msg = ""; 27 + private String msg;
28 28
29 /** 29 /**
30 * 错误消息内容 30 * 错误消息内容
@@ -103,7 +103,10 @@ public class ResultJson<T> implements Serializable { @@ -103,7 +103,10 @@ public class ResultJson<T> implements Serializable {
103 { 103 {
104 return new ResultJson<>("200", message, data); 104 return new ResultJson<>("200", message, data);
105 } 105 }
106 - 106 + public static ResultJson success(CustomExceptionType customExceptionType)
  107 + {
  108 + return new ResultJson<>(customExceptionType.getCode(), customExceptionType.getMsg());
  109 + }
107 /** 110 /**
108 * 请求出现异常时的响应数据封装 111 * 请求出现异常时的响应数据封装
109 * 112 *
  1 +package com.sunyo.wlpt.message.bus.service.service;
  2 +
  3 +import com.sunyo.wlpt.message.bus.service.domain.XmlData;
  4 +import org.springframework.scheduling.annotation.Async;
  5 +import org.springframework.stereotype.Component;
  6 +
  7 +import javax.annotation.Resource;
  8 +
  9 +/**
  10 + * @author 子诚
  11 + * Description:这个Service,用来保存异步任务;
  12 + * 注意点:异步任务需要单独放在一个类中
  13 + * 时间:2020/7/30 15:59
  14 + */
  15 +@Component
  16 +public class AsyncTaskService {
  17 +
  18 + @Resource
  19 + private MessageNoteService messageNoteService;
  20 +
  21 + @Async
  22 + public void saveMessage(XmlData sentData)
  23 + {
  24 + // 无论消息是否发送成功,将消息存储于数据库
  25 + messageNoteService.insertMessageSelective(sentData);
  26 + }
  27 +}
@@ -2,6 +2,7 @@ package com.sunyo.wlpt.message.bus.service.service; @@ -2,6 +2,7 @@ package com.sunyo.wlpt.message.bus.service.service;
2 2
3 import com.github.pagehelper.PageInfo; 3 import com.github.pagehelper.PageInfo;
4 import com.sunyo.wlpt.message.bus.service.domain.MessageNote; 4 import com.sunyo.wlpt.message.bus.service.domain.MessageNote;
  5 +import com.sunyo.wlpt.message.bus.service.domain.XmlData;
5 6
6 /** 7 /**
7 * @author 子诚 8 * @author 子诚
@@ -74,6 +75,15 @@ public interface MessageNoteService { @@ -74,6 +75,15 @@ public interface MessageNoteService {
74 * @param deleteTime 删除的时间 75 * @param deleteTime 删除的时间
75 */ 76 */
76 void autoDelete(Integer deleteTime); 77 void autoDelete(Integer deleteTime);
  78 +
  79 +
  80 + /**
  81 + * 存储MQ发送的消息于数据库
  82 + *
  83 + * @param xmlData {@link XmlData}
  84 + * @return 插入数量
  85 + */
  86 + int insertMessageSelective(XmlData xmlData);
77 } 87 }
78 88
79 89
@@ -124,6 +124,34 @@ public class MessageNoteServiceImpl implements MessageNoteService { @@ -124,6 +124,34 @@ public class MessageNoteServiceImpl implements MessageNoteService {
124 } 124 }
125 125
126 126
  127 + @Override
  128 + public int insertMessageSelective(XmlData xmlData)
  129 + {
  130 + String description = "序列-->" + xmlData.getSequence() + "; token-->" + xmlData.getToken();
  131 + MessageNote messageNote = MessageNote.builder()
  132 + .id(IdUtils.generateId())
  133 + // 发送者
  134 + .username(xmlData.getSender())
  135 + // 服务器
  136 + .serverName(xmlData.getServerName())
  137 + // 虚拟主机
  138 + .virtualHostName(xmlData.getVirtualHostName())
  139 + // 交换机
  140 + .exchangeName(xmlData.getExchangeName())
  141 + // 路由键
  142 + .routingKeyName(xmlData.getRoutingKeyName())
  143 + // 发送时间
  144 + .sendTime(xmlData.getSendDateTime())
  145 + // 消息内容
  146 + .sendContent(xmlData.getSendContent().getBytes())
  147 + // 描述:序列+token,or 自我描述
  148 + .description(description)
  149 + .build();
  150 + int num = messageNoteMapper.insertSelective(messageNote);
  151 + return num;
  152 + }
  153 +
  154 +
127 /** 155 /**
128 * 填充名称(使用get方法,如果不存在就会报空指针异常) 156 * 填充名称(使用get方法,如果不存在就会报空指针异常)
129 * 157 *