防止重复提交,接口幂等性 文章介绍了接口幂等性的概念及其重要性,即用户对同一操作发起的一次或多次请求结果一致,不会因多次点击产生副作用。文章列举了需要防止非幂等性的情况,如用户多次点击按钮、页面回退再次提交等,并以SQL为例说明了哪些操作是天然幂等的。对于如何保证幂等性,提出了多种解决方案:使用token机制(需注意先删除还是后删除token的问题及原子性)、数据库悲观锁与乐观锁、业务层分布式锁、数据库唯一约束、Redis set防重以及防重表和全局请求唯一ID等方法。这些方案各有优缺点,适用于不同的场景。 2021-07-26 3270 0 java 总结 锁 分布式
RabbitMQ消息确认机制-可靠抵达 为了确保消息的可靠传递,可以采用事务消息,但其性能会大幅下降。为此,引入了确认机制以提高效率。确认机制包括生产者端的ConfirmCallback和ReturnCallback以及消费者端的ack机制。 - **ConfirmCallback**:通过设置`spring.rabbitmq.publisher-confirms=true`或`spring.rabbitmq.publisher-confirm-type=correlated`开启,并在RabbitTemplate中设置确认回调,当消息被成功接收时触发。 - **ReturnCallback**:通过配置`spring.rabbitmq.publisher-returns=true`及`spring.rabbitmq.template.mandatory=true`启用,在消息未能正确路由到队列时触发回调。 - **消费者确认**:默认情况下,消费者自动确认消息;若需手动控制,则应将`spring.jms.listener.acknowledge-mode`设为`manual`,并在监听器中实现具体的消息签收(`basicAck`)或拒收逻辑(`basicNack`/`basicReject`)。这样即使处理过程中出现问题,也能保证消息不会丢失。 2021-07-19 2648 0 java 总结 MQ RabbitMQ
RabbitMQ的安装及使用 RabbitMQ是一款使用Erlang开发的开源消息中间件,支持AMQP协议。它具有高可靠性、灵活的消息分发策略(如简单模式、工作队列模式等)、集群支持、多种协议兼容性以及丰富的客户端语言支持。RabbitMQ还提供了可视化管理界面和插件扩展机制。通过Docker可以方便地安装和配置RabbitMQ,并设置为开机自启。文章详细介绍了四种类型的Exchange(Direct, Fanout, Topic, Headers)及其应用场景,同时展示了如何在Spring Boot项目中整合RabbitMQ,包括依赖引入、配置设置、组件启用及消息发送与接收的具体实现。这为开发者提供了一个全面了解和使用RabbitMQ作为消息中间件的基础指南。 2021-07-17 2814 0 java 总结 springboot MQ
SpringCache Spring从3.1版本开始引入了`Cache`和`CacheManager`接口来统一不同缓存技术,并支持JCache(JSR-107)注解以简化开发。`Cache`接口的实现包括`RedisCache`、`EhCacheCache`等。每次调用需要缓存的方法时,Spring会检查该方法是否已执行过,若存在结果则直接返回缓存中的数据;否则执行方法并将结果缓存后返回。 使用步骤如下: 1. 添加依赖:`spring-boot-starter-cache`。 2. 在配置文件中指定缓存类型(如Redis)及过期时间。 3. 编写配置类设置缓存序列化方式及其他属性。 4. 通过`@EnableCaching`启用缓存功能。 Spring Cache提供了多个注解如`@Cacheable`用于定义缓存、`@CachePut`更新缓存、`@CacheEvict`清除缓存等。此外,`@Caching`可以组合多种缓存操作。对于缓存问题,如穿透、击穿和雪崩,Spring提供了相应解决方案,例如缓存空值、加锁以及随机过期时间策略。针对读多写少且一致性要求不高的场景,Spring Cache是一个很好的选择。 2021-07-03 1891 0 java 总结 锁 springboot 分布式 微服务
分布式锁Redisson Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务。其中包括(BitSet, Set, Multimap, SortedSet, Map, List, Queue, B 2021-07-02 1956 0 java 总结 锁 redis 分布式 微服务
本地缓存与分布式缓存 缓存在服务端编程当中,缓存主要是指将数据库的数据加载到内存中,之后对该数据的访问都在内存中完成,从而减少了对数据库的访问,解决了高并发场景中数据库容易成为性能瓶颈的问题;以及基于内存的访问速度高于磁盘的访问速度的原理(数据库读取数据一般需要从磁盘读取),提高了数据的访问速度和程序性能。本地缓存本地缓 2021-07-01 1193 0 java 总结 redis 分布式 微服务
lettuce堆外内存溢出bug 在进行压力测试时,可能会遇到堆外内存溢出(OutOfDirectMemoryError)的问题。这主要是由于Spring Boot 2.0之后默认使用的Redis客户端lettuce存在bug,导致Netty在处理网络通信时出现堆外内存溢出。Netty如果没有明确指定堆外内存大小,默认会使用Xms的值,可以通过设置-Dio.netty.maxDirectMemory来调整,但这不是根本解决办法。为了解决这一问题,建议升级Spring Boot版本或切换到使用Jedis作为Redis客户端。如果选择后者,需要在项目的依赖中排除lettuce-core,并添加jedis依赖。 2021-06-30 2135 0 java 问题 redis 分布式
MySql乐观锁和悲观锁 本文介绍了乐观锁和悲观锁的概念及其在数据库中的实现方式。乐观锁假设数据通常不会被其他事务修改,因此读取时不加锁,仅在提交更新时检查是否有冲突;常见的实现方法包括使用版本号或时间戳字段来跟踪数据更改。而悲观锁则认为数据很可能被其他事务修改,所以在每次操作前都会锁定数据,确保同一时间只有一个事务可以修改数据。乐观锁适用于读多写少的场景,能提高吞吐量但可能在高并发写入时导致多次重试;悲观锁适合写多读少的情况,虽然保证了数据的安全性,但会增加系统开销并降低吞吐量。此外,文章还提到了多版本并发控制(MVCC)作为另一种并发控制机制。 2021-06-22 1315 0 总结 mysql 锁