使用redisson的锁

我们一个使用量非常小的小系统,不知道抽什么疯,突然出现了几起并发插入的问题,插入时上锁,好像只能上表锁,表锁会影响其他用户的使用,所以打算用Redis实现一个小小的分布式锁。

引入依赖如下:

1
2
3
4
5
6
7

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.12.5</version>
</dependency>

配置如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

@Configuration
public class RedissonConfig {
    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private Integer port;

    @Value("${spring.redis.password}")
    private String password;

    @Value("${spring.redis.lettuce.pool.max-idle}")
    private int maxPoolSize;

    private String cluster;

    @Bean
    public RedissonClient redissonClient() {
        return loadRedisson();
    }

    public RedissonClient loadRedisson() {
        RedissonClient redisson;
        Config config = new Config();
        //单节点
        if (!StringUtils.isEmpty(host)) {
            config.useSingleServer().
                    setAddress("redis://" + host + ":" + port)
                    .setPassword(StringUtils.isEmpty(password) ? null : password)
                    .setConnectionPoolSize(maxPoolSize)
                    .setDnsMonitoringInterval(-1)
                    //最小空闲连接
                    .setConnectionMinimumIdleSize(0);
        } else {
            //集群节点
            String[] nodes = cluster.split(",");
            //redisson版本是3.5,集群的ip前面要加上“redis://”,不然会报错,3.2版本可不加
            for (int i = 0; i < nodes.length; i++) {
                nodes[i] = "redis://" + nodes[i];
            }
            //这是用的集群server
            config.useClusterServers()
                    //设置集群状态扫描时间2000
                    .setScanInterval(2000)
                    .addNodeAddress(nodes)
                    .setPassword(password)
                    .setMasterConnectionPoolSize(maxPoolSize)
                    .setDnsMonitoringInterval(-1)
                    //最小空闲连接
                    .setMasterConnectionMinimumIdleSize(0);
        }
        redisson = Redisson.create(config);
        return redisson;
    }

    public RedissonClient retryGetRedisson() {
        return loadRedisson();
    }
}

业务逻辑代码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14

// 根据supplierId、tenantId上锁
RLock lock = redissonClient.getLock(String.format("SRM:inviteFromMaterialPlatform:%s_%s", tenantId, supplierId);

try {
    lock.lock();

    return inviteInsert.getId();
} finally {
    if (lock.isLocked()) {
        lock.unlock();
    }
}

遇到的问题

因为配置文件中使用了一个奇怪的配置redis://192.168.11.1:2345,而我本机又在使用Proxifier,让我的java.exe流量始终走在代理下,导致这块始终报host解析失败。实际上我代理服务器已经设置了redis的域名解析。最后我解决这个问题的方法是在我们的本机配置hosts。