异地恋,用我做了十来年系统架构的视角看,就是一个典型的分布式系统。两个节点,各自独立运行,中间隔着一条网络链路,链路质量还不稳定。普通恋爱是单机应用,两个人同处一座城市,所有状态都在本地,实时同步,出了问题也好排查。异地恋不一样,它天然就是分布式,天然就要处理网络延迟、节点故障、状态不一致。这三个词,随便拿出一个,都是系统架构里的大课题。所以异地恋“跑不通”非常正常,不是人的问题,是系统架构的问题。
这篇文章我想从系统架构的角度,把异地恋为什么“跑不通”、“高维护成本”到底高在哪、以及如果真的想“优化”这段关系的性能,有哪些可落地的操作思路,一次讲清楚。不管你是正在异地恋、准备异地,还是你本身就搞分布式系统,这篇文章都值得花几分钟看完。看懂这套架构逻辑,你会少生很多没必要的闷气。
1. 先把异地恋画成一张架构图:它到底是个什么系统
1.1 从“单机系统”到“分布式系统”:恋爱内核的架构演进
你可以把“恋爱”这个产品,想象成一个系统。非异地恋呢,就是单机部署。两个人物理上待在一起,一起吃饭,一起逛街,一起面对每天发生的所有事。系统的状态是共享的,消息是同步的,延迟以毫秒计,几乎可以忽略不计。这种架构最大的好处是确定性高:对方不高兴,你当场就能看到,当场就能处理,处理完了,状态立刻恢复。就像在本地调试代码,变量值变了,你马上能看到输出结果,不用远程连上去猜。
而且单机系统还有一个隐藏红利:不需要设计复杂的通信协议。你想说什么,直接说出口就能被接收;对方的状态,你抬眼就能看到。所有信息都在一个进程空间里,没有序列化、没有网络传输、没有消息丢失。这种系统跑起来非常省心,维护成本极低,就像一台嵌入式设备跑裸机程序,确定性强,响应快,出问题也好调试。哪怕真出了问题,现场就在眼前,拿个调试器就能定位。
异地恋一上线,架构就变了。两个节点,分布在两地,各自运行着独立的生活进程。你不能直接访问对方的本地内存,只能通过网络请求去获取状态。这个网络请求,就是你们的聊天、电话、视频。问题是,网络请求天然是异步的、有延迟的、会丢包的。所以在异地恋里,第一层高维护成本就来自通信链路本身。你可以理解成,一个原本可以本地直接调用的系统,现在变成了RPC远程调用——所有原来免费的东西,现在都要收费,而且要额外处理超时、重试、乱序、语义丢失这些问题。
这种架构模式,在分布式系统里有个很出名的判断标准:任何一次远程调用,都和本地调用有着本质区别。你不仅要考虑“对方是否在线”,还要考虑“消息是否送达”“对方理解的是否是你表达的”“你们的状态是否已经同步”。这些在单机系统里根本不存在的问题,在分布式系统里每一个都是大坑。
1.2 异地恋的拓扑结构:双活数据中心,还是冷备从机?
从部署拓扑上看,异地恋最理想的模型是“双活数据中心”:两个节点都在运行,都有完整的数据(各自的生活),通过专线同步数据,任何一个节点挂了,整个系统还能继续对外提供服务。听起来不错,但双活的代价极高。数据同步要实时、要可靠、要无冲突,这在工程上是最难解决的问题之一。分布式系统从业者都知道,双活就是“听起来很美,做起来想哭”的代名词。
绝大多数异地恋,实际上跑的不是双活,而是“主从复制”。一方是主节点,另一方是备节点,备节点靠主节点定期同步数据来维持状态。典型场景就是:一个在外面打拼,定期向留守的一方“汇报”生活状态;留守的一方,生活半径相对固定,主要等待主节点的数据同步。这种架构的好处是简单,坏处是备节点长期处于“被动接收”状态,自己的状态没有被真正的“本地存储”,时间长了就会出问题。
问题是,谁当主节点?如果两个人都认为自己是主节点,都往本地写状态,那版本迟早要分叉。如果一方长期当备节点,那这个人就会觉得自己的生活只是对方的附属品,自己的状态没有被真正的“本地存储”,这其实就是很多异地恋里“我好像只是你的一个异步任务”这种感觉的来源。主从切换也不是没有,每次见面可能就切换一次,但切换过程中谁负责写?谁负责读?这事情如果没提前说清楚,跑出双主甚至多主(多个人?)的拓扑,那这个系统就直接不可用了。
另外,还有一种常见拓扑叫“冷备从机”,就是平时根本不怎么同步,只在节假日集中
