Documentation
¶
Overview ¶
Package servercore 提供 realtime-ping 分布式模式的「中心汇总」能力。
设计目标:只依赖 transport(协议契约),不依赖 monitor / notify / metrics, 形成一个可独立引入的中心服务内核。realtime-ping 的 server 模式直接挂载 Handler, 也可被其他消费者复用——拆装自由。
Index ¶
- type ConfigStore
- type HistoryPoint
- type NodeConfigStore
- type NodeState
- type RedisConfigStore
- type RegionSummary
- type Registry
- func (r *Registry) ApplyHeartbeat(hb transport.Heartbeat) (isNew bool)
- func (r *Registry) DeleteNodeConfig(nodeID string) error
- func (r *Registry) Handler() http.Handler
- func (r *Registry) LoadNodeConfigs() error
- func (r *Registry) NodeConfig(nodeID string) (transport.NodeConfig, bool)
- func (r *Registry) Prune(now int64) []string
- func (r *Registry) PublicStatusHandler() http.Handler
- func (r *Registry) PutNodeConfig(nodeID string, targets []transport.TargetSpec) error
- func (r *Registry) Regions() []RegionSummary
- func (r *Registry) SetNodeConfig(nodeID string, targets []transport.TargetSpec)
- func (r *Registry) Snapshot() []NodeState
- func (r *Registry) StartBackgroundPruner(interval time.Duration) func()
- func (r *Registry) Status() statusSummary
- func (r *Registry) StatusJSONHandler() http.Handler
- func (r *Registry) TopologyHandler() http.Handler
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ConfigStore ¶
type ConfigStore interface {
// Load 读取全量节点配置映射;首次无数据时应返回空 map(而非错误)。
Load() (map[string][]transport.TargetSpec, error)
// Save 全量持久化配置映射。
Save(m map[string][]transport.TargetSpec) error
}
ConfigStore 是中心下发配置「期望状态」的持久化抽象。
默认实现为文件型 NodeConfigStore(JSON atomic rename,零外部依赖)。当中心需要 多实例共享存储时,可提供基于 Redis / DB 的实现并替换到 Registry,对外 API 不变, 无需改动 topology / REST 层。类型安全(map[string][]transport.TargetSpec)由实现保证。
type HistoryPoint ¶
HistoryPoint 是某目标的一次状态采样点(用于长周期趋势展示)。
type NodeConfigStore ¶
type NodeConfigStore struct {
// contains filtered or unexported fields
}
NodeConfigStore 是 ConfigStore 的默认文件型实现。
设计取舍:server-core 刻意保持零外部依赖(仅依赖 transport),因此这里用 JSON 文件做持久化,而不是 SQLite。配置是低频写、启动读、内存热路径,JSON 文件 + atomic rename 足够,且运维可直接 cat/vi 编辑,符合「最小可运维」目标。
底层落盘已收敛到公共模块 jsonstore(atomic rename),本类型仅做类型安全的封装, 把 jsonstore 的 any 接口收敛为 server-core 专用的 map[string][]transport.TargetSpec。
并发安全:所有读写都走 Registry 的 mu(写 API 与心跳共用同一把锁,避免配置与 存活状态出现不一致窗口)。
func NewNodeConfigStore ¶
func NewNodeConfigStore(path string) *NodeConfigStore
NewNodeConfigStore 构造文件型配置存储。path 为空表示纯内存(不落盘)。
func (*NodeConfigStore) Load ¶
func (s *NodeConfigStore) Load() (map[string][]transport.TargetSpec, error)
Load 从磁盘读取全量节点配置映射。文件不存在时返回空 map(而非错误), 便于「首次启动无配置」场景。
func (*NodeConfigStore) Save ¶
func (s *NodeConfigStore) Save(m map[string][]transport.TargetSpec) error
Save 原子写全量配置到磁盘(先写临时文件再 rename,避免半截写损坏)。
type NodeState ¶
type NodeState struct {
Info transport.NodeInfo `json:"info"`
Targets []transport.TargetStatus `json:"targets"`
LastSeen int64 `json:"last_seen"` // 最近一次心跳 Unix 时间戳(秒)
Stale bool `json:"stale"` // 超过心跳超时未上报
History map[string][]HistoryPoint `json:"history,omitempty"` // 各目标最近状态窗口(key=target name)
}
NodeState 是 server 侧维护的单个节点运行状态。
type RedisConfigStore ¶
type RedisConfigStore struct {
// contains filtered or unexported fields
}
RedisConfigStore 是 ConfigStore 的共享存储实现,底层复用 kvstore.Store 契约 (内存 / Redis 后端可插拔)。它让中心下发配置「期望状态」脱离单机文件, 多个 server 实例共享同一份配置,实现多实例一致性。
设计取舍:本类型只依赖零外部依赖的 kvstore 核心接口(Store),真正的分布式 后端(kvstore/redis)由调用方在构造处注入(如 kvredis.NewStore + Backend:"redis"), 因此 server-core 自身依旧不引入任何第三方依赖。键值均为 JSON 编码的 map[string][]transport.TargetSpec,与 NodeConfigStore 落盘格式互通。
func NewRedisConfigStore ¶
func NewRedisConfigStore(store kvstore.Store) *RedisConfigStore
NewRedisConfigStore 构造基于 kvstore.Store 的共享配置存储。 store 由调用方注入:单机可传 kvstore.NewMemory(),跨节点共享传 kvstore/redis 的 Redis 后端。store 为 nil 时退化为纯内存空实现(Load 返回空 map)。
func (*RedisConfigStore) Load ¶
func (s *RedisConfigStore) Load() (map[string][]transport.TargetSpec, error)
Load 读取共享存储中的全量节点配置映射;无数据时返回空 map(而非错误)。
func (*RedisConfigStore) Save ¶
func (s *RedisConfigStore) Save(m map[string][]transport.TargetSpec) error
Save 全量写入配置映射到共享存储。
type RegionSummary ¶
type RegionSummary struct {
Region string `json:"region"` // 区域标签;空串表示「未分区」
Nodes int `json:"nodes"` // 该区域节点总数
OnlineNodes int `json:"online_nodes"` // 在线(非 stale)节点数
Targets int `json:"targets"` // 该区域目标总数
DownTargets int `json:"down_targets"` // 该区域不可达目标数
}
RegionSummary 是多区域聚合视图的单项:按节点 Region 标签分组统计。
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry 是线程安全的节点注册表。 nodeConfigs(下发配置的「期望状态」)可选地经 ConfigStore 持久化;默认实现为 文件型 NodeConfigStore(JSON),需要多实例共享时替换为 Redis/DB 实现即可。
func NewRegistry ¶
func NewRegistry(heartbeatTimeout time.Duration, store ConfigStore, writeToken string) *Registry
NewRegistry 构造注册表。heartbeatTimeout 建议与 agent 心跳周期的 2~3 倍一致。 store 传 nil 为纯内存模式;writeToken 非空时写 API 需要 Bearer 鉴权。 readToken 留空表示读端点不鉴权(向后兼容旧行为)。
func NewRegistryWithTokens ¶
func NewRegistryWithTokens(heartbeatTimeout time.Duration, store ConfigStore, writeToken, readToken string) *Registry
NewRegistryWithTokens 是 NewRegistry 的完整版:额外支持 readToken, 对读端点(拓扑页 / 节点快照 / 配置拉取)做 Bearer 鉴权,便于将 server 安全暴露到内网/有限外网。 readToken 为空表示读端点不鉴权(向后兼容)。
func (*Registry) ApplyHeartbeat ¶
ApplyHeartbeat 处理一次 agent 上报,注册或更新节点。 返回该节点此前是否已存在(用于日志/计数)。 同时把本次每个目标的状态点追加到历史窗口(环形覆盖,上限 historyWindow)。
func (*Registry) DeleteNodeConfig ¶
DeleteNodeConfig 清空某节点的下发目标(保留节点存活状态),并落盘。 这是 DELETE /api/v1/config 的处理入口。
func (*Registry) Handler ¶
Handler 返回可直接挂载到 http.Server 的路由 Handler。 暴露端点:
- POST /api/v1/heartbeat : agent 上报心跳(transport.Heartbeat JSON)
- GET /api/v1/nodes : 返回全局节点汇总快照(JSON;读鉴权)
- GET /api/v1/regions : 多区域聚合视图(JSON;读鉴权)
- GET / : 中心拓扑 HTML 视图(TopologyHandler 内部鉴权)
- GET/PUT/DELETE /api/v1/config?node_id= : 配置下发;PUT/DELETE 需写鉴权
- GET /api/v1/status : 公开状态 JSON(有意匿名)
- GET /status : 公开状态 HTML(有意匿名)
func (*Registry) LoadNodeConfigs ¶
LoadNodeConfigs 在启动时把磁盘配置全量灌入内存(不含落盘,启动阶段本就来自磁盘)。
func (*Registry) NodeConfig ¶
func (r *Registry) NodeConfig(nodeID string) (transport.NodeConfig, bool)
NodeConfig 返回指定节点的下发配置(GET /api/v1/config 使用)。
func (*Registry) Prune ¶
Prune 清理超过 heartbeatTimeout 未上报的节点,将其标记为 stale(不删除, 便于前端区分「已离线」与「从未上线」)。返回的列表为本次新变 stale 的节点 ID。
func (*Registry) PublicStatusHandler ¶
PublicStatusHandler 返回 GET /status 的公开 HTML 状态页(匿名公开,只读)。
func (*Registry) PutNodeConfig ¶
func (r *Registry) PutNodeConfig(nodeID string, targets []transport.TargetSpec) error
SetNodeConfig 在 Registry 上覆盖某节点的下发目标,并落盘(若配置了 store)。 这是 PUT /api/v1/config 的处理入口:全量替换(而非 merge),语义简单、幂等。
func (*Registry) Regions ¶
func (r *Registry) Regions() []RegionSummary
Regions 按节点 Region 标签聚合全局状态,返回各区域汇总。 未带 Region 标签的节点归入空串区域("未分区")。
func (*Registry) SetNodeConfig ¶
func (r *Registry) SetNodeConfig(nodeID string, targets []transport.TargetSpec)
nodeConfigs 是中心下发给各节点的「应监控目标」配置。 由运维通过 SetNodeConfig 注入(静态初始化)或 PUT /api/v1/config 写 API 注入, agent 拉取后用于构建本地 monitor。与 Registry.nodes 解耦:nodes 是存活状态, nodeConfigs 是期望状态。
func (*Registry) StartBackgroundPruner ¶
StartBackgroundPruner 启动一个后台 goroutine,每隔 interval 调用 Prune。 返回的 stop 函数用于优雅退出。now 通过 time.Now().Unix 取得;间隔由 interval 指定。
func (*Registry) Status ¶
func (r *Registry) Status() statusSummary
Status 返回公开状态页的只读快照。幂等、不加锁地聚合现有状态。
func (*Registry) StatusJSONHandler ¶
StatusJSONHandler 返回 GET /api/v1/status 的 JSON 视图(匿名公开,只读)。
func (*Registry) TopologyHandler ¶
TopologyHandler 返回中心拓扑 HTML 视图的 http.Handler(GET /)。 它复用 Registry 的 Snapshot,按「节点 → 目标」两层渲染实时状态。
鉴权(readToken / WWW-Authenticate 头)由调用方在上层中间件中处理(例如 Registry.Handler 里的 mwTopoHTML),本 handler 不判 Authorization:鉴权与内容职责分层,后续接入别的访问控制 时可直接替换中间件、无需改动视图逻辑。