前言
同学最近工作之余在看一些开源源码。我觉得我也不能太落后,在10月的末尾,开始尝试阅读etcd的源码。
正文
阅读源码前的准备工作:
在 https://github.com/coreos/go-systemd 下载go-systemd-master,将其内容(解压不含go-systemd-master目录)放$GOROOT/src/github.com/go-systemd
在 https://github.com/spf13/cobra 下载cobra-master,将其内容放$GOROOT/src/github.com/cobra
在 https://github.com/uber-go/zap 下载zap-master,将其内容放$GOROOT/src/go.uber.org/zap
在 https://github.com/etcd-io/etcd 下载etcd-master,将其内容放$GOROOT/src/go.etcd.io/etcd,随后用IDEA打开$GOROOT/src/go.etcd.io/
etcd简介
etcd是一个高可用的分布式的键值数据库,基于github开源,提供配置共享和服务发现的集群服务。通常我们一般用来存储数据的链接,缓存配置等的自动发现和更新。 这一系列就是通过对etcd的源码的解读,去弄懂商用的raft以及grpc等的使用和设计,同时也会介绍一下,其所使用的的一些开源的库的精彩设计。
首先我们从etcd的main方法开始,
func main() {
etcdmain.Main()
}
很简单,进入到etcdmain.Main之后,
func Main() {
checkSupportArch()//检查系统是否支持
if len(os.Args) > 1 {//获取入参,
cmd := os.Args[1]//获取启动命令
if covArgs := os.Getenv("ETCDCOV_ARGS"); len(covArgs) > 0 {
args := strings.Split(os.Getenv("ETCDCOV_ARGS"), "\xe7\xcd")[1:]
rootCmd.SetArgs(args)
cmd = "grpc-proxy"
}
switch cmd {//根据命令启用程序
case "gateway", "grpc-proxy":
if err := rootCmd.Execute(); err != nil {
fmt.Fprint(os.Stderr, err)
os.Exit(1)
}
return
}
}
startEtcdOrProxyV2()
}
在github上etcd/etcdctl/ctlv2/ctl_cov.go文件的提交信息显示etcdctl, e2e: use 0xe7cd as argument separator in cov-enabled etcdctl这一段话,使用0xe7cd标记作为分隔。
func checkSupportArch() {
// TODO qualify arm64
if runtime.GOARCH == "amd64" || runtime.GOARCH == "ppc64le" {
return
}
// unsupported arch only configured via environment variable
// so unset here to not parse through flag
defer os.Unsetenv("ETCD_UNSUPPORTED_ARCH")
if env, ok := os.LookupEnv("ETCD_UNSUPPORTED_ARCH"); ok && env == runtime.GOARCH {
fmt.Printf("running etcd on unsupported architecture %q since ETCD_UNSUPPORTED_ARCH is set\n", env)
return
}
fmt.Printf("etcd on unsupported platform without ETCD_UNSUPPORTED_ARCH=%s set\n", runtime.GOARCH)
os.Exit(1)
}
如果是amd和ppc64le架构是能够支持的架构(可以使用go env查看runtime.GOARCH),不支持的架构要提前设置ETCD_UNSUPPORTED_ARCH系统环境变量(退出会重置ETCD_UNSUPPORTED_ARCH环境变量),不支持并且没有设置ETCD_UNSUPPORTED_ARCH,则程序终止。
上面仔细去看,是根据命令行输入的第一个参数去启动不同的代码逻辑,我们来查看一下etcd命令的使用帮助:
$ ./etcd -help
Usage:
etcd [flags]
Start an etcd server.
etcd --version //查看版本
Show the version of etcd.
etcd -h | --help //获取帮助
Show the help information about etcd.
etcd --config-file //设置配置文件
Path to the server configuration file.
etcd gateway //启动 L4 TCP网关代理
Run the stateless pass-through etcd TCP connection forwarding proxy.
etcd grpc-proxy //L7 grpc 代理
Run the stateless etcd v3 gRPC L7 reverse proxy.
........
注意看上面的最后两个说明:
gateway 无状态的tcp转发服务 grpc-proxy 无状态grpc服务 可以从代码逻辑看到,可以有3个启动命令服务,
./etcd //启动etcd服务
./etcd gateway start //启动tcp网关代理
./etcd grpc-proxy start //启动grpc网关代理
我们主要也是从这三个命令去贯穿整个etcd的源码去介绍。