我的区块链运维日记 · 第 7 日:影子区块的诱惑 —— 多节点下的“重复充值”危机

🚨 序章:好心办坏事的高可用

前几天刚解决了单点故障的隐患,为了让系统达到 99.99% 的可用性(High Availability),我给 Scanner 做了升级:

  • 主力:AWS AMB 节点(稳重,就在自家内网)。

  • 备胎:Infura 和 Alchemy(外部公共节点集群,全球都有)。

我的逻辑是:"三个臭皮匠顶个诸葛亮。AMB 要是挂了,备胎立刻顶上,保证 Scanner 永远有数据抓。"

结果,早上 10 点,客服主管冲进来说:"Henry!有个用户只充了 10 ETH ,但咱们给人家加了 20 ETH!这钱是天上掉下来的吗?"


🎬 第一章:消失的唯一性

我第一时间查了数据库,看到了让我窒息的两行记录:

记录ID 交易哈希 (TxHash) 金额 区块哈希 (BlockHash) 数据来源 时间
#101 0xabc... +10 0x111... (宇宙A) AWS AMB 10:00:01
#102 0xabc... +10 0x222... (宇宙B) Infura 10:00:03

同一笔交易,被记了两次账。 唯一的区别是,它们属于两个完全不同的区块哈希。

这意味着:在那个瞬间,我们的系统同时相信了两个"平行的世界"。


🕵️‍♂️ 第二章:原理复盘 ------ 村口的黑板报

为了搞懂为什么会有两个世界,我给团队画了一个**"区块链村"**的比喻。

1. P2P 网络(传播是有时差的)

区块链村没有广播站,消息全靠村民(节点)之间口口相传。

  • 现象:村东头发生了什么事,传到村西头需要几秒钟。

  • 后果 :在某一秒钟,东头的人以为"王五赢了",西头的人以为"孙七赢了"。这就是分叉(Fork)

2. 节点的性格分析
  • AWS AMB(我们的老村长)

    • 性格:稳重、死板。

    • 行为:他一定要等全村大部分人都确认了(12 个确认数),才肯在自家的黑板上写字。写上去就是**"铁案"**,基本不会擦掉。

    • 缺点:反应慢半拍。

  • Infura(消息灵通的八卦王)

    • 性格:急躁、甚至有点"听风就是雨"。

    • 行为 :他眼线多,只要听到一点风声(比如产生了一个新块),他立刻就会写在黑板上(打草稿)。

    • 风险:如果过了一会儿发现消息是假的(分叉被回滚),他会立刻拿黑板擦擦掉,重写正确的。

3. 事故真相

我们的 Scanner(抄账员)犯了两个错误:

  1. 乱跑:先去了老村长家(AMB)抄了一笔确定的账(宇宙 A)。

  2. 轻信草稿 :紧接着又跑到了八卦王家(Infura),看到黑板上写了个不一样的区块(宇宙 B),以为是新消息,赶紧又抄了一遍。殊不知,那只是 Infura 打的草稿,还没来得及擦掉。


🛠️ 第三章:Henry 的三板斧修复方案

为了防止"假传圣旨",我进行了架构级重构:

1. 数据库层面的"死锁" (The Hard Stop)

我在 RDS 数据库里执行了一条死命令:

ALTER TABLE deposits ADD CONSTRAINT unique_tx UNIQUE (tx_hash);

  • 逻辑 :不管外面有多少个平行宇宙,不管 Scanner 从哪个节点抄来了数据,同一个 TxHash 在数据库里只能存一次

  • 效果 :如果 Scanner 试图插入第二笔 0xabc...,数据库会直接报错,物理隔绝重复充值。

2. "主从锁定"策略 (Primary First)
  • 旧逻辑:随机轮询(Round Robin)。谁有空问谁。

  • 新逻辑独宠 AMB

    • Scanner 永远只问 AMB。

    • 只有当 AMB 彻底断气(Timeout > 1min),才允许去问 Infura。

    • Henry 语录"老村长的消息虽然慢,但是准。管钱的事,要准不要快。"

3. "回溯校验"机制 (Look-Back Check)

如果被迫切换到了 Infura,Scanner 必须执行一套**"对齐仪式"**:

  • 动作 :不查最新块,先查上一个块(N-1)

  • 判定:问 Infura:"你眼里的 N-1 块哈希,跟老村长(AMB)之前记的一样吗?"

    • 如果一样 -> 说明你们在一个频道,继续工作。

    • 如果不一样 -> 说明 Infura 正在看"别的频道",立即停机,等待它同步回来。


📚 第四章:运维深度问答 (Q&A)

Q1: 为什么 Infura 的数据会不准?是它质量不好吗?

  • Henry: 不是质量不好,是角色不同 。Infura 是为了给前端钱包(Metamask)提供极速体验的,所以它必须快,哪怕偶尔有分叉也没关系。但我们做的是后端入账,我们需要的是 Finality(最终确定性)。用跑车的速度去拉货,必然会翻车。

Q2: 为什么 AMB 需要"等很多个同步一样"才发给我们?

  • Henry: AMB 节点通常只连接了有限的几个 Peers(邻居)。它内部有校验机制,会等待这些 Peers 达成共识后,才更新自己的区块头。这就相当于它是经过了"二次过滤"的数据,虽然慢,但过滤掉了大部分网络噪音。

Q3: 所谓的"草稿"和"封存"在技术上是什么?

  • Henry:

    • 打草稿 = 只有一个块头(Block Header),状态是 Canonical 但没经过足够多确认,随时可能变成 Uncle Block(叔块/孤块)。

    • 封存 = 区块后面连接了 12 个以上的新块,攻击成本极高,被全网回滚的概率接近 0。


💡 Henry 的日记结语

"第 7 天的教训告诉我:在分布式系统里,'一致性'是奢侈品。

以前我觉得高可用就是多接几根管子。今天我才知道,管子接多了,流进来的不一定是水,可能是洪水。

给数据库加上'唯一锁',并且学会区分'草稿'和'正文',是每个区块链运维必须修满的学分。"

相关推荐
爱华晨宇3 分钟前
Xshell高效运维实战指南
运维·服务器
未来之窗软件服务3 分钟前
服务器运维(四十一)日服务器linux-audit.log分析工具—东方仙盟
linux·运维·服务器·服务器运维·仙盟创梦ide·东方仙盟
志栋智能12 分钟前
AI驱动的自动化运维机器人:从“数字劳动力”到“智能协作者”的进化
大数据·运维·网络·人工智能·机器人·自动化
guizhoumen30 分钟前
建站从零开始之域名、服务器和CMS网站程序的选择
运维·服务器·网络
笨蛋不要掉眼泪31 分钟前
OpenFeign远程调用详解:声明式实现、第三方API集成与负载均衡对比
java·运维·负载均衡
Codefengfeng39 分钟前
Kali安装工具通用教程
运维·服务器
姜行运39 分钟前
[Linux]基础指令3
linux·运维·服务器
dashizhi201539 分钟前
服务器共享文件设置权限、共享文件防止删除复制打印?
运维·服务器
xiaoliuliu123451 小时前
银河麒麟V10安装 zlib-1.2.11-20.ky10.x86_64教程(含依赖解决)
linux·运维·服务器
袁袁袁袁满1 小时前
Linux/Window如何查网络连接/端口/套接字信息?
linux·运维·服务器·网络安全·网络连接