6.5 Gateway锁

Gateway 锁机制确保在多节点环境中只有一个活跃的 Gateway 实例在运行,防止冲突和资源竞争。

概述

Gateway 锁的主要功能:

  • 防止多个 Gateway 实例同时运行
  • 确保配置和状态的一致性
  • 支持主备切换和故障恢复
  • 保护共享资源访问

锁机制原理

文件锁

Gateway 使用文件锁防止重复启动:

# 锁文件位置
~/.openclaw/gateway.lock

# 锁文件内容
{
  "pid": 12345,
  "hostname": "macbook-pro.local",
  "startTime": "2024-01-15T10:30:00Z",
  "port": 18789
}

锁获取流程

  1. Gateway 启动时尝试创建锁文件
  2. 如果锁文件已存在,检查进程是否仍在运行
  3. 如果旧进程已退出,清理陈旧锁并获取新锁
  4. 如果旧进程仍在运行,启动失败并报错

配置锁行为

基本配置

{
  "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"
      }
    }
  }
}

故障切换

  1. 备用节点持续监控主节点健康
  2. 主节点失败时,备用节点检测到超时
  3. 备用节点尝试获取锁
  4. 成功获取锁后升级为主节点
  5. 接管所有 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"
      }
    }
  }
}
更多信息
更多高可用部署和分布式配置请参考 官方文档