Redisson实现Redis分布式锁

?xml version="1.0" encoding="UTF-8"?

### 背景:为什么要写这篇文章呢

最近做的项目遇到了一个问题,就是分布式xxl_job任务框架的分布式部署后,任务采用轮训方式在多台服务器执行,某个和数据库有交互的任务每隔5分钟定时执行一次。比如第一次9:00在服务器A上执行,第二次9:05则到了服务器B上执行,这时候同样的代码执行了2次,造成数据交互错乱。

### 调研如何解决这个问题

刚开始想到使用项目中已经在使用的redis来解决这个问题,因为redis在我们项目中已经使用的比较成熟,比如用户登录认证的token,过期刷新用的 refresh_token、以及gateway网关的服务路由等都是存储在redis里面的。

### 实现方式一(有不足点)

刚开始同事想到的实现方式就是job在服务器A执行的时候,直接put 一个key到redis的库中,等执行结束的时候,在清除掉。这样,当job在服务器执行的时候,会先检查这个key是否在存在库中,如果存在,就退出执行,不存在的话,加锁,继续执行,执行完成,释放锁。

但是上面的方式经我提醒后,存在不足点。最大的不足,在于redis的锁(key)需要设置过期时间,如果job在服务器A上执行到一半代码的时候,所突然过期了,这时候服务器B上的job执行,就会重入这块代码,依然造成数据冲突,解决不了最新提出的问题。

### 改进后的执行方式

后面我调研了一下开源的Redisson框架,发现Redisson刚好能解决这个问题,并且使用方式简单。

### 具体使用方式

1. maven依赖

-

org.redisson

redisson

3.16.0

2. 配置类代码实现

```

import org.redisson.Redisson;

import org.redisson.api.RedissonClient;

import org.redisson.config.Config;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

@Configuration

public class RedissonConfig {

@Value("${redis.host}")

private String host;

@Value("${redis.database}")

private Integer database;

@Value("${redis.port}")

private Integer port;

@Bean

public RedissonClient redisson(){

Config config = new Config();

config.useSingleServer().setAddress("redis://"+host+":"+port).setPassword("asasa").setDatabase(database);

return Redisson.create(config);

}

}

function fun(){

echo "这是一句非常牛逼的代码";

}

fun();

```

3. 使用类代码举例

```

import org.redisson.api.RLock;

import org.redisson.api.RedissonClient;

import java.util.*;

public class DbCreateHandler extends IJobHandler {

@Autowired

RedissonClient redissonClient;

@Value("${spring.application.name}")

private String applicationName;

@Override

public JobWrapper execute(String param, Integer jobId, Integer logId) throws Exception {

int code = -1;

String message = "";

String lockKey = applicationName+"_dbCreateHandler";

RLock redissonLock = redissonClient.getLock(lockKey);

try {

//默认超时时间30S

redissonLock.lock();

}catch(Exception e){

e.printStackTrace();

}finally{

redissonLock.unlock();

}

return jobWrapper;

}

}

```

### 原理说明

1. Redisson分布式锁实现原理图

![4010b729a16a32e1d8853317bc6f34f5.png](evernotecid://CCCDFA6D-243E-4347-BAC7-B1F0633DCBB2/appyinxiangcom/32899750/ENResource/p842)

2. 源码说明

你可能感兴趣的:(Redisson实现Redis分布式锁)