
同步队列的秘密:离线POS如何协调两个收银机
我们开发Pultrack,这是一款为小零售商设计的收银和库存应用,他们面对不稳定的电力供应、不完善的网络连接,以及同一个货架上常常有两种货币。所以当一波关于"离线优先POS"的工程文章传播开来时,我们像一个店主那样阅读它们:不是看架构图,而是思考一个周二网络在班次中期掉线时会发生什么,当时两个人仍在为客户结账。
离线优先讨论中真正新颖的是什么?
最近关于离线优先收银系统设计的技术文章在一点上达成共识:离线操作不再被视为需要修补的边缘情况,它现在是整个系统的起点假设。[1] 实现方式趋同于一个熟悉的技术栈——设备上的本地数据库(IndexedDB或SQLite)、待处理操作队列、幂等同步API,以及连接恢复时的某种冲突解决机制。[1] 多个供应商的页面将这个特性表述为业务承诺而不仅仅是技术细节:即使互联网不配合,收银机也能继续工作,所以店铺也能继续赚钱。[2]
这个表述很有用,也大体准确。但几乎没有任何公开材料花真正的时间在那个实际决定一家小店是否信任该系统的部分上:在两个离线设备重新连接后的那几秒和几分钟内发生什么,当它们都声称售出了同一件商品、退款给了同一个客户或结束了同一班次时。
为什么单一收银机的店铺也会遇到这个问题?
我们很容易假设协调冲突是"多店铺"或"企业级"的问题。但事实并非如此。一家角落店从它拥有多于一种在离线时记录销售的方式的那一刻就会遇到这个问题——一部在柜台的手机和一块在储藏室附近的平板电脑、一个收银员的设备和店主的设备,或只是同一部设备在同步过程中因断电而重启。从离线优先设计的意义上讲,这每一个都是一个独立的"节点",每个都会将自己的本地写入排队,直到能再次与服务器通信。[1]
架构模式通过同步队列和幂等操作来处理这个问题,这样重复播放一个操作就不会重复计费或重复扣除库存。[1] 那是正确的工程答案。零售问题是不同的:当同一个物理班次产生两个本地"真实"的事件版本时——比如,在一个设备上应用的折扣和在另一个设备上记录的同一件商品的全价销售——店铺的每日总额应该反映谁的版本,店主在他们已经对收银机里的现金进行协调之前还是之后才能发现这一点?
"收入连续性"遗漏了什么?
供应商越来越多地用收入连续性的术语来描述离线能力:即使网络停止工作,收银机也不会停止销售。[3] 这是一个公平且重要的说法,特别是对于网络中断是常规而非罕见的市场。但停机期间的收入连续性只是故事的一半。另一半是停机后的协调准确性——最终同步回记录系统的总额是否与柜台实际发生的事情相匹配,逐件、逐种货币地。
对于同时运营两种货币的店铺来说,这重要得多。一个用本地货币以一个汇率离线记录的销售,几小时后在汇率已经变动后同步,会在货架说的内容和账簿现在显示的内容之间造成一个真实但微小的差距。我们查看的所有公开离线优先文章都没有专门涉及多货币协调——这是一个值得指出而不是掩盖的差距。
"本地优先"与"协调安全"是同一回事吗?
不是自动的。当前离线优先材料中更广泛的论点是,小商家不需要"带离线模式的云POS"——他们需要商务基础设施,其中互联网被视为同步渠道,而不是依赖。[4] 这是一个健全的设计原则,也是思考连接的正确方式。但"本地优先"描述的是数据的位置和捕获方式;它本身并不保证两个本地真实合并成一个正确的班次总额。冲突解决逻辑——最后写入胜出、人工审查队列、事件溯源重放——是一个设计选择,具有真实的权衡,它是决定店主是否能信任关闭时屏幕上显示的数字的部分。
一些实践中将"离线能力"与"协调安全"区分开的实用模式:
- 每个离线交易在被排队之前都会得到一个稳定的、由设备生成的唯一ID,所以重放或重复同步永远不能重复计数。
- 冲突浮现给人类——即使是一个简单的"这两条记录不一致,选择一个"提示——而不是被静默解决,即无论哪个设备最后同步。
- 货币和汇率值被锁定在销售时刻,而不是在同步时重新计算,所以延迟同步不会悄悄改变班次的报告值。
- 班次总额从完整事件日志重建,而不仅仅是最后已知状态,所以审查可以准确显示哪个设备记录了什么和何时记录的。
小店在购买之前应该如何真正评估这一点?
因为这个话题上发布的大部分内容来自供应商博客、工程案例研究和产品营销页面,而不是独立审计,所以值得将"离线优先"标签本身视为营销简称而不是保证。底层架构——本地存储、同步队列、幂等API——确实在各产品中趋同。[1] 但每个供应商处理混乱中间部分的方式差异很大,而且很少被公开记录:多设备冲突、同步延迟期间的货币漂移,以及店主是否能实际看到并纠正有争议的交易,而不仅仅是相信总额。
在Pultrack,这是我们花最多工程时间的部分,正好因为当它工作时不可见,当它不工作时很昂贵:每个离线销售都带有自己的时间戳、设备来源和锁定的汇率,冲突记录浮现供审查,而不是静默地相互覆盖。我们认为这是谈论离线韧性更诚实的方式——不仅仅是"它保持销售",而是"它之后保持计数正确"。
如果您在比较离线优先POS选项,值得问供应商的问题不是关于正常运行时间声称。它们是关于当两个曾经都离线的设备同时回到在线时您的数字会发生什么。