系列博客目录
文章目录
https://blog.youkuaiyun.com/2303_76696898/article/details/142426882
怎么样才能够在简历上写熟悉redisson的应用以及原理
在简历上描述你熟悉 Redisson 的应用以及原理时,需要做到以下几点:
1. 清晰描述技能与经验
直接说明你对 Redisson 的熟悉程度以及具体的应用场景,展示你掌握的技术能力和应用经验。
示例:
- 核心技能描述:
熟悉 Redisson 框架,掌握其核心功能(如分布式锁、缓存、延时队列等)的应用场景及实现原理。
2. 列举具体应用场景
通过实际的项目经验或典型场景来证明你熟悉 Redisson。以下是一些可以写在简历上的内容:
示例项目经验:
-
分布式锁:
在项目中使用 Redisson 实现分布式锁,解决多节点环境下资源竞争问题,保证任务调度的幂等性。通过
RLock
提高系统的稳定性,并避免因重复操作导致的数据冲突。 -
分布式缓存:
使用 Redisson 实现基于 Redis 的分布式缓存,结合 Spring Boot 提供缓存自动刷新功能,优化热点数据的访问性能。
-
延时任务(分布式队列):
利用 Redisson 的
RDelayedQueue
实现延时任务调度,用于电商订单超时取消功能,减少订单未支付资源浪费。 -
分布式对象:
使用 Redisson 提供的分布式对象(如
RMap
、RSet
等),实现多节点间共享数据一致性,避免传统分布式缓存的复杂性。 -
事务与锁结合:
在复杂交易系统中,结合 Redisson 分布式锁与 Redis 事务,保证高并发场景下的数据一致性和安全性。
3. 展示你对原理的理解
除了应用,还需要说明你对 Redisson 核心原理的理解。以下是常见的原理,可以根据你的实际掌握情况选取一些写入简历:
示例:
-
Redisson 的核心机制:
理解 Redisson 通过基于 Redis 的 Lua 脚本实现分布式锁的可重入性、自动续期及超时释放机制,掌握其背后的实现逻辑。
-
分布式锁实现原理:
熟悉 Redisson 分布式锁的实现原理,包括:
- 单实例模式:基于 Redis 单节点的锁机制。
- 集群模式:通过主从复制和集群广播机制,实现分布式环境下的高可用锁管理。
-
一致性与高可用保障:
熟悉 Redisson 基于 Redis 哨兵模式和集群模式实现的高可用分布式锁机制,了解锁失效和数据一致性问题的处理。
-
缓存设计原理:
掌握 Redisson 基于本地缓存与 Redis 缓存结合的二级缓存策略,避免缓存击穿与缓存雪崩问题。
-
延时任务的实现:
理解 Redisson 的延时队列
RDelayedQueue
背后的时间轮算法(time-wheel)实现原理,以及其在高性能任务调度中的优势。
4. 用简历中的关键词突出你的能力
招聘方通常通过关键字筛选简历,所以确保简历中包含以下关键词:
- 分布式锁
- 缓存机制
- 延时队列
- Redisson
- Redis
- 数据一致性
- 高并发
- 高可用
示例段落:
熟悉 Redisson 框架,具备丰富的分布式环境下的开发经验。在电商项目中,基于 Redisson 实现分布式锁(
RLock
)和延时任务(RDelayedQueue
),解决高并发环境下的资源竞争与任务调度问题。掌握其核心原理,包括锁的可重入性、自动续期、高可用保障机制及其在 Redis 哨兵与集群模式下的实现逻辑。
5. 附加具体的技术成果
如果可能,可以在简历中添加具体的技术成果或优化效果。例如:
- 性能提升:描述通过使用 Redisson 优化后的系统性能。
- 示例:通过 Redisson 分布式锁优化任务调度系统,减少 40% 的任务冲突,提升任务处理效率约 30%。
- 系统稳定性:通过分布式锁、缓存等应用,解决实际的复杂问题。
- 示例:通过 Redisson 缓存机制降低数据库查询压力,支撑了日均 500w+ 的请求量。
总结
在简历中写 “熟悉 Redisson 的应用及原理” 时,可以采用以下结构:
- 技能概述:直接说明熟悉 Redisson 的具体功能(如分布式锁、缓存、延时队列)和实现原理。
- 项目经验:列举 2~3 个具体的项目场景,描述问题、Redisson 的应用方式及最终优化效果。
- 技术理解:补充对核心原理的掌握(如分布式锁、缓存一致性、高可用机制等)。
- 成果数据:用实际成果证明你的能力(如性能提升、系统稳定性提高等)。
通过具体化的描述,不仅可以证明你对 Redisson 的熟悉程度,还能体现出你对分布式系统的实战经验。
1.为什么学习Redisson
为了解决上图的一人一单的并发性问题,我们使用了基于Redis的分布式锁+lua脚本的方法,但是存在如下问题:
自己实现上面的功能太麻烦了,可以借用成熟的框架,所以我们要使用Redisson。企业环境下不用自己实现分布式锁,之前的学习都是为了理解原理。
2.Redisson简介
Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务,其中就包含了各种分布式锁的实现。
官网地址: https://redisson.org
GitHub地址: https://github.com/redisson/redisson
3.Redisson入门
1.引入依赖:
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.13.6</version>
</dependency>
2.配置Redisson客户端:下面是利用Java的方式来配置(推荐),也可以利用Yaml文件,和SpringBoot整合实现,不推荐使用redisson的starter,会覆盖redis的starter。
@Configuration
public class RedisConfig {
@Bean
public RedissonClient redissonClient() {
// 配置类
Config config = new Config();
// 添加redis地址,这里添加了单点的地址,也可以使用config.useClusterServer()添加集群地址
config.useSingleServer()
.setAddress("redis://192.168.150.101:6379")
.setPassword("123321");
// 创建客户端
return Redisson.create(config);
}
}
3.使用Redisson的分布式锁
4.Redisson可重入锁的原理
上图中的锁是无法实现可重入的。上图中左边的代码是同一个线程,但是想要两次获取锁。
那我们如何实现可重入呢?借鉴JDK的Reentrantlock的原理。那Redis如何实现在一个key中存储两个东西(线程ID和重入次数)呢?Hash结构。
这时候释放锁的逻辑也要改变,要通过次数判断是否为最后的锁(比如value减去一为零了),才会决定是否删除锁,不能不管次数都去释放锁。
为了保证原子性,我们一定要用lua脚本。
获取锁脚本如下:
释放锁脚本如下
代码运行如下:
boolean isLock =lock.trylock();
找到trylock的实现类,我们使用的最普通的Redissionlock
@Override
public boolean tryLock(){
return get(tryLockAsync());//实现类中存在一个get(tryLockAsync()。
再跟踪
再跟踪
上面的“不管你传没传 leaseTime释放时间,都会进下面蓝色的代码中”,是因为你不传这个参数,会赋值一个默认值,默认值是 -1 ,导致不符合if判断。
再跟踪,发现lua脚本,脚本和我们之前学的是一样的。
unlock跟踪的话,是一样的,会跟踪到lua脚本。
5.基于Redis的分布式锁优化
我们之前自己的分布式锁,除了不可重入,还不可重试,也就是获取锁一次失败了就停止了。还有超时释放问题:锁超时释放虽然可以避免死锁,但如果是业务执行耗时较长,也会导致业务没有结束,锁就被释放,存在安全隐患。
我们trylock可以添加三个参数,添加了第一个参数-等待时间,就可以变成可重试的锁了。
Lock.java 接口如下
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
找到实现,如下
RedissionLock,class:
public boolean tryLock(long waitTime, TimeUnit unit) throws InterruptedException {
return this.tryLock(waitTime, -1L, unit);//tryLock代码如下
}
public boolean tryLock(long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException {
long time = unit.toMillis(waitTime); // 将等待时间转化为毫秒,方便后续的时间计算
long current = System.currentTimeMillis(); // 获取当前时间戳,记录下开始时间
long threadId = Thread.currentThread().getId(); // 获取当前线程的ID,用于锁的订阅
Long ttl = this.tryAcquire(waitTime, leaseTime, unit, threadId); // 尝试获取锁并返回锁的剩余时间(ttl)
if (ttl == null) {
// 如果ttl为null,表示锁获取成功
return true; // 返回true,表示获取锁成功
} else {
time -= System.currentTimeMillis() - current; // 计算获取锁所需的时间,并更新剩余等待时间
if (time <= 0L) {
// 如果剩余等待时间小于等于0,说明已经超时,无法获取锁
this.acquireFailed(waitTime, unit, threadId); // 获取锁失败,记录失败信息
return false; // 返回false,表示获取锁失败
} else {
current = System.currentTimeMillis(); // 重新记录当前时间 这里不能立即尝试获取锁,因为我们刚得知获得锁的进程的业务还没有结束,立刻尝试,大概率还是没结束。
RFuture<RedissonLockEntry> subscribeFuture =