1 基础预览

  • 1.1 环境准备
  1. Springboot 1.5.6.RELEAS
  2. Springcloud Dalston.SR2
  • 1.2 交换机类型

交换机是用来发送消息的AMQP实体。交换机拿到一个消息之后将它路由给一个或零个队列。它使用哪种路由算法是由交换机类型和被称作绑定(bindings)的规则所决定的。AMQP 0-9-1的代理提供了四种交换机

Name(交换机类型) Default pre-declared names(预声明的默认名称) 
Direct exchange(直连交换机) (Empty string) and amq.direct 
Fanout exchange(扇型交换机) amq.fanout 
Topic exchange(主题交换机) amq.topic 
Headers exchange(头交换机) amq.match (and amq.headers in RabbitMQ)

  • 1.3 绑定

绑定(Binding)是交换机(exchange)将消息(message)路由给队列(queue)所需遵循的规则。如果要指示交换机“E”将消息路由给队列“Q”,那么“Q”就需要与“E”进行绑定。绑定操作需要定义一个可选的路由键(routing key)属性给某些类型的交换机。路由键的意义在于从发送给交换机的众多消息中选择出某些消息,将其路由给绑定的队列。

打个比方:

队列(queue)是我们想要去的位于纽约的目的地 
交换机(exchange)是JFK机场 
绑定(binding)就是JFK机场到目的地的路线。能够到达目的地的路线可以是一条或者多条 
拥有了交换机这个中间层,很多由发布者直接到队列难以实现的路由方案能够得以实现,并且避免了应用开发者的许多重复劳动。

如果AMQP的消息无法路由到队列(例如,发送到的交换机没有绑定队列),消息会被就地销毁或者返还给发布者。如何处理取决于发布者设置的消息属性。

  • 1.4 ack机制

RabbitMq默认是ack机制:no-ack的方式

执行一个任务可能需要花费几秒钟,你可能会担心如果一个消费者在执行任务过程中挂掉了。一旦RabbitMQ将消息分发给了消费者,就会从内存中删除。在这种情况下,如果正在执行任务的消费者宕机,会丢失正在处理的消息和分发给这个消费者但尚未处理的消息。

实际项目需要手动ack机制 - 见下问实战代码

  • 1.5 消息重复消费

用户在停止查询时,会导致消费者进程被杀死,因此ACK状态码未反馈至MQ,从而消息一直存留在MQ中,当新的消费者启动时会重新消费;

接受消息后-消费消息前,db或者redis nosql检查消息消费状态 - 见下问实战代码

2 配置准备

  • 2.1 pom
  1. <!-- rabbbit.mq -->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-amqp</artifactId>
  5. </dependency>
  • 2.2 rabbitMQ config
  1. package com.ttd.trustProduct.mq.rabbit;
  2. import org.springframework.amqp.core.Binding;
  3. import org.springframework.amqp.core.BindingBuilder;
  4. import org.springframework.amqp.core.FanoutExchange;
  5. import org.springframework.amqp.core.Queue;
  6. import org.springframework.amqp.core.TopicExchange;
  7. import org.springframework.amqp.rabbit.annotation.EnableRabbit;
  8. import org.springframework.context.annotation.Bean;
  9. import org.springframework.context.annotation.Configuration;
  10. /**
  11. * rabbit 配置
  12. *
  13. * @author wolf
  14. */
  15. @Configuration
  16. @EnableRabbit
  17. public class RabbitConfiguration {
  18. //===============以下是验证topic Exchange的队列==========
  19. @Bean
  20. public Queue productMessage() {
  21. return new Queue("ttd.trust.product");
  22. }
  23. @Bean
  24. public Queue allMessages() {
  25. return new Queue("ttd.all");
  26. }
  27. @Bean
  28. TopicExchange exchange() {
  29. return new TopicExchange("exchange");
  30. }
  31. /**
  32. * 将队列topic.message与exchange绑定,binding_key为topic.message,就是完全匹配
  33. *
  34. * @param queueMessage
  35. * @param exchange
  36. * @return
  37. */
  38. @Bean
  39. Binding bindingExchangeMessage(Queue productMessage, TopicExchange exchange) {
  40. return BindingBuilder.bind(productMessage).to(exchange).with("ttd.trust.product");
  41. }
  42. /**
  43. * 将队列topic.messages与exchange绑定,binding_key为topic.#,模糊匹配
  44. *
  45. * @param queueMessage
  46. * @param exchange
  47. * @return
  48. */
  49. @Bean
  50. Binding bindingExchangeMessages(Queue allMessages, TopicExchange exchange) {
  51. return BindingBuilder.bind(allMessages).to(exchange).with("ttd.#");
  52. }
  53. //===============以上是验证topic Exchange的队列==========
  54. //===============以下是验证Fanout Exchange的队列==========
  55. @Bean
  56. public Queue AMessage() {
  57. return new Queue("fanout.A");
  58. }
  59. @Bean
  60. public Queue BMessage() {
  61. return new Queue("fanout.B");
  62. }
  63. @Bean
  64. public Queue CMessage() {
  65. return new Queue("fanout.C");
  66. }
  67. @Bean
  68. FanoutExchange fanoutExchange() {
  69. return new FanoutExchange("fanoutExchange");
  70. }
  71. @Bean
  72. Binding bindingExchangeA(Queue AMessage, FanoutExchange fanoutExchange) {
  73. return BindingBuilder.bind(AMessage).to(fanoutExchange);
  74. }
  75. @Bean
  76. Binding bindingExchangeB(Queue BMessage, FanoutExchange fanoutExchange) {
  77. return BindingBuilder.bind(BMessage).to(fanoutExchange);
  78. }
  79. @Bean
  80. Binding bindingExchangeC(Queue CMessage, FanoutExchange fanoutExchange) {
  81. return BindingBuilder.bind(CMessage).to(fanoutExchange);
  82. }
  83. //===============以上是验证Fanout Exchange的队列==========
  84. @Bean
  85. public Queue helloQueue() {
  86. return new Queue("newhelloQueue");
  87. }
  88. }
  • 2.4 数据交换协议
  1. package com.ttd.sdk.common;
  2. import java.io.Serializable;
  3. import java.util.Date;
  4. import java.util.Map;
  5. import com.alibaba.fastjson.JSON;
  6. import com.ttd.sdk.util.DateUtil;
  7. import com.ttd.sdk.util.RandomUtils;
  8. /**
  9. * 消息体
  10. *
  11. * @author wolf
  12. *
  13. */
  14. public class MQMessage implements Serializable {
  15. private static final long serialVersionUID = 1L;
  16. private Integer productCode; // 生产者代码
  17. private Integer consumerCode; // 消费者代码
  18. private String messageId; // 消息唯一标识
  19. private Integer event; // 消息监听事件
  20. private Integer action; //操作:1加,2减
  21. private Date created; // 消息发送时间
  22. private Map<String, Object> bussinessBody; // 消息体,封装业务数据
  23. private MQMessage() {
  24. super();
  25. }
  26. private MQMessage(Integer productCode, Integer consumerCode, String messageId, Integer event, Date created,
  27. Map<String, Object> bussinessBody, Integer action) {
  28. super();
  29. this.productCode = productCode;
  30. this.consumerCode = consumerCode;
  31. this.messageId = messageId;
  32. this.event = event;
  33. this.created = created;
  34. this.bussinessBody = bussinessBody;
  35. this.action = action;
  36. }
  37. private MQMessage(Integer productCode, Integer consumerCode, Integer event, Map<String, Object> bussinessBody, Integer action) {
  38. super();
  39. this.productCode = productCode;
  40. this.consumerCode = consumerCode;
  41. this.event = event;
  42. this.bussinessBody = bussinessBody;
  43. this.action = action;
  44. }
  45. public static String productMQMessage(Integer productCode, Integer consumerCode, Integer event, Map<String, Object> bussinessBody, Integer action) {
  46. MQMessage mqObj = new MQMessage(productCode, consumerCode, event, bussinessBody, action);
  47. mqObj.setCreated(new Date());
  48. mqObj.setMessageId(generatSeriaeNo());
  49. return JSON.toJSONString(mqObj);
  50. }
  51. //生成消息唯一标识
  52. private static String generatSeriaeNo() {
  53. return DateUtil.dateFormat("yyyyMMddHHmmss") + RandomUtils.randomCode(2);
  54. }
  55. public Integer getProductCode() {
  56. return productCode;
  57. }
  58. public void setProductCode(Integer productCode) {
  59. this.productCode = productCode;
  60. }
  61. public Integer getConsumerCode() {
  62. return consumerCode;
  63. }
  64. public void setConsumerCode(Integer consumerCode) {
  65. this.consumerCode = consumerCode;
  66. }
  67. public String getMessageId() {
  68. return messageId;
  69. }
  70. public void setMessageId(String messageId) {
  71. this.messageId = messageId;
  72. }
  73. public Integer getEvent() {
  74. return event;
  75. }
  76. public void setEvent(Integer event) {
  77. this.event = event;
  78. }
  79. public Date getCreated() {
  80. return created;
  81. }
  82. public void setCreated(Date created) {
  83. this.created = created;
  84. }
  85. public Map<String, Object> getBussinessBody() {
  86. return bussinessBody;
  87. }
  88. public void setBussinessBody(Map<String, Object> bussinessBody) {
  89. this.bussinessBody = bussinessBody;
  90. }
  91. public Integer getAction() {
  92. return action;
  93. }
  94. public void setAction(Integer action) {
  95. this.action = action;
  96. }
  97. @Override
  98. public String toString() {
  99. return "MQMessage [productCode=" + productCode + ", consumerCode="
  100. + consumerCode + ", messageId=" + messageId + ", event="
  101. + event + ", action=" + action + ", created=" + created
  102. + ", bussinessBody=" + bussinessBody + "]";
  103. }
  104. }

3 实战

  • 3.1 生产者
  1. 生产者与消费者数据协议为json,定义统一数据传输实体。
  2. package com.ttd.trustProduct.mq.rabbit;
  3. import org.slf4j.Logger;
  4. import org.slf4j.LoggerFactory;
  5. import org.springframework.amqp.core.AmqpTemplate;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.stereotype.Component;
  8. @Component
  9. public class ProductTopicSender {
  10. @Autowired
  11. private AmqpTemplate rabbitTemplate;
  12. private static final Logger logger = LoggerFactory.getLogger(ProductTopicSender.class);
  13. public void send(String msg) {
  14. System.out.println("ProductTopicSender : " + msg);
  15. this.rabbitTemplate.convertAndSend("exchange", "ttd.trust.product", msg);
  16. }
  17. }
  • 3.2 消费者
  1. package com.ttd.trustProduct.mq.rabbit;
  2. import javax.annotation.Resource;
  3. import org.slf4j.Logger;
  4. import org.slf4j.LoggerFactory;
  5. import org.springframework.amqp.core.AcknowledgeMode;
  6. import org.springframework.amqp.core.Message;
  7. import org.springframework.amqp.rabbit.annotation.RabbitListener;
  8. import org.springframework.amqp.rabbit.connection.ConnectionFactory;
  9. import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;
  10. import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.context.annotation.Bean;
  13. import org.springframework.stereotype.Component;
  14. import com.alibaba.fastjson.JSON;
  15. import com.rabbitmq.client.Channel;
  16. import com.ttd.sdk.common.MQMessage;
  17. import com.ttd.sdk.common.enumerate.ActionCodeEnum;
  18. import com.ttd.sdk.common.enumerate.EventCodeEnum;
  19. import com.ttd.trustProduct.domain.LogMqMessage;
  20. import com.ttd.trustProduct.domain.SaleInfo;
  21. import com.ttd.trustProduct.service.LogMqMessageService;
  22. import com.ttd.trustProduct.service.SaleInfoService;
  23. import com.ttd.trustProduct.utils.IntegerUtils;
  24. @Component
  25. @RabbitListener(queues = "ttd.trust.product")
  26. public class ProductMessageReceiver {
  27. @Resource private SaleInfoService saleInfoService;
  28. @Resource private LogMqMessageService logMqMessageService;
  29. private final Logger logger = LoggerFactory.getLogger(ProductMessageReceiver.class);
  30. @Autowired private ConnectionFactory connectionff;
  31. /*
  32. * Map<String, Object> bussiness = Maps.newHashMap();
  33. **公共必填:**
  34. bussiness.put("productId", 11);
  35. bussiness.put("companyId", 100); //B公司id
  36. bussiness.put("isSmallPerson", 1); //1 or 0
  37. bussiness.put("assignType", 1) //'1指定派发,2抢购派发',
  38. **预约事件必填**
  39. bussiness.put("bookNum", 1);
  40. bussiness.put("bookAmount", 100);
  41. **报单事件必填**
  42. bussiness.put("formNum", 1);
  43. bussiness.put("formAmount", 100);
  44. **募集事件必填**
  45. bussiness.put("raiseNum", 1);
  46. bussiness.put("raiseAmount", 100);
  47. **签章事件必填**
  48. bussiness.put("signedNum", 1); //电子签章数
  49. bussiness.put("paperSignedNum", 1);//纸质签章数
  50. **双录事件必填**
  51. bussiness.put("signingNum", 100);
  52. */
  53. @Bean
  54. public SimpleMessageListenerContainer messageContainer() {
  55. SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionff);
  56. container.setQueueNames("ttd.trust.product");
  57. container.setExposeListenerChannel(true);
  58. container.setMaxConcurrentConsumers(1);
  59. container.setConcurrentConsumers(1);
  60. container.setAcknowledgeMode(AcknowledgeMode.MANUAL); //设置确认模式手工确认
  61. container.setMessageListener(new ChannelAwareMessageListener() {
  62. @Override
  63. public void onMessage(Message message, Channel channel) throws Exception {
  64. byte[] body = message.getBody();
  65. String jsonString = new String(body);
  66. logger.info("|============ProductMessageReceiver : " + jsonString);
  67. MQMessage msg = JSON.parseObject(jsonString, MQMessage.class);
  68. boolean preRet = preEventHandler(msg);
  69. if (preRet == false) {
  70. channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
  71. return ;
  72. }
  73. boolean postRet = postEventHandler(msg);
  74. if (postRet == false) {
  75. channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
  76. return ;
  77. }
  78. afterEventHandler(msg);
  79. channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); //确认消息成功消费
  80. //channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
  81. }
  82. });
  83. return container;
  84. }
  85. /* @RabbitHandler
  86. public void process(String msg) {
  87. System.out.println("|============ProductMessageReceiver : " +msg);
  88. MQMessage message = JSON.parseObject(msg, MQMessage.class);
  89. boolean preRet = preEventHandler(message);
  90. if (preRet == false)
  91. return ;
  92. boolean postRet = postEventHandler(message);
  93. if (postRet == false)
  94. return ;
  95. afterEventHandler(message);
  96. }*/
  97. private void recordLogMQ(MQMessage message, Integer state) {
  98. LogMqMessage log = new LogMqMessage();
  99. log.setMessageId(message.getMessageId());
  100. log.setProductCode(message.getProductCode());
  101. log.setConsumerCode(message.getConsumerCode());
  102. log.setEvent(message.getEvent());
  103. log.setBussinessBody(JSON.toJSONString(message));
  104. log.setState(state);
  105. logMqMessageService.insertEntry(log);
  106. }
  107. /**
  108. * 消息体检查
  109. * @param message
  110. * @return
  111. */
  112. private boolean preEventHandler(MQMessage message) {
  113. //不能重复消费
  114. LogMqMessage logMQ = new LogMqMessage();
  115. logMQ.setMessageId(message.getMessageId());
  116. int count = logMqMessageService.selectEntryListCount(logMQ);
  117. System.out.println(count);
  118. if (count > 0) {
  119. return false;
  120. }
  121. //消息体格式错误
  122. if (message.getEvent() == null || message.getAction() == null || message.getBussinessBody() == null ||
  123. !IntegerUtils.greatThanZero((Integer) message.getBussinessBody().get("productId")) ||
  124. !IntegerUtils.greatThanZero((Integer) message.getBussinessBody().get("companyId")) ||
  125. (Integer) message.getBussinessBody().get("isSmallPerson") == null ) {
  126. recordLogMQ(message, -1);
  127. return false;
  128. }
  129. //业务类型检查
  130. //预约事件
  131. if (IntegerUtils.equals(message.getEvent(), EventCodeEnum.BOOK_EVENT.getValue())) {
  132. if (!IntegerUtils.greatThanZero((Integer) message.getBussinessBody().get("bookNum")) ||
  133. !IntegerUtils.greatThanZero((Integer) message.getBussinessBody().get("bookAmount"))) {
  134. recordLogMQ(message, -1);
  135. return false;
  136. }
  137. //报单事件
  138. } else if (IntegerUtils.equals(message.getEvent(), EventCodeEnum.FORM_EVENT.getValue())) {
  139. if (!IntegerUtils.greatThanZero((Integer) message.getBussinessBody().get("formNum")) ||
  140. !IntegerUtils.greatThanZero((Integer) message.getBussinessBody().get("formAmount"))) {
  141. recordLogMQ(message, -1);
  142. return false;
  143. }
  144. //双录事件
  145. } else if (IntegerUtils.equals(message.getEvent(), EventCodeEnum.RECORD_EVENT.getValue())) {
  146. if (!IntegerUtils.greatThanZero((Integer) message.getBussinessBody().get("signingNum"))) {
  147. recordLogMQ(message, -1);
  148. return false;
  149. }
  150. //签章事件
  151. } else if (IntegerUtils.equals(message.getEvent(), EventCodeEnum.RECORD_EVENT.getValue())) {
  152. if (!IntegerUtils.greatThanZero((Integer) message.getBussinessBody().get("signedNum"))
  153. || !IntegerUtils.greatThanZero((Integer) message.getBussinessBody().get("paperSignedNum"))) {
  154. recordLogMQ(message, -1);
  155. return false;
  156. }
  157. //募集事件
  158. } else if (IntegerUtils.equals(message.getEvent(), EventCodeEnum.RECORD_EVENT.getValue())) {
  159. if (!IntegerUtils.greatThanZero((Integer) message.getBussinessBody().get("raiseNum")) ||
  160. IntegerUtils.greatThanZero((Integer) message.getBussinessBody().get("raiseAmount"))) {
  161. recordLogMQ(message, -1);
  162. return false;
  163. }
  164. }
  165. return true;
  166. }
  167. /**
  168. * 业务处理
  169. * @param message
  170. * @return
  171. */
  172. private boolean postEventHandler(MQMessage message) {
  173. Integer productId = (Integer) message.getBussinessBody().get("productId");
  174. Integer companyId = (Integer) message.getBussinessBody().get("companyId");
  175. Integer isSmallPerson = (Integer) message.getBussinessBody().get("isSmallPerson");
  176. Integer assignType = (Integer) message.getBussinessBody().get("assignType");
  177. //查询
  178. SaleInfo saleInfo = new SaleInfo();
  179. saleInfo.setCompanyId(IntegerUtils.parseLong(companyId));
  180. saleInfo.setProductId(IntegerUtils.parseLong(productId));
  181. saleInfo.setAssignType(assignType);
  182. SaleInfo cond = saleInfoService.selectEntryOne(saleInfo);
  183. //预约事件
  184. if (IntegerUtils.equals(message.getEvent(), EventCodeEnum.BOOK_EVENT.getValue())) {
  185. Integer bookNum = (Integer) message.getBussinessBody().get("bookNum");
  186. Integer bookAmount = (Integer) message.getBussinessBody().get("bookAmount");
  187. //insert and plus
  188. if (cond == null && IntegerUtils.equals(ActionCodeEnum.PLUS_ACTION.getValue(), message.getAction())) {
  189. saleInfo.setBookTotalNum(bookNum);
  190. saleInfo.setBookTotalAmount(bookAmount);
  191. if (IntegerUtils.greatThanZero(isSmallPerson)) {
  192. saleInfo.setSmallPersonBookNum(bookNum);
  193. saleInfo.setSmallPersonBookAmount(bookAmount);
  194. }
  195. saleInfoService.insertEntry(saleInfo);
  196. //update
  197. } else {
  198. if (IntegerUtils.equals(ActionCodeEnum.PLUS_ACTION.getValue(), message.getAction())) {
  199. cond.setBookTotalNum(cond.getBookTotalNum() + bookNum);
  200. cond.setBookTotalAmount(cond.getBookTotalAmount() + bookAmount);
  201. if (IntegerUtils.greatThanZero(isSmallPerson)) {
  202. cond.setSmallPersonBookNum(cond.getSmallPersonBookNum() + bookNum);
  203. cond.setSmallPersonBookAmount(cond.getSmallPersonBookAmount() + bookAmount);
  204. }
  205. } else {
  206. cond.setBookTotalNum(cond.getBookTotalNum() - bookNum);
  207. cond.setBookTotalAmount(cond.getBookTotalAmount() - bookAmount);
  208. if (IntegerUtils.greatThanZero(isSmallPerson)) {
  209. cond.setSmallPersonBookNum(cond.getSmallPersonBookNum() - bookNum);
  210. cond.setSmallPersonBookAmount(cond.getSmallPersonBookAmount() - bookAmount);
  211. }
  212. }
  213. saleInfoService.updateByKey(cond);
  214. }
  215. //报单事件
  216. } else if (IntegerUtils.equals(message.getEvent(), EventCodeEnum.FORM_EVENT.getValue())) {
  217. Integer formNum = (Integer) message.getBussinessBody().get("formNum");
  218. Integer formAmount = (Integer) message.getBussinessBody().get("formAmount");
  219. //insert and plus
  220. if (cond == null && IntegerUtils.equals(ActionCodeEnum.PLUS_ACTION.getValue(), message.getAction())) {
  221. saleInfo.setFormTotalNum(formNum);
  222. saleInfo.setFormTotalAmount(formAmount);
  223. if (IntegerUtils.greatThanZero(isSmallPerson)) {
  224. saleInfo.setSmallPersonFormNum(formNum);
  225. saleInfo.setSmallPersonFormAmount(formAmount);
  226. }
  227. saleInfoService.insertEntry(saleInfo);
  228. //update
  229. } else {
  230. if (IntegerUtils.equals(ActionCodeEnum.PLUS_ACTION.getValue(), message.getAction())) {
  231. cond.setFormTotalNum(cond.getFormTotalNum() + formNum);
  232. cond.setFormTotalAmount(cond.getFormTotalAmount() + formAmount);
  233. if (IntegerUtils.greatThanZero(isSmallPerson)) {
  234. cond.setSmallPersonFormNum(cond.getSmallPersonFormNum() + formNum);
  235. cond.setSmallPersonFormAmount(saleInfo.getSmallPersonFormAmount() + formAmount);
  236. }
  237. } else {
  238. cond.setFormTotalNum(cond.getFormTotalNum() - formNum);
  239. cond.setFormTotalAmount(cond.getFormTotalAmount() - formAmount);
  240. if (IntegerUtils.greatThanZero(isSmallPerson)) {
  241. cond.setSmallPersonFormNum(cond.getSmallPersonFormNum() - formNum);
  242. cond.setSmallPersonFormAmount(cond.getSmallPersonFormAmount() - formAmount);
  243. }
  244. }
  245. saleInfoService.updateByKey(cond);
  246. }
  247. //双录事件
  248. } else if (IntegerUtils.equals(message.getEvent(), EventCodeEnum.RECORD_EVENT.getValue())) {
  249. Integer signingNum = (Integer) message.getBussinessBody().get("signingNum");
  250. //insert and plus
  251. if (cond == null && IntegerUtils.equals(ActionCodeEnum.PLUS_ACTION.getValue(), message.getAction())) {
  252. saleInfo.setSigningContractNum(signingNum);
  253. saleInfoService.insertEntry(saleInfo);
  254. //update
  255. } else {
  256. if (IntegerUtils.equals(ActionCodeEnum.PLUS_ACTION.getValue(), message.getAction())) {
  257. cond.setSigningContractNum(cond.getSigningContractNum() + signingNum);
  258. } else {
  259. cond.setSigningContractNum(cond.getSigningContractNum() - signingNum);
  260. }
  261. saleInfoService.updateByKey(cond);
  262. }
  263. //签章事件
  264. } else if (IntegerUtils.equals(message.getEvent(), EventCodeEnum.RECORD_EVENT.getValue())) {
  265. Integer signedNum = (Integer) message.getBussinessBody().get("signedNum");
  266. Integer paperSignedNum = (Integer) message.getBussinessBody().get("paperSignedNum");
  267. //insert and plus
  268. if (cond == null && IntegerUtils.equals(ActionCodeEnum.PLUS_ACTION.getValue(), message.getAction())) {
  269. saleInfo.setSignedContractNum(signedNum);
  270. saleInfo.setPaperSignedContractNum(paperSignedNum);
  271. saleInfoService.insertEntry(saleInfo);
  272. //update
  273. } else {
  274. if (IntegerUtils.equals(ActionCodeEnum.PLUS_ACTION.getValue(), message.getAction())) {
  275. cond.setSignedContractNum(cond.getSignedContractNum() + signedNum);
  276. cond.setPaperSignedContractNum(cond.getPaperSignedContractNum() + paperSignedNum);
  277. } else {
  278. cond.setSignedContractNum(cond.getSignedContractNum() - signedNum);
  279. cond.setPaperSignedContractNum(cond.getPaperSignedContractNum() - paperSignedNum);
  280. }
  281. saleInfoService.updateByKey(cond);
  282. }
  283. //募集事件
  284. } else if (IntegerUtils.equals(message.getEvent(), EventCodeEnum.RECORD_EVENT.getValue())) {
  285. Integer raiseNum = (Integer) message.getBussinessBody().get("raiseNum");
  286. Integer raiseAmount = (Integer) message.getBussinessBody().get("raiseAmount");
  287. //insert and plus
  288. if (cond == null && IntegerUtils.equals(ActionCodeEnum.PLUS_ACTION.getValue(), message.getAction())) {
  289. saleInfo.setRaiseTotalNum(raiseNum);
  290. saleInfo.setRaiseTotalAmount(raiseAmount);
  291. saleInfoService.insertEntry(saleInfo);
  292. //update
  293. } else {
  294. if (IntegerUtils.equals(ActionCodeEnum.PLUS_ACTION.getValue(), message.getAction())) {
  295. cond.setRaiseTotalNum(cond.getRaiseTotalNum() + raiseNum);
  296. cond.setRaiseTotalAmount(cond.getRaiseTotalAmount() + raiseAmount);
  297. } else {
  298. cond.setRaiseTotalNum(cond.getRaiseTotalNum() - raiseNum);
  299. cond.setRaiseTotalAmount(cond.getRaiseTotalAmount() - raiseAmount);
  300. }
  301. saleInfoService.updateByKey(cond);
  302. }
  303. }
  304. return true;
  305. }
  306. /**
  307. * 消息日志处理
  308. * @param message
  309. */
  310. private void afterEventHandler(MQMessage message) {
  311. recordLogMQ(message, 1);
  312. }
  313. }
  • 3.3 单元测试
  1. package com.ttd.test;
  2. import java.util.Map;
  3. import javax.annotation.Resource;
  4. import org.junit.Test;
  5. import com.google.common.collect.Maps;
  6. import com.ttd.sdk.common.MQMessage;
  7. import com.ttd.sdk.common.enumerate.ActionCodeEnum;
  8. import com.ttd.sdk.common.enumerate.EventCodeEnum;
  9. import com.ttd.sdk.common.enumerate.ServiceCodeEnum;
  10. import com.ttd.trustProduct.mq.kafka.MsgProducer;
  11. import com.ttd.trustProduct.mq.rabbit.ProductTopicSender;
  12. public class TestMsg extends BaseTestService{
  13. @Resource private MsgProducer producer;
  14. @Resource private ProductTopicSender topicSender;
  15. // @Resource private FanoutSender fanoutSender;
  16. // @Resource private CallBackSender callBackSender;
  17. // @Resource private HelloSender1 hellSender1;
  18. //kafka
  19. // @Test
  20. public void testSendMsg() {
  21. String seriNo = System.currentTimeMillis()/1000 + "";
  22. producer.send("edwintest", "{\"seriNo\":" + seriNo + ",\"code\":200, \"msg\":\"发送一条消息,1-topic-8partion-1-replication\"}");
  23. }
  24. // topic exchange
  25. @Test
  26. public void testTopicRabbit() throws InterruptedException {
  27. Map<String, Object> bussiness = Maps.newHashMap();
  28. bussiness.put("productId", 15);
  29. bussiness.put("companyId", 100); //B公司id
  30. bussiness.put("isSmallPerson", 1); //1 or 0
  31. bussiness.put("assignType", 1);
  32. bussiness.put("bookNum", 1);
  33. bussiness.put("bookAmount", 100);
  34. /*bussiness.put("formNum", 1);
  35. bussiness.put("formAmount", 100);
  36. bussiness.put("raiseNum", 1);
  37. bussiness.put("raiseAmount", 100);
  38. bussiness.put("signedNum", 1);
  39. bussiness.put("signingNum", 100); */
  40. String messageBody = MQMessage.productMQMessage(
  41. ServiceCodeEnum.TTD_TRUST_ORDER.getValue(),
  42. ServiceCodeEnum.TTD_TRUST_PRODUCT.getValue(),
  43. EventCodeEnum.BOOK_EVENT.getValue(),
  44. bussiness,
  45. ActionCodeEnum.PLUS_ACTION.getValue());
  46. topicSender.send(messageBody);
  47. }
  48. }

SpringBoot RabbitMQ 实战解决项目中实践的更多相关文章

  1. Hystrix在项目中实践

    Hystrix在项目中实践 https://mp.weixin.qq.com/s/4Fg0COnWRB3rRWfxbJt7gA

  2. Eclipse解决项目中找不到Maven Dependencies

    项目中找不到Maven Dependencies 正常的Maven项目应该是这样的 自己的项目中却没有Maven Dependencies 先做第一步 若项目中还没有出现Maven Dependenc ...

  3. 解决项目中.a文件的冲突

    .a文件是静态文件,有多个.o文件组合而成的,在ios项目开发中,当引用第三方库的时候,时不时的会碰到诸如库冲突.库包含了某些禁用的API等问题,而这些库往往都被打包成了静态库文件(即 .a文件)来使 ...

  4. 针对MSHFlexGrid的一系列通用方法-项目中实践代码分享

    1.给MSHFlexGrid填充数据通用方法 '自定义报表填充程序 fgrid Public Function ShowformfData(Resultset As ADODB.Recordset, ...

  5. 解决项目中EF5.0升级到EF6.0无法安装包的方法

    今天在vs2012上新建了一个mvc4的项目,mvc4中默认的Entity Framework是5.0的版本,如下所示: 或者:,但是项目中有些要用到EF6.0的相关方法,用EF5.0实在繁琐,于是在 ...

  6. 解决项目中找不到Maven Dependencies

    项目中找不到Maven Dependencies 正常的Maven项目应该是这样的 自己的项目中却没有Maven Dependencies,自己百度了, 发现解决不了,最后发现在.classpath和 ...

  7. 开源物联网框架ServerSuperIO(SSIO),项目中实践应用介绍

    一.项目背景 我们是传统行业,但是我们有一颗不传统的心.企业用户遍布国内和国外,面对行业,要建设行业级的(大)数据平台.一提到大数据平台,大家往往想到Hadoop.Spark.Nosql.分布式等等, ...

  8. 使用mysql的SUBSTRING_INDEX函数解决项目中编码非重复问题的实现方案!

    一 SUBSTRING_INDEX函数介绍 作用:按关键字截取字符串 substring_index(str,delim,count) 说明:substring_index(被截取字段,关键字,关键字 ...

  9. Springboot Maven 多模块项目中 @Service跨模块引用失败的问题

    子模块中引用另一个子模块中的Service, @Autowired失败. 添加了模块之间的依赖没解决. 组以后在启动类上加上 @SpringBootApplication(scanBasePackag ...

  10. 使用Spring CROS解决项目中的跨域问题

    CROS(Cross-Origin Resource Sharing) 用于解决浏览器中跨域请求的问题.简单的Get请求可以使用JSONP来解决,而对于其它复杂的请求则需要后端应用的支持CROS.Sp ...

随机推荐

  1. Cisco RV32X系列路由器 从1day分析到0day挖掘

    前言 拿到一个iot设备,笔者比较喜欢先去看一下它的历史漏洞,也许可以从中得到一些启发.发现Cisco之前修补过这个系列设备的命令注入漏洞. https://sec.cloudapps.cisco.c ...

  2. [软件测试]Web接口的性能测试

    1 接口响应性能影响因素分析 影响Web接口查询响应性能的重要因素: 1.网络/带宽.服务器硬件资源(CPU.内存.磁盘) 2.用户并发数 3.查询的基础数据集的量级.百万级?亿级?百亿级? 4.查询 ...

  3. [数据库/MySQL]解决异常:Data truncation: Truncated incorrect DOUBLE value: 'dc5'

    1 场景复现 MySQL: 5.7.24-27 表结构 (两张独立的表) [表 RRR1] CREATE TABLE `RRR1` ( `R1` float NOT NULL COMMENT 'R1' ...

  4. IIS 部署.NET CORE 项目 出现 HTTP 错误 500.19 - Internal Server Error

    当出现这个错误时是因为服务器上没有.NET CORE对应的SDK以及运行时文件,我的.NET CORE版本是2.2,下载的就是2.2对应的文件. 附上.NET CORE2.2版本的下载链接 下载 .N ...

  5. Vue修改单页面背景颜色

  6. Django笔记二十五之数据库函数之日期函数

    本文首发于公众号:Hunter后端 原文链接:Django笔记二十五之数据库函数之日期函数 日期函数主要介绍两个大类,Extract() 和 Trunc() Extract() 函数作用是提取日期,比 ...

  7. 深入理解python虚拟机:程序执行的载体——栈帧

    深入理解python虚拟机:程序执行的载体--栈帧 栈帧(Stack Frame)是 Python 虚拟机中程序执行的载体之一,也是 Python 中的一种执行上下文.每当 Python 执行一个函数 ...

  8. Kubernetes Gateway API 深入解读和落地指南

    背景 Kubernetes Gateway API 是 Kubernetes 1.18 版本引入的一种新的 API 规范,是 Kubernetes 官方正在开发的新的 API,Ingress 是 Ku ...

  9. Prism Sample 7 Modules LoadManual

    这种模块是手动载入的,需要的时候手动加载. 在app.xaml.cs中注册为按需加载,代码 protected override void ConfigureModuleCatalog(IModule ...

  10. iview中时间选择器组件改变日期格式

    //改变视图的显示格式,但不会改变value的值的格式 format="yyyy-MM-dd" //改变value值的格式 @on-change="anZhuangDat ...