Redisson概述
Redisson是架设在Redis基础上的一个Java驻内存数据网格(In-Memory Data Grid)。充分的利用了Redis键值数据库提供的一系列优势,基于Java实用工具包中常用接口,为使用者提供了一系列具有分布式特性的常用工具类。使得原本作为协调单机多线程并发程序的工具包获得了协调分布式多机多线程并发系统的能力,大大降低了设计和研发大规模分布式系统的难度。同时结合各富特色的分布式服务,更进一步简化了分布式环境中程序相互之间的协作。
适用场景
分布式应用,分布式缓存,分布式回话管理,分布式服务(任务,延迟任务,执行器),分布式redis客户端
实际应用
这里还使用高并发卖票问题来介绍Redisson,详情参见 手写一个Redis分布式锁解决实际开发中高并发问题
Redission这个框架就解决了 分布式锁的问题
Reddsion这个框架实际上也是的Redis的客户端代码
1、导入依赖
<!-- redssion -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.12.0</version>
</dependency>
2、编写配置文件
@SpringBootConfiguration
public class RedisConfig {
private Logger logger = LoggerFactory.getLogger(RedisConfig.class);
@Bean
public RedissonClient redisClient() {
RedissonClient redissonClient = null;
// 获取config的实例
Config config = new Config();
// 设置请求的URL地址
String url = "redis://39.105.232.73:6379";
config.useSingleServer().setAddress(url);
// 设置密码
String password = "root";
config.useSingleServer().setPassword(password);
// 通过redisson创建一个客户端对象
try {
redissonClient = Redisson.create(config);
logger.info("创建RedissonClient成功...");
return redissonClient;
} catch (Exception e) {
logger.error("创建RedissonClient失败:" + e.fillInStackTrace());
return null;
}
}
}
3、自定义分布式锁 lock
@Component
public class DistributeRedisLock {
private Logger logger = LoggerFactory.getLogger(DistributeRedisLock.class);
@Autowired
private RedissonClient redissonClient;
/**
* 加锁的方法
*/
public boolean lock(String lockName) {
try {
if (null == redissonClient) { // 表示 redissonClient 注入失败
logger.info("注入redissonClient对象失败...");
return false;
}
// 获取这个锁
RLock lock = redissonClient.getLock(lockName);
// 给程序加锁
lock.lock(30, TimeUnit.SECONDS);
logger.info("加锁成功...");
return true;
} catch (Exception e) {
logger.error("不可预期的异常造成了加锁失败...");
return false;
}
}
/**
* 释放锁的方法
*/
public boolean unlock(String lockName) {
try {
if (null == redissonClient) { // 表示 redissonClient 注入失败
logger.info("释放锁失败:" + lockName);
return false;
}
// 获取这个锁对象
RLock lock = redissonClient.getLock(lockName);
if (null != lock) {
lock.unlock();
logger.info("释放锁成功...");
return true;
}
return false;
} catch (Exception e) {
logger.info("不可预期的异常造成了锁释放失败...");
return false;
}
}
}
4、业务逻辑中调用锁
@Autowired
private DistributeRedisLock distributeRedisLock;
private Logger logger = LoggerFactory.getLogger(TicketServiceImpl.class);
@Override
public String sellTicketRedisson() {
String lock = "lock";
try {
boolean addLock = distributeRedisLock.lock(lock);
if (!addLock) { // 如果加锁失败
return "当前排队人数过多...请等待...";
}
String ticketStr = stringRedisTemplate.opsForValue().get("ticket");
int ticket = 0;
if (null != ticketStr) {
ticket = Integer.parseInt(ticketStr);
}
if (ticket > 0) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
int ticketNew = ticket - 1;
stringRedisTemplate.opsForValue().set("ticket", String.valueOf(ticketNew));
logger.info("当前票的库存为:" + ticketNew);
} else {
logger.info("手速不够呀,票已经卖光了...");
}
} finally {
// 关闭锁
distributeRedisLock.unlock(lock);
}
return "抢票成功...";
}