Why Use This
This skill provides specialized capabilities for TencentBlueKing's codebase.
Use Cases
- Developing new features in the TencentBlueKing repository
- Refactoring existing code to follow TencentBlueKing standards
- Understanding and working with TencentBlueKing's codebase structure
Skill Snapshot
Auto scan of skill assets. Informational only.
Valid SKILL.md
Checks against SKILL.md specification
Source & Community
Updated At Jan 9, 2026, 09:52 AM
Skill Stats
SKILL.md 159 Lines
Total Files 1
Total Size 0 B
License NOASSERTION
---
name: 10-distributed-lock
description: 分布式锁使用指南,涵盖 Redis 分布式锁、锁超时处理、可重入锁、锁粒度设计、死锁预防。当用户需要并发控制、实现分布式锁、处理资源竞争或保证数据一致性时使用。
---
# 分布式锁
分布式锁使用指南.
## 触发条件
当用户需要实现分布式环境下的资源互斥访问、防止并发冲突时,使用此 Skill。
## RedisLock 实现
```kotlin
class RedisLock(
private val redisOperation: RedisOperation,
private val lockKey: String,
private val expiredTimeInSeconds: Long,
private val sleepTime: Long = 100L,
private var lockValue: String = UUID.randomUUID().toString()
) : AutoCloseable {
// 阻塞获取锁
fun lock() {
synchronized(getLocalLock()) {
while (true) {
if (tryLockRemote()) break
Thread.sleep(sleepTime)
}
}
}
// 尝试获取锁(非阻塞)
fun tryLock(): Boolean = tryLockRemote()
// 释放锁
fun unlock(): Boolean = unLockRemote()
// 自动释放(try-with-resources)
override fun close() = unlock()
// 锁包装执行
fun <T> lockAround(action: () -> T): T {
try {
this.lock()
return action()
} finally {
this.unlock()
}
}
}
```
## 使用方式
### 1. 基本用法
```kotlin
@Service
class PipelineService(
private val redisOperation: RedisOperation
) {
fun startBuild(pipelineId: String) {
val lock = RedisLock(
redisOperation = redisOperation,
lockKey = "pipeline:build:$pipelineId",
expiredTimeInSeconds = 60
)
try {
lock.lock()
// 执行构建逻辑
doBuild(pipelineId)
} finally {
lock.unlock()
}
}
}
```
### 2. try-with-resources
```kotlin
fun updatePipeline(pipelineId: String) {
RedisLock(redisOperation, "pipeline:update:$pipelineId", 30).use { lock ->
lock.lock()
// 更新逻辑
doUpdate(pipelineId)
}
}
```
### 3. lockAround 包装
```kotlin
fun processTask(taskId: String): Result<String> {
val lock = RedisLock(redisOperation, "task:$taskId", 60)
return lock.lockAround {
// 处理任务
doProcess(taskId)
}
}
```
### 4. 非阻塞尝试
```kotlin
fun tryProcess(resourceId: String): Boolean {
val lock = RedisLock(redisOperation, "resource:$resourceId", 30)
if (!lock.tryLock()) {
logger.info("资源 $resourceId 正在被其他进程处理")
return false
}
try {
doProcess(resourceId)
return true
} finally {
lock.unlock()
}
}
```
## Lua 解锁脚本
```lua
-- 防止误删其他客户端的锁
if redis.call("get", KEYS[1]) == ARGV[1] then
return redis.call("del", KEYS[1])
else
return 0
end
```
## 锁命名规范
```kotlin
// 格式:业务:操作:资源ID
"pipeline:build:$pipelineId"
"project:update:$projectId"
"task:process:$taskId"
"user:login:$userId"
```
## 最佳实践
1. **合理设置过期时间**:根据业务执行时间设置,避免死锁
2. **使用 UUID 作为锁值**:确保只释放自己持有的锁
3. **优先使用 try-finally**:确保锁一定被释放
4. **本地锁优化**:先获取本地锁减少 Redis 请求
## 相关文件
- `common-redis/src/main/kotlin/com/tencent/devops/common/redis/RedisLock.kt`
- `common-redis/src/main/kotlin/com/tencent/devops/common/redis/RedisOperation.kt`