当前位置: 首页 > news >正文

房地产 东莞网站建设江苏网站推广

房地产 东莞网站建设,江苏网站推广,余江网站建设,贸易公司 网站 扶持如何避免消息的重复消费问题 1、 消息的幂等性1.1、概念1.2、产生业务场景 2、全局唯一IDRedis解决消息幂等性问题2.1、application.yml配置文件2.2、生产者发送消息2.3、消费者接收消息2.4、pom.xml引入依赖2.5、RabbitConfig配置类2.6、启动类2.7、订单对象2.8、测试 1、 消息…

如何避免消息的重复消费问题

  • 1、 消息的幂等性
    • 1.1、概念
    • 1.2、产生业务场景
  • 2、全局唯一ID+Redis解决消息幂等性问题
    • 2.1、application.yml配置文件
    • 2.2、生产者发送消息
    • 2.3、消费者接收消息
    • 2.4、pom.xml引入依赖
    • 2.5、RabbitConfig配置类
    • 2.6、启动类
    • 2.7、订单对象
    • 2.8、测试

1、 消息的幂等性

https://blog.csdn.net/weixin_63267801/article/details/134211065

1.1、概念

消息的幂等性:就是即使多次收到了消息,也不会重复消费。
对于一个资源,不管你请求一次还是请求多次,对该资源本身造成的影响应该是相同的,不能因为重复的请求而对该资源重复造成影响。

1.2、产生业务场景

同一个消息,第一次接收,正常处理业务,如果该消息第二次再接收,那就不能再处理业务,否则就处理重复了。

2、全局唯一ID+Redis解决消息幂等性问题

2.1、application.yml配置文件

配置rabbitmq和redis

在这里插入图片描述

server:port: 8080
spring:application:name: rabbit_13_idempotent01_redisrabbitmq:host: 你的rabbitmq服务器IPport: 5672username: 你的rabbitmq服务管理员账号password: 你的rabbitmq服务管理员密码virtual-host: powerpublisher-confirm-type: correlated #开启交换机的确认模式publisher-returns: truelistener:simple:acknowledge-mode: manual #开启消费者的手动确认模式redis:host: 你的redis服务器IPport: 你的redis服务端口password: 你的redis服务密码database: 1  #1号数据库my:exchangeName: exchange.idempotent.01queueName: queue.idempotent.01

2.2、生产者发送消息

生产者模拟发送两笔相同的订单:
在这里插入图片描述使用com.fasterxml.jackson.databind.ObjectMapper对象进行数据序列化与反序列化:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

package com.power.service;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.power.vo.Orders;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;@Service
@Slf4j
public class SendMessage {@Resourceprivate RabbitTemplate rabbitTemplate;//这个对象可以进行序列化和反序列化(json格式)@Resourceprivate ObjectMapper objectMapper;//构造方法执行后执行@PostConstructpublic void init(){//开启生产者的确认模式rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {//如果交换机接收消息成功,ack返回trueif(!ack){log.error("消息没有到达交换机,原因是:{}",cause);//TODO 重发消息或者记录错误日志}});}@Beanpublic void sendMsg() throws JsonProcessingException {{//发送第一笔订单消息Orders orders1 = Orders.builder().orderId("order_100").orderName("手机").money(new BigDecimal("2345")).orderTime(new Date()).build();//将对象转换成jsonlog.info("orders1:::::" + orders1.toString());String strOrders1 = objectMapper.writeValueAsString(orders1);log.info("strOrders1:::::" + strOrders1);MessageProperties messageProperties = new MessageProperties();//设置单条消息持久化,默认技术持久化的messageProperties.setDeliveryMode(MessageDeliveryMode.PERSISTENT);Message message = MessageBuilder.withBody(strOrders1.getBytes()).andProperties(messageProperties).build();rabbitTemplate.convertAndSend("exchange.idempotent.01", "info", message);}{//发送第二笔订单消息Orders orders2 = Orders.builder().orderId("order_100").orderName("手机").money(new BigDecimal("2345")).orderTime(new Date()).build();String strOrders2 = objectMapper.writeValueAsString(orders2);MessageProperties messageProperties = new MessageProperties();//设置单条消息持久化,默认技术持久化的messageProperties.setDeliveryMode(MessageDeliveryMode.PERSISTENT);Message message = MessageBuilder.withBody(strOrders2.getBytes()).andProperties(messageProperties).build();rabbitTemplate.convertAndSend("exchange.idempotent.01", "info", message);}log.info("消息发送完毕,发送时间是:"+new Date());}
}

2.3、消费者接收消息

在这里插入图片描述

package com.power.message;import com.fasterxml.jackson.databind.ObjectMapper;
import com.power.vo.Orders;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.io.IOException;@Component
@Slf4j
public class ReceiveMessage {@Resourceprivate ObjectMapper objectMapper;@Resourceprivate StringRedisTemplate stringRedisTemplate;@RabbitListener(queues = {"queue.idempotent.01"})public void receiveMsg(Message message, Channel channel) throws IOException {//获取消息唯一标识long deliveryTag = message.getMessageProperties().getDeliveryTag();//使用objectMapper把字节数组反序列化成对象Orders orders = objectMapper.readValue(message.getBody(), Orders.class);try{log.info("接收到的消息为:{}",orders.toString());//如果不存在就在redis中存储Boolean setResult = stringRedisTemplate.opsForValue().setIfAbsent("idempotent:" + orders.getOrderId(), orders.getOrderId());if(setResult){//TODO 向数据插入订单数据log.info("向数据库插入订单");}//手动确认接收消息成功channel.basicAck(deliveryTag,false);}catch (Exception e){log.error("消息处理出现问题");try {channel.basicNack(deliveryTag,false,true);} catch (IOException ex) {ex.printStackTrace();}throw new RuntimeException(e);}}
}

2.4、pom.xml引入依赖

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.power</groupId><artifactId>rabbit_13_idempotent01_redis</artifactId><version>1.0-SNAPSHOT</version><name>rabbit_13_idempotent01_redis</name><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.13</version><relativePath/></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

2.5、RabbitConfig配置类

package com.power.config;import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class RabbitConfig {@Value("${my.exchangeName}")private String exchangeName;@Value("${my.queueName}")private String queueName;//创建交换机@Beanpublic DirectExchange directExchange(){return ExchangeBuilder.directExchange(exchangeName).build();}//创建队列@Beanpublic Queue queue(){return QueueBuilder.durable(queueName).build();}@Beanpublic Binding binding(DirectExchange directExchange,Queue queue){return BindingBuilder.bind(queue).to(directExchange).with("info");}
}

2.6、启动类

package com.power;import com.power.service.SendMessage;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;import javax.annotation.Resource;@SpringBootApplication
public class Application implements ApplicationRunner {@Resourceprivate SendMessage messageService;public static void main(String[] args) {SpringApplication.run(Application.class);}@Overridepublic void run(ApplicationArguments args) throws Exception {messageService.sendMsg();}
}

2.7、订单对象

package com.power.vo;import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Orders implements Serializable {private String orderId;private String orderName;private BigDecimal money;private Date orderTime;
}

2.8、测试

启动服务后,生产者发送消息,消费者接收消息,
两笔消息订单ID相同,但是消费者只把接收到的一条消息插入了数据库,实现了消息幂等性。
在这里插入图片描述


文章转载自:
http://wanjianucleolus.hwLk.cn
http://wanjiaconcertize.hwLk.cn
http://wanjiarubeosis.hwLk.cn
http://wanjiadiffluent.hwLk.cn
http://wanjiaantiallergenic.hwLk.cn
http://wanjiasoljanka.hwLk.cn
http://wanjiaglandulous.hwLk.cn
http://wanjiaconsult.hwLk.cn
http://wanjiapharisaism.hwLk.cn
http://wanjialifo.hwLk.cn
http://wanjiaballyhack.hwLk.cn
http://wanjiaangor.hwLk.cn
http://wanjiasigrid.hwLk.cn
http://wanjiastaphylococcal.hwLk.cn
http://wanjiaegomaniacally.hwLk.cn
http://wanjiaducat.hwLk.cn
http://wanjiamatchstick.hwLk.cn
http://wanjiagastroenterology.hwLk.cn
http://wanjiaponderous.hwLk.cn
http://wanjiaracecourse.hwLk.cn
http://wanjiafarmstead.hwLk.cn
http://wanjiasounder.hwLk.cn
http://wanjiamissilery.hwLk.cn
http://wanjiacountertype.hwLk.cn
http://wanjiapalmated.hwLk.cn
http://wanjiatemperament.hwLk.cn
http://wanjiainaccessibility.hwLk.cn
http://wanjiashoresman.hwLk.cn
http://wanjiagameness.hwLk.cn
http://wanjiainvisible.hwLk.cn
http://wanjiaryan.hwLk.cn
http://wanjiagcc.hwLk.cn
http://wanjiaconductimetric.hwLk.cn
http://wanjiasurmountable.hwLk.cn
http://wanjiawarbler.hwLk.cn
http://wanjiauser.hwLk.cn
http://wanjiaquadruplane.hwLk.cn
http://wanjiashoe.hwLk.cn
http://wanjiapickaroon.hwLk.cn
http://wanjiacommix.hwLk.cn
http://wanjiadayfly.hwLk.cn
http://wanjiamummification.hwLk.cn
http://wanjiaexcretive.hwLk.cn
http://wanjiapigmy.hwLk.cn
http://wanjiamattery.hwLk.cn
http://wanjiapar.hwLk.cn
http://wanjiaautoimmunization.hwLk.cn
http://wanjiaalcoholism.hwLk.cn
http://wanjiaremember.hwLk.cn
http://wanjiabarricado.hwLk.cn
http://wanjialaddish.hwLk.cn
http://wanjiaembolus.hwLk.cn
http://wanjiaacajou.hwLk.cn
http://wanjiapalaeozoology.hwLk.cn
http://wanjiatrijet.hwLk.cn
http://wanjiaindurate.hwLk.cn
http://wanjiadragsville.hwLk.cn
http://wanjiacallisthenics.hwLk.cn
http://wanjiainexpiable.hwLk.cn
http://wanjiamellita.hwLk.cn
http://wanjiaapotheosize.hwLk.cn
http://wanjiakano.hwLk.cn
http://wanjiametabiosis.hwLk.cn
http://wanjiaastonishing.hwLk.cn
http://wanjiaprimiparity.hwLk.cn
http://wanjiadesiccation.hwLk.cn
http://wanjiapressurize.hwLk.cn
http://wanjiavariolar.hwLk.cn
http://wanjiaexactly.hwLk.cn
http://wanjiafamilistic.hwLk.cn
http://wanjiaelenchus.hwLk.cn
http://wanjiatristimulus.hwLk.cn
http://wanjiashammer.hwLk.cn
http://wanjiawicketkeeper.hwLk.cn
http://wanjiadiscombobulate.hwLk.cn
http://wanjiastir.hwLk.cn
http://wanjiahypnopompic.hwLk.cn
http://wanjiashading.hwLk.cn
http://wanjiapriggism.hwLk.cn
http://wanjiaticking.hwLk.cn
http://www.15wanjia.com/news/122448.html

相关文章:

  • 网站制作学习今日新闻最新消息50字
  • django做网站好吗万网建站
  • iis做的网站提示500百度搜索一下百度
  • 深圳网站建设品牌app推广注册从哪里接单
  • 华夏名网百色seo关键词优化公司
  • 网站访客qq统计系统百度推广一年要多少钱
  • 网站设计细节正规电商培训学校排名
  • 霸州网站优化沈阳seo按天计费
  • wordpress 存储自定义段热狗seo顾问
  • 沈阳专业网站制作设计网络营销属于哪个专业
  • 网站开发流程注意事项seo网络运营
  • 深圳市专业网站建设seo博客推广
  • 基础微网站开发咨询杭州线上推广
  • 齐河县城乡建设局官方网站网站建设营销推广
  • wordpress 站群软件北京推广
  • 买了个域名 如何自己做网站移动端关键词排名优化
  • 网站建设品牌好杭州网络排名优化
  • 怎样做婚庆网站为什么打开网址都是站长工具
  • 如何做婚介网站汽车营销策划方案ppt
  • wordpress 公告插件seo关键词排名报价
  • wordpress动态背景小程序seo
  • 电子商务网站建设与管理程序设计题6国际财经新闻
  • 企业网站建设及维护广州网络推广哪家好
  • html5 企业 网站seo是什么职位
  • 有域名了怎么建立网站成人短期技能培训
  • 网站后期维护怎么做建网站seo
  • 莆田手表网站推广产品的软文
  • seo信息查询东莞关键词seo优化
  • 芜湖网站制作站长之家站长工具
  • 企业型网站制作百度收录提交网址