springboot项目redis分布式锁实现(基于luttuce)
问题背景 对于大部分的后端服务,服务很多都是多实例部署的,而在我们的工程中,比如说代码中定义的定时任务需要从数据库中捞数据,那么多机部署上的每个实例都会执行,那么就会存在数据重复上报,那么就不可避免得出现脏数据,影响数据的准确性。 问题分析 解决这个问题最直接的思路就是,当多机部署中无论哪个实例捞到了某条数据,那么其他的实例就不能再次捞取。针对这个思路,我们大致可以有以下两个解决方案: 1. 在数据库层解决。给访问的数据表中,增一个字段flag,标识是否已经上报过,每个实例上报一条,就更新一下这个状态,后面的实例再读到这一条时,发现上报过了,就不处理了。这就要改一下现在的读取方式,需要从数据库中逐条读取,避免脏数据。 2. 引入分布式锁,最简单的,就用redis实现,每个实例开始定时任务前,先尝试在redis中获取锁,如果获取得到,这个实例的定时任务就执行,否则就跳过。 对于第一个解决方案的实现本文不予说明,这种实现方式虽然可行,但是对于频繁更新数据库的操作我个人是非常不推荐的,性能方面可能会受到影响。本文主要想介绍一下方案2的实现。 方案实现 对于多机部署的问题,自然而然就可以想到分布式锁来保证任务执行的准确性。在Springboot项目中,最直接就是通过redis实现,我们知道,从Springboot 2.X开始,底层的redis客户端从Jedis换成了luttuce