一、准备工作
1. 下载源码
- https://github.com/coreos/etcd - 旧地址,访问时会自跳转至下面的新地址
- https://github.com/etcd-io/etcd - 新地址,这个才可用
需要注意的是 ETCD 地址迁移之后,项目内的包名并未更名,
随便翻开一个源码文件的 import 部分,项目内部的引用路径写的还是旧的
import (
...
"github.com/coreos/etcd/lease"
...
)
常规操作是会把该源码下载到 $GOPATH/src/github/etcd-io/etcd。
如此操作,项目的内部引用应该是 github.com/etcd-io/etcd/lease ,才得搜得到正确引用。
但由于源码文件的 import 仍引用旧包名,所以实际下载后,项目内引用是会失败的。
有如下三种方式可以解决这个问题,
- 改源码 - emmm....谁改谁S....B。
- 源码直接下载到 $GOPATH/src/github/coreos/etcd,就没有这个烦恼了。
- 创建一个软链
$GOPATH
├── bin
├── pkg
├── src
│ ├── github
│ │ └── etcd-io (源码下载的落地目录)
│ │ └── coreos (软链,链接到上面 etcd-io)
2. 选择分支
选一个稳定版本即可,目前最新发布的是 3.3,就选择这个分支吧。
3. 下载依赖
用的是 glide 进行依赖管理,那就装个,然后 glide install 一下即可。
(go项目最头大的就是有很多依赖需要翻墙,好在我厂网络自带翻墙,给网络小哥哥比心。)
分支切到 release-3.3,会发现有个 grpc 的依赖有问题,需要打开 glide.yaml 添加之,
- package: github.com/grpc-ecosystem/go-grpc-middleware
version: v1.0.0
然后 glide up 更新 glide.lock 文件,再 glide install 重新安装依赖。
4. 选择 debug 工具
一开始在 gdb 和 delve 两者之间选择。
本来要选择后者了,毕竟后者确实强大很多。
后来发现,常用的 intellj 自带的工具还不错,就放弃 delve 了。毕竟是要阅读源码,在控制台切来切去的,可读性差。
二、阅读路径
1. 了解功能
了解一个系统,当时得 由外及里,由简及繁。
所以肯定得把 ETCD 是神马,以及提供的所有功能都轮一篇啦,至于怎么轮,就自由发挥吧。
2. 了解 raft
etcd 的亮点在于 使用 raft 协议解决了分布式一致性的问题,所以这个也是作为阅读代码前的基础。
- https://raft.github.io/ - 这边下载得到 raft 的论文
- http://thesecretlivesofdata.com//raft/ - raft 动画,解释得很清楚
3. 轮廓
笔者在厂里的工作有一部分是中间件开发,一个完整的中间件工程有以下几个部分,
- 协议处理 - 解析处理整个中间件使用到的协议,一般该协议在前期讨论确定,当然,也可以没有,非必备品。
- 协议demo - 如果有协议,为了方便对协议的了解及验证,会搞一个简单的demo。
- 核心功能 - 中间件本身需要处理的功能业务相关操作。
- 交互API - 中间件与外系统进行交互的API,比如http接口、grpc。
- 工具 - 包括运维工具、管理工具,具体如启动、停止服务、排查服务状态的工具等等。
- 文档 - 七七八八的介绍文档
粗略看了一下,ETCD 也基本上遵循了以上的项目结构,
- 协议处理 - etcd/raft,封装了一个 raft library 。
- 协议demo - etcd/contrib/raftexample, 这是一个比较简单的demo。
- 核心功能 - 这个比较杂,后续再介绍。
- 交互API - etcd/etcdserver/api/v3rpc,API 历史有比较多的变迁,现在最新是使用 v3。
- 工具 - etcd/etcdctl,有v2,v3两个版本,现在最新是使用 v3。
- 文档 - 分散在各个包。
综上所述,我们最好的方式是先了解 raft library 及 raft demo,再了解 核心功能 。
网友评论