添加:ZHub 管理接口文档和客户端使用指南

This commit is contained in:
2025-09-23 21:48:31 +08:00
parent 88011cf20b
commit 5af775e525
35 changed files with 4133 additions and 412 deletions

View File

@@ -1,5 +1,314 @@
---
sidebar_position: 2
sidebar_position: 3
title: 分布式锁
description: ZHub 分布式锁功能详解
---
# 分布式锁
ZHub 提供了分布式锁功能,支持多客户端环境下的资源互斥访问控制。
---
## 功能特性
- **分布式互斥**: 多个客户端实例之间互斥访问共享资源
- **自动超时**: 支持锁超时自动释放,避免死锁
- **非阻塞获取**: 支持尝试获取锁,立即返回结果
- **自动释放**: 支持手动释放锁,确保资源及时释放
---
## 基础使用
### 1. 阻塞式获取锁
```java
// 获取锁,会阻塞直到获取成功或超时
Lock lock = zhub.lock("resource-key", 30); // 30秒超时
try {
if (lock.success()) {
System.out.println("获取到锁,开始处理业务");
// 执行业务逻辑
Thread.sleep(5000); // 模拟业务处理
} else {
System.out.println("获取锁失败");
}
} finally {
lock.unLock(); // 释放锁
}
```
### 2. 非阻塞式获取锁
```java
// 尝试获取锁,立即返回结果
Lock lock = zhub.tryLock("resource-key", 30);
if (lock.success()) {
try {
System.out.println("获取到锁,开始处理业务");
// 执行业务逻辑
} finally {
lock.unLock(); // 释放锁
}
} else {
System.out.println("未获取到锁,资源被其他客户端占用");
}
```
---
## 高级用法
### 1. 锁超时处理
```java
public void processWithTimeout(String resourceKey, int timeoutSeconds) {
Lock lock = zhub.tryLock(resourceKey, timeoutSeconds);
if (!lock.success()) {
System.out.println("资源被占用,请稍后重试");
return;
}
try {
// 业务处理
processResource(resourceKey);
} finally {
lock.unLock();
}
}
```
### 2. 锁重试机制
```java
public boolean processWithRetry(String resourceKey, int maxRetries) {
for (int i = 0; i < maxRetries; i++) {
Lock lock = zhub.tryLock(resourceKey, 10);
if (lock.success()) {
try {
// 业务处理
processResource(resourceKey);
return true;
} finally {
lock.unLock();
}
}
// 等待一段时间后重试
try {
Thread.sleep(1000 * (i + 1)); // 递增等待时间
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
return false;
}
```
### 3. 锁监控和统计
```java
public class LockMonitor {
private final ZHubClient zhub;
private final Map<String, LockInfo> lockStats = new ConcurrentHashMap<>();
public void acquireLock(String key, int timeout) {
long startTime = System.currentTimeMillis();
Lock lock = zhub.lock(key, timeout);
if (lock.success()) {
long acquireTime = System.currentTimeMillis() - startTime;
lockStats.put(key, new LockInfo(key, acquireTime, System.currentTimeMillis()));
System.out.println("锁获取成功,耗时: " + acquireTime + "ms");
}
}
public void releaseLock(String key) {
LockInfo info = lockStats.remove(key);
if (info != null) {
long holdTime = System.currentTimeMillis() - info.acquireTime;
System.out.println("锁持有时间: " + holdTime + "ms");
}
}
static class LockInfo {
String key;
long acquireTime;
long acquireDuration;
LockInfo(String key, long acquireDuration, long acquireTime) {
this.key = key;
this.acquireDuration = acquireDuration;
this.acquireTime = acquireTime;
}
}
}
```
---
## 实现原理
### 服务端实现
ZHub 服务端锁管理结构:
```go
// 锁结构
type Lock struct {
Key string
UUID string
Duration int
Conn *ZConn
CreateTime time.Time
}
// 锁管理
type ZBus struct {
locks map[string][]*Lock // 锁映射表
// ... 其他字段
}
```
### 客户端实现
ZHub 客户端锁实现结构:
```java
public class Lock {
protected String name; // 锁名称
protected String uuid; // 锁唯一标识
protected int duration; // 锁持续时间
protected boolean success; // 获取是否成功
protected ZHubClient hubClient; // 客户端引用
}
```
---
## 最佳实践
### 1. 锁命名规范
```java
// 推荐:使用有意义的锁名称
String lockKey = "user:update:" + userId;
String lockKey = "order:process:" + orderId;
String lockKey = "cache:refresh:" + cacheType;
// 避免:使用无意义的锁名称
String lockKey = "lock1";
String lockKey = "temp";
```
### 2. 超时时间设置
```java
// 根据业务处理时间设置合理的超时时间
int shortTaskTimeout = 5; // 短任务5秒
int mediumTaskTimeout = 30; // 中等任务30秒
int longTaskTimeout = 300; // 长任务5分钟
// 避免设置过短或过长的超时时间
int tooShort = 1; // 太短,可能导致获取失败
int tooLong = 3600; // 太长,可能导致资源长时间占用
```
### 3. 异常处理
```java
public void safeProcess(String resourceKey) {
Lock lock = null;
try {
lock = zhub.lock(resourceKey, 30);
if (lock.success()) {
// 业务处理
processResource(resourceKey);
}
} catch (Exception e) {
logger.error("处理资源时发生异常", e);
} finally {
if (lock != null && lock.success()) {
try {
lock.unLock();
} catch (Exception e) {
logger.error("释放锁时发生异常", e);
}
}
}
}
```
### 4. 性能优化
```java
// 使用 tryLock 避免长时间阻塞
public boolean tryProcess(String resourceKey) {
Lock lock = zhub.tryLock(resourceKey, 5);
if (!lock.success()) {
return false; // 快速失败
}
try {
processResource(resourceKey);
return true;
} finally {
lock.unLock();
}
}
```
---
## 注意事项
### 1. 死锁预防
- 避免嵌套锁的使用
- 设置合理的锁超时时间
- 确保锁的释放逻辑正确
### 2. 性能考虑
- 锁的粒度要适中,不要过细或过粗
- 避免长时间持有锁
- 考虑使用非阻塞的 tryLock
### 3. 错误处理
- 始终在 finally 块中释放锁
- 处理锁获取失败的情况
- 记录锁的使用情况用于监控
---
## 监控和调试
### 1. 锁状态查询
```bash
# 通过管理接口查看锁状态
curl http://127.0.0.1:711/_/info
```
### 2. 日志监控
```java
// 在客户端代码中添加锁使用日志
logger.info("尝试获取锁: " + resourceKey);
Lock lock = zhub.lock(resourceKey, 30);
if (lock.success()) {
logger.info("锁获取成功: " + resourceKey);
} else {
logger.warn("锁获取失败: " + resourceKey);
}
```
### 3. 性能指标
- 锁获取成功率
- 锁平均持有时间
- 锁等待时间
- 锁竞争频率