不仅数据有一致性问题,代码的一致性问题更加遍地都是。判断主机是否运行应该面向 libvirt 接口,而不是面向实现中的文件、过程。
现象
我们有个查看虚拟机如果异常关闭、将其拉起的机制。
它判断主机是否在运行的依据是 xml!这非常不对。
而且在服务启动的时候,会去清理 xml,到处都是零散的变更逻辑。你改一个功能都不知道影响哪些。
根因:面向实现,而不是面向接口
判断 xml 显然不符合一致性,因为 virsh 才是根本。
大家都面向 libvirt 接口来判断,就不存在那么多问题了,也不存在要清理 xml,或者说清理 xml 影响不大了。
典型的面向实现,而不是面向接口。
事实是我们依赖 libvirt 搭建的 iaas 平台,所以得围绕 libvirt api,而不是实现中的文件、过程。
面向接口而非面向实现。
一致性来源
另外,主机属于哪个节点、状态是什么,应该有一个一致性的来源。
比如 k8s 就是 etcd。
我们这玩意,自己在那判断然后和数据库做对比,但不是以数据库为准,而是自己判断,美其名是为了根据实际情况避免双写,实际更加复杂和错乱。
go 的 defer 就是典型的一致性表现
这种一致性,在哪里创建,就在那里跟着关闭。
而不是在其他零散的地方关闭,容易忘,也容易乱套。
小结
- 代码也有一致性问题,而且更加遍地都是;
- 判断主机是否运行应该面向 libvirt 接口,而不是面向实现中的文件、过程;
- 面向接口而非面向实现;
- 主机属于哪个节点、状态是什么,应该有一个一致性的来源(如 k8s 的 etcd);
- go 的 defer 是典型的一致性表现:在哪里创建,就在那里跟着关闭。