Skip to content

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_pointsstring—etcd 端点,多个用英文逗号分隔
prefixstringcherryetcd namespace 前缀
ttlint3lease TTL(秒)
dial_timeout_secondint1连接超时(秒)
op_timeoutint5Grant / Put / Get 操作超时(秒)
retry_waitint3断线重连间隔(秒)
userstring""etcd 用户名
passwordstring""etcd 密码

节点在 etcd 中的 key 格式为 /cherry/node/<nodeID>。

旧版配置字段已废弃

如果你从早期版本升级,注意这几个字段当前代码完全不读取,写在配置里不会生效,应当删除:

  • dial_timeout → 改用 dial_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/v3 v3.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 模式。