一、背景
最近笔者在 AskTUG 回答问题的时候发现,在 6.5.0 版本出现了几个显示未启动必要组件 NgMonitoring 的问题贴。经过排查发现,是 ngmonitoring.toml 中的配置文件出现了问题。文件中的 endpoints 应该是以逗号分隔的,但是却写成了以空格分隔的情况,所以才导致了报错。
临时的解决方案就是手动修改配置文件,并 restart prometheus。
(这里借用一下原帖中的截图)
二、修复BUG
前面已经发现问题了,先简单分析一下,这里是配置文件出现问题了,那么大概率是需要到 TiUP 的仓库中去修复 bug。所以笔者就到 GitHub 中找到了 TiUP 仓库。
TiUP仓库地址:pingcap/tiup: A component manager for TiDB (http://github.com)
首先笔者需要知道出问题的具体代码在哪,所以笔者先根据文件中的注释进行查找。
这个配置文件与 ngmonitoring.toml 完全吻合,点进去查看,笔者发现这里使用的变量名是 PDAddrs
继续使用 PDAddrs 进行查找,看看代码中是如何给 PDAddrs 赋值的。在结果中排除掉路径中带有 template 关键字的文件,发现只有路径为 pkg/cluster/spec/monitoring.go 的文件最符合。
查看代码后发现,NgMonitoringConfig 数据结构正是存储 ngmonitoring.toml 文件中数据的结构,变量 pds 正是出现 bug 的地方了。
笔者梳理了一下这里的逻辑:
- 首先定义了一个名为 pds 的变量,类型为字符串切片(string slice);
- 通过解析变量 PDServers,将一个或多个 PDServers 的信息用 append 函数添加到 pds 中;
- 将 pds 赋值给变量 ngcfg。
根据这个逻辑,可以猜测在添加元素到 pds 变量之后,数据存储的方式已经使用空格分隔。下面是一个简单的Go代码示例,用于复现该bug:
import (
"fmt"
)
func main() {
data := [...]string{"one", "two", "three"}
fmt.Println(data)
pds := []string{}
for i := 0; i < 10; i++ {
pds = append(pds, fmt.Sprintf("\"127.0.0.1:4000\""))
}
fmt.Println(pds)
}
输出结果:
根据结果,可以得出结论:无论是数组还是切片,在Go语言中,它们的结果都是用空格进行分隔的。
由此,笔者脑海中又冒出了一个疑问:如果问题是由切片存储数据导致的,那为什么之前的TiUP版本(1.11.1)没有出现同样的问题呢?
为了解决这个疑问,笔者查阅了上一个TiUP版本(1.11.1)的代码。
根据数据结构的定义,可以看到在1.11.3版本中,PDAddrs的类型是字符串(string)。而且,在赋值部分的代码中有了很大的改变,这表明部分代码在进行优化和重构之后,数据结构发生了改变,导致了bug的出现。
解决这个问题的方法很简单,只需要将pds中的元素改为逗号分隔,并传递给PDServers变量即可。因此,需要进行以下变更:
三、提交代码
//Step 1
首先需要把 TiUP 项目 Fork 到自己的仓库中,点击这个地方:
//Step 2
然后到自己的仓库中,使用在线的 vscode 进行代码编写及代码提交:
//Step 3
代码修改完毕之后,填写好修改的bug信息,然后提交并推送:
//Step 4
之后到自己的 TiUP 仓库中,创建一个 pr :
写好相关信息直接提交即可。第一次参与 TiDB 开源项目需要签署 CLA 贡献者许可协议,留意 PR 中机器人的提示就行。
最后就等待反馈,比如有人会告诉你更好的写法,或者是更好的解决方案,或者直接把 PR 合并到了 master。
到这里,一个开源项目的 bug 修复就已经完成了。
四、总结
由于笔者是第一次参与开源项目,整个过程花费了一些时间去摸索。所以在这里记录了自己成为 Contributor 的全过程,给想要为开源项目尽一份力的同学一个参考,为开源社区贡献自己的一份力量。
PS:第一次为 TiDB 开源项目做出自己的贡献还是非常令人激动的。在此感谢原厂大佬在我的 PR 基础上给了代码优化的建议。
作者:蔡一凡 | 后端开发工程师
版权声明:本文由神州数码云基地团队整理撰写,若转载请注明出处。
公众号搜索神州数码云基地,后台回复数据库,加入数据库技术交流群。