etcd源码导读2

etcdmain/main.go

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()
}

为理解这段代码,我们先看一下etcd启动的参数

./bin/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. Note that if a configuration file is provided, other command line flags and environment variables will be ignored.

  etcd gateway
    Run the stateless pass-through etcd TCP connection forwarding proxy.

  etcd grpc-proxy
    Run the stateless etcd v3 gRPC L7 reverse proxy.

而官方推荐的启动命令:
On each etcd node, specify the cluster members:

TOKEN=token-01
CLUSTER_STATE=new
NAME_1=machine-1
NAME_2=machine-2
NAME_3=machine-3
HOST_1=10.240.0.17
HOST_2=10.240.0.18
HOST_3=10.240.0.19
CLUSTER=${NAME_1}=http://${HOST_1}:2380,${NAME_2}=http://${HOST_2}:2380,${NAME_3}=http://${HOST_3}:2380

Run this on each machine:

# For machine 1
THIS_NAME=${NAME_1}
THIS_IP=${HOST_1}
etcd --data-dir=data.etcd --name ${THIS_NAME} \
	--initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://${THIS_IP}:2380 \
	--advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://${THIS_IP}:2379 \
	--initial-cluster ${CLUSTER} \
	--initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}

# For machine 2
THIS_NAME=${NAME_2}
THIS_IP=${HOST_2}
etcd --data-dir=data.etcd --name ${THIS_NAME} \
	--initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://${THIS_IP}:2380 \
	--advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://${THIS_IP}:2379 \
	--initial-cluster ${CLUSTER} \
	--initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}

# For machine 3
THIS_NAME=${NAME_3}
THIS_IP=${HOST_3}
etcd --data-dir=data.etcd --name ${THIS_NAME} \
	--initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://${THIS_IP}:2380 \
	--advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://${THIS_IP}:2379 \
	--initial-cluster ${CLUSTER} \
	--initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}

我们没有定义ETCDCOV_ARGS,也没有grpc-gateway或者grpc-proxy,实际上测试环境直接就是

etcd

啥参数也没有,所以接下来的流程就到了startEtcdOrProxyV2()

etcdmain/etcd.go

#56: startEtcdOrProxyV2()
这个函数太长了,源码就不贴了

  1. 先生成一个默认的配置
// config holds the config for a command line invocation of etcd
type config struct {
	ec           embed.Config
	cp           configProxy
	cf           configFlags
	configFile   string
	printVersion bool
	ignored      []string
}

这里embed.Config就是etcdserver的配置,同时etcd也可以当作主要程序的一部分运行而不用单独启动一个进程。

  1. 检查data-dir里面的数据,如果已经有数据但是与当前数据不符,比如这个dir之前用来保存proxy启动的etcd,现在又要求以member形式启动,那么就不行,panic完事
  2. 检查完毕,开启etcd server

startEtcd

这是以member形式启动etcd

func startEtcd(cfg *embed.Config) (<-chan struct{}, <-chan error, error) {
	e, err := embed.StartEtcd(cfg)
	if err != nil {
		return nil, nil, err
	}
	osutil.RegisterInterruptHandler(e.Close)
	select {
	case <-e.Server.ReadyNotify(): // wait for e.Server to join the cluster
	case <-e.Server.StopNotify(): // publish aborted from 'ErrStopped'
	}
	return e.Server.StopNotify(), e.Err(), nil
}

这个函数显示了etcd的主要逻辑,以embed的形式启动etcd,其实etcd作为单独进程启动跟作为embed启动是一个流程。单独启动就是启动一个进程运行embed

等待退出

	select {
	case lerr := <-errc:
		// fatal out on listener errors
		if lg != nil {
			lg.Fatal("listener failed", zap.Error(lerr))
		} else {
			plog.Fatal(lerr)
		}
	case <-stopped:
	}

etcdmain文件夹

总的来说etcdmain目录作为main函数的下一个目的地,主要实现的逻辑有:

  1. 命令检查,确定是启动member模式还是proxy模式
  2. 参数检查,根据服务模式获取需要运行的参数
  3. 调用具体的服务实现函数,交由接下来的embed
  4. 等待信号,关闭资源,退出
etcdmain/
├── config.go
├── config_test.go
├── doc.go
├── etcd.go
├── gateway.go
├── grpc_proxy.go
├── help.go
├── main.go
└── util.go

config.go:定义配置以及解析
etcd.go:启动embed etcd前后的准备和收尾
gateway.go, grpc_proxy.go: proxy模式的进程
help.go: --help的输出
main.go:确定是proxy还是member模式运行etcd
util.go:根据dns名字获取ip

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值