背景
etcd在单独使用过程中,可能需要配合一些技巧食用
奇技淫巧
版本选择
如果自己涉及到etcd相关代码开发,最好是选择3.5
版本以上。个人目前选择3.5.4
。
为什么呢?原因是此前etcd的module做过迁移(从github.com/coreos/etcd迁移到go.etcd.io/etcd),导致了一系列的go module引用混乱的问题。。可以参考一下这个博客: https://colobu.com/2020/04/09/accidents-of-etcd-and-go-module/,里面对于这个问题还有相关的github issue描述地比较详细。
本地替换
如果自己出于某些原因,想本地替换etcd的package来做部分测试,那么你可能需要同时替换多个package,否则一大堆引用错误在等着你
replace (
go.etcd.io/etcd/api/v3 => /your/local/path/etcd/api
go.etcd.io/etcd/client/pkg/v3 => /your/local/path/etcd/client/pkg
go.etcd.io/etcd/client/v3 => /your/local/path/etcd/client/v3
go.etcd.io/etcd/pkg/v3 => /your/local/path/etcd/pkg
go.etcd.io/etcd/server/v3 => /your/local/path/etcd/server
)
单元测试
本着单元测试不经过实际中间件的原则,如果我们要测试etcd相关的内容(尤其是涉及到了etcd的消息发布订阅),那么有一个官方提供的轻量版etcd可以专门用来进行单元测试。
import (
"net"
"net/url"
"os"
"testing"
"go.etcd.io/etcd/server/v3/embed"
)
func TestEtcdRelated(t *testing.T) {
dir := t.TempDir()
if err := os.Chmod(dir, 0777); err != nil {
t.FailNow()
}
cfg := embed.NewConfig()
cfg.Dir = dir
// establish two tcp connections in advance
// or you can just choose two ports that are not used
lpap, err := net.Listen("tcp", ":0")
if err != nil {
t.FailNow()
}
lcac, err := net.Listen("tcp", ":0")
if err != nil {
t.FailNow()
}
lpapUrl := url.URL{Scheme: "http", Host: lpap.Addr().String()}
lcacUrl := url.URL{Scheme: "http", Host: lcac.Addr().String()}
cfg.LPUrls = []url.URL{lpapUrl}
cfg.APUrls = []url.URL{lpapUrl}
cfg.LCUrls = []url.URL{lcacUrl}
cfg.ACUrls = []url.URL{lcacUrl}
var cluster string
for i := range cfg.APUrls {
cluster = cluster + "," + "default" + "=" + cfg.APUrls[i].String()
}
cfg.InitialCluster = cluster[1:]
if err = lpap.Close(); err != nil {
t.FailNow()
}
if err = lcac.Close(); err != nil {
t.FailNow()
}
etcdSvr, err := embed.StartEtcd(cfg)
if err != nil {
t.FailNow()
}
defer etcdSvr.Close()
// do the unit tests you want
// ...
}
PREVIOUSgolang服务记录版本信息
NEXTk8s基础知识和名词整理