etcd 组件
基于 etcd 的 lease + watch 实现分布式节点发现:节点注册到 etcd 并定期续租,断线自动重连,成员变更实时通知到各个节点。
安装
bash
go get github.com/cherry-game/components/etcd@latest注册组件
go
import (
"github.com/cherry-game/cherry"
cherryDiscovery "github.com/cherry-game/cherry/net/discovery"
cherryETCD "github.com/cherry-game/components/etcd"
)
func main() {
app := cherry.Configure("./config/profile.json", "game-1", false, cherry.Cluster)
// 把 etcd 注册为发现服务实现
cherryDiscovery.Register(cherryETCD.New())
app.Startup()
}或者通过 builder 指定:
go
app := cherry.Configure(path, nodeID, false, cherry.Cluster)
app.SetDiscovery(cherryETCD.New())
app.Startup()Startup() 会根据 cluster.discovery.mode 的值,从注册表里查出对应的实现。
配置
需要同时配置发现服务模式和 etcd 连接参数:
json
{
"cluster": {
"discovery": {
"mode": "etcd"
},
"etcd": {
"end_points": "dev.com:2379,dev1.com:2379",
"prefix": "cherry",
"ttl": 3,
"dial_timeout_second": 1,
"op_timeout": 5,
"retry_wait": 3,
"user": "",
"password": ""
}
}
}| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
end_points | string | — | etcd 端点,多个用英文逗号分隔 |
prefix | string | cherry | etcd namespace 前缀 |
ttl | int | 3 | lease TTL(秒) |
dial_timeout_second | int | 1 | 连接超时(秒) |
op_timeout | int | 5 | Grant / Put / Get 操作超时(秒) |
retry_wait | int | 3 | 断线重连间隔(秒) |
user | string | "" | etcd 用户名 |
password | string | "" | etcd 密码 |
节点在 etcd 中的 key 格式为 /cherry/node/<nodeID>。
旧版配置字段已废弃
如果你从早期版本升级,注意这几个字段当前代码完全不读取,写在配置里不会生效,应当删除:
→ 改用dial_timeoutdial_timeout_second→ 已移除dial_keep_alive_time→ 已移除dial_keep_alive_timeout
使用发现服务
etcd 组件实现的是标准的 IDiscovery 接口,业务代码用法和其它模式完全一致:
go
discovery := app.Discovery()
// 查询成员
games := discovery.ListByType("game")
member, ok := discovery.GetMember("game-1")
randomGate, ok := discovery.Random("gate")
// settings 变更会自动同步到 etcd 并广播
discovery.UpdateSetting("region", "us-east")
discovery.UpdateSettings(map[string]string{"region": "us-east", "zone": "a"})
// 成员变更监听
discovery.OnAddMember(func(member cfacade.IMember) {
clog.Infof("节点加入: %s", member.GetNodeID())
})
discovery.OnRemoveMember(func(member cfacade.IMember) {
clog.Infof("节点离开: %s", member.GetNodeID())
})完整的接口说明见 通信 & 集群 - 发现服务。
API
| 方法 | 说明 |
|---|---|
New() *Component | 创建组件 |
Mode() string | 返回 "etcd" |
UpdateSetting(key, value string) | 更新单个 setting 并同步到 etcd |
UpdateSettings(setting map[string]string) | 批量更新并同步 |
成员查询、监听等方法继承自内嵌的 ComponentDefault:Map、ListByType、Random、GetMember、OnAddMember、OnUpdateMember、OnRemoveMember。
外部依赖
需要部署 etcd v3 集群:
go.etcd.io/etcd/client/v3v3.5.9
etcd 客户端的连接只在 Init() 时构建一次,后续断线重连复用同一连接。
版本兼容性
本组件的 go.mod 中锁定的是 github.com/cherry-game/cherry v1.5.0,其 Init() 调用了 ComponentDefault.InitFields()。该方法在 cherry v1.6.0 起已被移除,因此本组件当前无法与 v1.6.x 及以上版本的框架一起编译。
在组件跟进适配之前,使用 etcd 发现服务的节点需要把框架版本固定在 v1.5.0,或改用 nats 模式。