Gateway 锁机制确保在多节点环境中只有一个活跃的 Gateway 实例在运行,防止冲突和资源竞争。
概述
Gateway 锁的主要功能:
- 防止多个 Gateway 实例同时运行
- 确保配置和状态的一致性
- 支持主备切换和故障恢复
- 保护共享资源访问
锁机制原理
文件锁
Gateway 使用文件锁防止重复启动:
# 锁文件位置
~/.openclaw/gateway.lock
# 锁文件内容
{
"pid": 12345,
"hostname": "macbook-pro.local",
"startTime": "2024-01-15T10:30:00Z",
"port": 18789
}
锁获取流程
- Gateway 启动时尝试创建锁文件
- 如果锁文件已存在,检查进程是否仍在运行
- 如果旧进程已退出,清理陈旧锁并获取新锁
- 如果旧进程仍在运行,启动失败并报错
配置锁行为
基本配置
{
"gateway": {
"lock": {
"enabled": true,
"path": "~/.openclaw/gateway.lock",
"timeout": "30s", // 获取锁超时
"staleTimeout": "5m" // 陈旧锁超时
}
}
}
多实例隔离
运行多个 Gateway 实例需要不同的锁文件:
# 实例 1
{
"gateway": {
"port": 18789,
"lock": {
"path": "~/.openclaw/gateway-1.lock"
}
}
}
# 实例 2
{
"gateway": {
"port": 18790,
"lock": {
"path": "~/.openclaw/gateway-2.lock"
}
}
}
强制启动
忽略锁
在确认旧实例已停止的情况下强制启动:
# 强制启动(忽略锁)
openclaw gateway start --force
# 或禁用锁
openclaw gateway start --no-lock
警告
强制启动可能导致多个 Gateway 同时运行,造成数据冲突。请确认旧实例已完全停止。
清理陈旧锁
# 手动清理锁文件
rm ~/.openclaw/gateway.lock
# 或使用命令
openclaw gateway unlock
# 检查锁状态
openclaw gateway lock-status
主备模式
高可用配置
配置主备 Gateway 实现高可用:
{
"gateway": {
"ha": {
"enabled": true,
"mode": "active-passive",
"healthCheck": {
"interval": "10s",
"timeout": "5s"
},
"failover": {
"enabled": true,
"timeout": "30s"
}
}
}
}
故障切换
- 备用节点持续监控主节点健康
- 主节点失败时,备用节点检测到超时
- 备用节点尝试获取锁
- 成功获取锁后升级为主节点
- 接管所有 Agent 会话
分布式锁
Redis 锁
使用 Redis 实现分布式环境的锁:
{
"gateway": {
"lock": {
"type": "redis",
"redis": {
"url": "redis://localhost:6379",
"key": "openclaw:gateway:lock",
"ttl": "30s",
"renewInterval": "10s"
}
}
}
}
etcd 锁
{
"gateway": {
"lock": {
"type": "etcd",
"etcd": {
"endpoints": ["http://localhost:2379"],
"key": "/openclaw/gateway/lock",
"ttl": "30s"
}
}
}
}
锁租约管理
心跳续约
定期更新锁以保持活性:
{
"gateway": {
"lock": {
"ttl": "60s", // 锁生存时间
"renewInterval": "20s", // 续约间隔
"renewRetries": 3 // 续约失败重试次数
}
}
}
优雅关闭
Gateway 关闭时自动释放锁:
# 正常停止会释放锁
openclaw gateway stop
# 强制停止也会尝试释放
openclaw gateway stop --force
# 超时强制停止
openclaw gateway stop --timeout 30s
监控锁状态
查看锁信息
# 查看当前锁持有者
openclaw gateway lock-status
# 输出示例
{
"locked": true,
"holder": {
"pid": 12345,
"hostname": "gateway-1.local",
"startTime": "2024-01-15T10:30:00Z",
"lastRenew": "2024-01-15T10:35:00Z"
}
}
锁竞争监控
{
"monitoring": {
"lock": {
"enabled": true,
"metrics": {
"acquisitionTime": true, // 获取锁耗时
"renewFailures": true, // 续约失败次数
"contentions": true // 锁竞争次数
}
}
}
}
故障场景处理
进程崩溃
- 陈旧锁检测会发现进程不存在
- 新 Gateway 可以清理陈旧锁并启动
- 陈旧锁超时后自动失效
网络分区
- 使用分布式锁时可能出现脑裂
- 依赖锁服务(Redis/etcd)的仲裁
- 失去锁的节点应主动降级
锁服务故障
{
"gateway": {
"lock": {
"fallback": {
"type": "file", // 降级到文件锁
"onLockServiceDown": true
}
}
}
}
调试锁问题
启用详细日志
# 查看锁相关日志
DEBUG=openclaw:lock openclaw gateway start
# 或在配置中
{
"logging": {
"components": {
"lock": "debug"
}
}
}
诊断命令
# 检查锁状态
openclaw doctor --check-lock
# 测试锁获取
openclaw gateway test-lock
# 强制释放(危险)
openclaw gateway force-unlock
最佳实践
- 生产环境始终启用锁机制
- 设置合理的 TTL 和续约间隔
- 监控锁竞争和续约失败
- 配置主备节点实现高可用
- 定期清理陈旧锁文件
- 使用分布式锁避免单点故障
Kubernetes 部署
StatefulSet 配置
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: openclaw-gateway
spec:
replicas: 2
serviceName: openclaw-gateway
selector:
matchLabels:
app: openclaw-gateway
template:
spec:
containers:
- name: gateway
image: openclaw/gateway:latest
env:
- name: OPENCLAW_LOCK_TYPE
value: "redis"
- name: REDIS_URL
value: "redis://redis:6379"
Leader Election
使用 Kubernetes 的 Leader Election:
{
"gateway": {
"lock": {
"type": "kubernetes",
"kubernetes": {
"namespace": "default",
"leaseName": "openclaw-gateway-lock",
"leaseDuration": "15s",
"renewDeadline": "10s",
"retryPeriod": "2s"
}
}
}
}
更多信息
更多高可用部署和分布式配置请参考 官方文档。