Java 基于 Redis的分布式锁 Redisson基本用法
用分布式锁的理由
- 在高并发场景上选型分布式服务架构时, 接口访问负载分散导致无法保证每次访问是同一个 JVM, 所以 Java锁(synchronized, ReentrantLock等)无法统一约束 .
- 还有在高并发场景上如果直接通过关系型 DB的悲观锁抗压力的话会很快用完 DB的最大连接数导致整个系统进入待机状态用户体验严重下降.
主要使用场景
秒杀, 抢购等, 为了避免因高并发重复操作同一个数据源出现的错改情况.
Maven Jar包
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.6.2</version>
</dependency>
Redisson配置
import org.apache.commons.lang3.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableCaching
public class RedissonConfig {
@Value("${spring.redis.host}")
String REDIS_HOST;
@Value("${spring.redis.port}")
String REDIS_PORT;
@Value("${spring.redis.password}")
String REDIS_PASSWORD;
@Value("${spring.redis.database}")
int REDIS_DATABASE;
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
SingleServerConfig r = config.useSingleServer();
r.setAddress("redis://" + REDIS_HOST + ":" + REDIS_PORT)
.setDatabase(REDIS_DATABASE)
.setConnectionMinimumIdleSize(5)
.setConnectionPoolSize(10);
if (!StringUtils.isEmpty(REDIS_PASSWORD)) {
r.setPassword(REDIS_PASSWORD);
}
return Redisson.create(config);
}
}
RedissonController.java
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@RestController
public class RedissonController {
@Autowired
private RedissonClient redissonClient;
/**
* 分布式锁键
* */
private final static String LOCK_KEY = "LockKey";
@GetMapping("/lock")
public Map<String, String> lock() {
final Map<String, String> result = new HashMap<>(1);
/**
* 获取锁对象
* */
final RLock lock = redissonClient.getLock(LOCK_KEY);
System.out.println("当前线程状态: " + lock.isLocked());
if (lock.isLocked()) {
result.put("message", "当前线程被锁!! " + lock.isLocked());
} else {
/**
* 加锁以后4秒钟自动解锁(为了防止死锁的产生)
* */
lock.lock(4, TimeUnit.SECONDS);
try {
/**
* 在此处理业务
* */
//Thread.sleep(3900L);
result.put("message", "处理逻辑完成!! " + LocalDateTime.now());
} catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
result.put("message", "处理逻辑失败!! " + LocalDateTime.now());
} finally {
System.out.println("当前时间: " + LocalDateTime.now());
if (lock.isLocked()) {
lock.unlock();
} else {
System.out.println("未正常解锁!!");
}
}
}
return result;
}
}
如果您觉得有帮助,欢迎点赞哦 ~ 谢谢!!