3、资源发现与注册:自动发现机制、手动注册流程、资源元数据管理、健康检查与心跳机制

资源发现与注册,说白了就是让管控平台知道「有哪些资源可以用」。我刚开始做资源管理时,觉得这步很简单——不就是把机器IP填进去嘛。结果第一次上线就出了大问题:漏掉了十几台机器,还有几台已经挂了,平台却以为它们还活着。嗯,从那以后我再也不敢小看这个环节了。

这一章,我们聊聊资源怎么被找到、怎么注册进来、元数据怎么管,以及怎么保证资源状态是真实的。

3.1 自动发现机制

自动发现,就是让平台自己去扫描、识别可用的资源。我习惯把自动发现分成两类:主动扫描和被动上报。

3.1.1 主动扫描

平台定期扫描指定网段或集群,发现新资源。常用的方式有:

  • IP 段扫描:通过 ICMP ping 或端口探测,发现存活主机
  • API 调用:调用云平台或集群管理系统的 API,获取资源列表
  • DNS 解析:通过 DNS 记录发现服务节点
  • 配置中心同步:从 Consul、Etcd、ZooKeeper 等配置中心拉取注册信息

核心原则:主动扫描不能太频繁,否则会变成「扫描攻击」。我见过一个团队把扫描间隔设成 10 秒,结果把整个机房的交换机 CPU 打满了。建议生产环境扫描间隔至少 30 秒以上。

3.1.2 被动上报

资源启动后,主动向管控平台发送注册请求。这种方式更轻量,也更容易控制。

# 伪代码:资源启动时的注册请求
POST /api/v1/resource/register
{
    "resource_id": "node-001",
    "ip": "192.168.1.100",
    "port": 8080,
    "type": "compute",
    "labels": {
        "env": "prod",
        "region": "cn-east"
    }
}

被动上报的好处是:资源自己知道什么时候准备好了。主动扫描可能会扫到还在初始化中的资源,导致状态不准确。

3.2 手动注册流程

自动发现不是万能的。有些场景必须手动注册:

  • 资源不在同一个网络段,无法自动扫描
  • 资源有特殊的安全策略,不允许主动探测
  • 需要人工审核后才能接入的资源

我建议手动注册流程做成三步:

  1. 填写资源信息:IP、端口、类型、标签等基础信息
  2. 验证连通性:平台尝试连接资源,确认可达
  3. 确认注册:验证通过后,写入注册表

小技巧:手动注册时,可以加一个「预注册」状态。资源先标记为待确认,等人工审核后再变成正式状态。这样能避免误操作。

3.3 资源元数据管理

元数据,就是描述资源的数据。我见过很多团队只存了 IP 和端口,结果出了问题根本没法排查。元数据至少要包含以下几类:

类别 字段示例 说明
基础信息 resource_id, ip, port, type 唯一标识和访问方式
归属信息 cluster, group, owner 资源属于哪个集群、谁负责
运行时信息 cpu, memory, disk, load 实时资源使用情况
标签信息 env, region, version 自定义分类标签
状态信息 status, last_heartbeat 当前状态和最后心跳时间

元数据存储我推荐用 Etcd 或 Consul。它们天然支持分布式、高可用,而且有 Watch 机制,能实时感知变化。

# Etcd 中资源元数据的存储结构示例
/resources/
  /compute/
    /node-001/
      /metadata    # 基础元数据
      /status      # 实时状态
      /labels      # 标签信息
  /storage/
    /nas-001/
      /metadata
      /status

注意:元数据一定要做版本管理。我曾经遇到过一个问题:有人误改了资源的标签,导致调度系统把生产流量发到了测试环境。后来我们给每条元数据加了版本号,修改必须走审批流程。

3.4 健康检查与心跳机制

资源注册进来之后,怎么知道它还活着?这就是健康检查和心跳要做的事。

3.4.1 心跳机制

资源定期向管控平台发送心跳包,告诉平台「我还活着」。心跳包通常包含:

  • 资源 ID
  • 当前时间戳
  • 简要状态(CPU、内存等)
# 心跳请求示例
POST /api/v1/resource/heartbeat
{
    "resource_id": "node-001",
    "timestamp": 1700000000,
    "cpu_usage": 45.2,
    "memory_usage": 62.1
}

心跳间隔一般设成 5-10 秒。太频繁浪费带宽,太慢又无法及时感知故障。

3.4.2 健康检查

健康检查是平台主动发起的探测。我常用的方式有三种:

  • TCP 端口检查:尝试连接资源的指定端口
  • HTTP 检查:请求资源的健康检查接口,看返回码
  • 自定义脚本检查:执行特定脚本,检查资源内部状态

经验之谈:心跳和健康检查要配合使用。心跳是资源自己报平安,健康检查是平台主动验证。两者都通过,才算资源真的健康。我遇到过心跳正常但实际服务已经挂了的案例——因为心跳是单独进程发的,服务进程挂了它还在发。

3.4.3 状态判定逻辑

综合心跳和健康检查的结果,资源状态可以分成几种:

状态 判定条件 处理方式
健康 心跳正常 + 健康检查通过 正常调度
可疑 心跳正常 + 健康检查失败 标记可疑,减少流量
失联 心跳超时 + 健康检查失败 标记下线,触发告警
已下线 人工确认或自动恢复失败 从注册表中移除

为什么会把「心跳正常 + 健康检查失败」标成可疑?因为可能是健康检查接口本身有问题,也可能是资源正在重启。直接标记下线太粗暴了,给个缓冲期更合理。

3.5 整体流程

把上面这些串起来,资源发现与注册的完整流程是这样的:

资源发现与注册整体流程 自动发现 手动注册 元数据管理 资源注册表 心跳机制(被动上报) 健康检查(主动探测) 状态判定(健康/可疑/失联) 更新注册表状态

你看,整个流程是闭环的:资源通过自动发现或手动注册进入元数据管理,写入注册表,然后通过心跳和健康检查持续监控,状态变化后更新注册表。这样就能保证注册表中的资源信息始终是准确的。

最后说一句:资源发现与注册是整个管控系统的基础。基础没打好,上层调度、监控、运维全都会出问题。我建议你在设计阶段就把元数据结构和状态判定逻辑想清楚,后面会省很多事。