我用了四周、从零学 Go,做出了一个"系统时光机"
一个让我抓狂的问题 上周我在调试一个 bug,花了两个小时才发现——问题在昨晚某个时间点一个配置文件被悄悄修改了。我当时就想:如果有一个工具能告诉我"昨晚 10 点到 11 点,我的系统到底发生了什么",该多好。 我为什么选择用 Go 来做这件事 我之前只会使用Python、Java,Go这个语言其实对我来说是完全陌生的存在,我对Go的了解最初也是从我的同事那里听到的,他说我要是有空闲的时间就试着学学Go,我也不懂Go的魅力在什么地方。 我也是抱着试一试的心态去学习Go,毕竟项目驱动学习是让我觉得学习一个新东西是最快的,并且也是最有成效的一个东西。 我先是用了大模型去进行查询Go的基础语法,看到 =: 这玩意不懂这跟Python、Java、C++这类的语法规则完全不一样,也不知道goroutine 和线程有什么区别,为什么错误处理要写if err != nil 而不是 try/catch。这就让我很抓狂了但是最后也是想着多学一点是一点的心态进行学习。 Event Sourcing:我学到的最重要的概念 在开始写代码之前,我以为 ChronoTrace 的存储逻辑很简单——每隔几秒扫描一次系统状态,把结果存起来就行了。 直到我真正想清楚需求:我需要知道某个文件是什么时候被删的,某个进程是什么时候启动的。定时快照做不到这件事。如果一个进程在两次快照之间启动又退出,它就像从未存在过一样。 这让我意识到,我需要的不是"记录状态",而是"记录发生的事情"。这就是 Event Sourcing 的核心。 先从一个你熟悉的例子说起 想象你的银行 App。 它显示的余额是 500 元——这是"当前状态"。但银行后台实际存储的不只是这个数字,而是一条条的流水记录: 1 2 3 4 5 存入 100 元 ← 事件1 取出 200 元 ← 事件2 存入 600 元 ← 事件3 ───────────── 余额 500 元 ← 把所有事件加起来算出来的 余额不是直接存储的,它是从事件计算出来的。 这意味着什么?意味着你可以回答任何时间点的问题:三天前我有多少钱?某笔钱是什么时候进来的?如果只存余额,这些问题永远无法回答。 Event Sourcing 就是把这个思路用在软件系统里:不存储"现在是什么",只存储"发生了什么"。 用传统做法对比一下 如果 ChronoTrace 用传统方式设计,代码大概是这样: ...