故事
乾陵的守陵人分两种:不动的石头在神道两侧站了千年,动的活人在地宫里一代一代死绝。
石头那套守在明处:朱雀门外列六十一蕃臣像,神道两侧石人石马,千年不动,风吹雨打只当没看见——它们的存在本身就是一道声明,此处不容侵犯。贼人见了,知道硬闯没好下场,多半绕道走。
活人这套守在暗处:地宫入口埋七重石门,每重由不同匠人掌管钥匙,钥匙分藏长安、洛阳、扬州三地。地宫里有水银江河、机弩暗矢,更有守陵人世代轮值。这套是动的——水银会挥发,机弩会锈蚀,守陵人会老死,得一代一代续上。
高宗驾崩后三十年,有个叫温韬的节度使起了歹心。他带了几万人马,把乾陵外围的石头仪仗砸了个遍,石人断头、石马缺腿,但地宫入口始终没找到。温韬泄了气,转去挖太宗的昭陵,一挖即中,满载而归。
后来人说起这段,总夸乾陵「固若金汤」。但守陵人的老族长知道,事情没那么简单。
温韬当年不是没找到地宫,是找到了没敢进——他手下有个偏将,在梁山北坡探到一处夯土层,刚掘三尺,触发了机弩,当场钉死两人。温韬怕的是这个:地宫里的机关他摸不清底细,六十一蕃臣像可以砸,暗弩从哪个方向来却没法猜。他算的是一笔账:昭陵没有活人守,没有机弩,只有一道石门,撬开就是;乾陵却是个活的系统,会咬人。
老族长每年清明给高宗上香,心里都悬着一件事:机弩的弦,今年紧了没有? 这是守内系统的代价——它能动,能吓人,但也需要持续地动。弦松了,暗弩变废铁;水银干了,江河成沟壑;守陵人绝了户,地宫就成了睁眼瞎。
他曾向礼部上书,说守陵人丁口日稀,请求增拨田产以募新丁。礼部回了八个字:「陵寝无恙,何必多事。」老族长捏着这八个字,在油灯下坐了一夜。他看懂了:礼部要的是「无恙」这个结果,不管你怎么维持;你要田产,就是承认「有恙」,就是失职。
这是两套逻辑的对撞。礼部要的是安全性——坏事永不发生,至少永不被人知道。老族长要的是活性——守陵这件事得持续运转,弦得有人紧,水银得有人补,人得有人换。活性是过程,安全性是结果;活性花钱、耗人、留痕迹,安全性只要一个「无恙」的报表。
老族长最终没再上书。他变卖了族中三十亩祭田,自募了十二个少年,教他们辨风向、听机括、换弩弦。这些事礼部簿子上没有,但地宫里的机弩因此又响了七十年。
—
七十年后,黄巢起兵。这回不是温韬那种小贼,是几十万流民,把乾陵外围又犁了一遍。守陵人的第十二代族长是个二十岁的年轻人,叫李慎。他面对的局面比先祖更糟:黄巢不在乎机弩,人命在他手里不值钱;他有的是时间,可以一寸一寸试。
李慎做了两件事。第一件事和第二件事。
第一件,他把地宫七重石门的机关改了。原先每重门独立,攻破一重算一重;他改成连环——触动第一重,第二重自动封死,要从头再来。这是安全性的加强:让攻击者的任何进展都无法累积,每次都得从零开始。
第二件,他派了三个守陵人,分三路逃出梁山,去长安、去凤翔、去成都,找任何还在运转的唐廷衙门报信。这是活性:承认守陵人自己的力量不够了,需要外部世界最终派来援军。三路人马可能全死在路上,可能全被截住,但只要有一个到了,消息就活了。
黄巢围了乾陵四个月。机弩的弦断了又换、换了又断,水银江河蒸腾出的毒气毒死了攻方不少人,但终究挡不住人海。第四个月末,第一重石门被撬开,第二重自动封死,攻方退回原点。第五个月,第三重石门出现裂缝,第四重封死。第六个月,黄巢不耐烦了,留下一支小队继续磨,主力转攻长安。
那支小队磨到第八个月,凤翔来的援军终于到了——不是来救乾陵的,是黄巢主力在长安受挫,撤军过凤翔时被截击,乾陵这边自然解了围。李慎派去成都的那路人,两年后还在路上,到了才发现王朝已经换了名字。
李慎后来把这段经历写进族谱,没有夸自己守住了陵,只记了一句话:「机弩可尽,人心不可尽;石门可破,信使不可绝。」
机弩和石门,是安全性——它们在说「坏事永不发生」,但任何物理屏障都有耗尽的一天。信使和援军,是活性——它们不保证坏事不发生,但保证「好事终将发生」,只要系统还在运转、还在尝试对外连接。
李慎改连环门的时候,心里清楚这是饮鸩止渴:每封死一重门,地宫就少一层保护,安全性在透支。但他更需要的是时间——让信使跑出去的时间,让外部世界最终回应的时间。没有活性,安全性是死的;没有安全性,活性是慌的。两者都要,但两者也互相撕扯:连环门封得越果断,信使的压力越大,因为退路在减少。
—
后来人修唐史,把乾陵列为「唐十八陵中唯一未被盗掘者」。这是安全性的叙事——结果论,成王败寇。守陵人的族谱里另有一笔:黄巢之后,朱温、刘知远、乃至后来的契丹、女真,每来一次,守陵人就少几户,机弩就少几架,石门就多几道裂缝。到宋初,乾陵的守陵人只剩七户,机弩全锈,水银干涸,地宫入口用土草草封住,假装它不存在。
那七户人还在,每年清明还在给高宗上香。他们守的已经不是陵,是一个还在运转的信号——告诉外界,这里还有人,这里的活性还没断。至于安全性,早就靠不住了。
宋真宗年间,有个盗墓贼摸上了梁山。他没遇到机弩,没遇到石门,只遇到七个老弱守陵人,坐在地宫入口的土堆前晒太阳。贼人亮出铲子,老人们没拦,只说:「你挖吧,里头是水银蒸气,我们七户人吸了百来年,早习惯了。你进去,一盏茶工夫就倒。」
贼人走了。老人们继续晒太阳。
这不是安全性——没有任何物理屏障在起作用。这是活性百年积累下来的信用:我们还在,我们还在处理这件事,我们的存在本身就是系统的一部分。坏事不是永不发生,是发生了也有人接着;好事不是立刻发生,是终究会有人回应。
—
概念解析
Leslie Lamport 在 1977 年把分布式系统的性质分成两类:安全性(Safety)和活性(Liveness)。这个分法后来成了形式化验证的基石。
安全性:坏事永不发生。 乾陵的机弩、石门、水银江河,都是安全性的具象——它们在说「盗墓这件事不能发生」。在分布式系统里,安全性对应的是「不会丢数据」「不会返回错误结果」「不会违反约束」。安全性一旦违反,就是不可逆的:钱转了两次,数据丢了,一致性破了,事后很难圆回来。
活性:好事终将发生。 李慎派出去的三路信使,是活性的具象——它们不保证「援军明天到」,但保证「只要还有人活着报信,外界终将知道」。在分布式系统里,活性对应的是「请求最终会得到响应」「分区最终会愈合」「选举最终会出结果」。活性违反的表现是卡死、饿死、无限等待——系统没出错,但也没进展。
为什么必须分开谈。 很多工程师直觉上觉得「既要对又要快」,把安全性和活性混成「系统要好」。但 Lamport 的划分指出:这两类性质需要完全不同的验证技术。安全性通常用不变式(invariant)来证——找出一个在系统每一步都保持为真的断言,就像老族长每年检查机弩的弦。活性通常要证最终性(eventuality)——排除所有无限循环和永久阻塞的可能,就像确认信使至少有一条路能走通。
更关键的:两者互相牵制。 李慎的连环门是最典型的例子:为了争取活性(等援军),透支了安全性(少了几层门)。分布式系统里,这种权衡无处不在——两阶段提交为了保证安全性(不会错提交)而牺牲活性(协调者挂了全体阻塞);Gossip 协议为了保证活性(随时能写)而牺牲安全性(暂时读到旧值)。FLP 不可能性([✓#15 雾中无回音])本质上就是在说:在异步网络里,同时满足安全性和活性的共识算法不存在。
活性比安全性更难证。 安全性违反是一瞬间的事——机弩断了,可以立刻看见。活性违反可能潜伏很久——信使一直在路上,你永远不知道他是还在走,还是已经死了。形式化验证里,证安全性有成熟工具(TLA+ 的 Invariant),证活性往往需要构造变函数(variant function)或井集关系(well-founded relation),技术门槛高得多。
工程上的教训。 很多系统崩溃不是因为安全性没做好,是因为活性断了却没人发现。守陵人族谱里「机弩可尽,人心不可尽」,翻译过来就是:物理屏障总会耗尽,但系统的持续运转意愿——心跳、重试、超时、降级——不能停。现代微服务的健康检查、熔断器的半开探测、队列的死信重投,都是活性机制:它们不保证这次成功,但保证系统还在尝试。
礼部那种「陵寝无恙,何必多事」的态度,在今天的组织里叫结果导向的惰性——只看最终报表上有没有报错,不看维持这个结果的过程是不是在失血。乾陵最后靠七户老人晒太阳吓退贼人,不是安全性的胜利,是活性百年积累的残余信用。但这信用不可复制,也不该被当作设计目标。
真正可靠的做法是李慎式的:明确知道自己哪部分在守安全性(连环门),哪部分在保活性(三路信使),以及两者之间的兑换率——多封一重门,能多换几天时间?多派一路信使,能多大程度对冲全军覆没的风险?
分布式系统没有乾陵的石头仪仗。连环门封到第七重,贼人总有更大的撞木;三路信使派出去,没有一路敢保证到达。现代系统比乾陵更惨:连七户晒太阳的老人都没有,只有日志里的心跳和告警,以及值班室里有没有人真的在看。