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