入职 Web3 运维日记 · 第 5 日:硬分叉倒计时 —— 给飞行中的飞机换引擎

时间 :入职第 5 天 天气 :晴,由于肾上腺素飙升感觉有点热 任务 :以太坊 "Shanghai" (上海) 硬分叉升级 SLA 要求:业务零中断

刚到公司打开 Slack,我就感受到了一股紧迫的气氛。 #announcements 频道里弹出了一条加急通知:以太坊主网将于区块高度 18,500,000 正式激活 "Shanghai" 升级。

组长把我叫到白板前,画了两条线:一条向左,一条向右。 "Alen,这是硬分叉 (Hard Fork)。如果我们在高度达到之前没有升级 Geth 和 Lighthouse,我们的节点就会因为不认识新规则,跑向右边这条废弃的分叉链。到时候 Scanner 读到的就是假数据,这属于 P0 级事故。"

目前的挑战:

  1. 截止时间:还有 48 小时。

  2. 业务限制 :Scanner 正在高频扫链,一秒钟都不能停。停机意味着漏块,漏块意味着用户充值无法入账。


🧠 1. 上午 10:00:制定策略 ------ 拒绝原地升级

我的第一反应是像维护 Web2 服务那样:停服务 -> 换包 -> 重启。 但在脑子里预演了一遍后,我否决了这个方案。

  • 风险点

    • Geth 在重启时需要重新加载巨大的数据库索引,可能耗时 5-10 分钟。这段时间 Nginx 会报 502,Scanner 业务会断。

    • 万一新版本 binary 有 Bug 起不来,或者数据库结构不兼容需要 Migration(迁移),那我就挂在半空了,回滚都来不及。

决定方案:AWS 蓝绿部署 (Blue/Green Deployment) 我要起一台全新的 Node B (Green) ,在后台升级并同步好。等它准备就绪,再在 Nginx 层把流量像扳道岔一样切过去。用户无感,风险可控。


☁️ 2. 上午 11:00:AWS 的"时间魔法" ------ EBS 快照

如果从零同步一台新节点需要 2 天,根本来不及。这时候,我作为 AWS 老兵的经验派上了用场。

操作步骤:

  1. 制作快照 (无需停机) : 我登录 AWS 控制台,找到正在运行的 Node A (旧节点) 的数据盘卷 (vol-xxxxxx)。这块盘是 io2 类型的,支持高性能热快照。

    • Action : Create Snapshot

    • Description : eth-mainnet-pre-shanghai-fork

    • 耗时: 因为是增量快照,大约 15 分钟就完成了。

  2. 克隆磁盘 : 用刚刚做好的快照,创建一块新的 EBS 卷 (vol-yyyyyy)。

    • Type : io2 Block Express (必须保持高性能)

    • IOPS: 10,000

    • Size: 2000 GB

  3. 启动 Node B : 启动一台新的 EC2 实例 (r6g.2xlarge),把这块新磁盘挂载到 /dev/nvme1n1

此时的状态 : 我拥有了一台 Node B,它的硬盘里拥有 Node A 15 分钟前所有的区块链数据(包括 JWT 密钥等配置文件)。我省去了 2 天的同步时间


🛠️ 3. 下午 2:00:在 Node B 上执行升级

现在,我有充足的时间在 Node B 上折腾,完全不影响正在跑业务的 Node A。

SSH 连接 Node B 进行操作:

  1. 挂载磁盘

    复制代码
    sudo mount /dev/nvme1n1 /data/ethereum
    # 确认数据都在
    ls -l /data/ethereum/execution/geth/chaindata
  2. 下载新版本客户端 : 根据公告,我们需要 Geth v1.11.5 和 Lighthouse v4.0.1

    复制代码
    # 下载并解压 Geth
    wget https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.11.5.tar.gz
    tar -xvf geth-linux-amd64-1.11.5.tar.gz
    sudo cp geth-linux-amd64-1.11.5/geth /usr/local/bin/geth
    
    # 下载并解压 Lighthouse
    wget https://github.com/sigp/lighthouse/releases/download/v4.0.1/lighthouse-v4.0.1-x86_64-unknown-linux-gnu.tar.gz
    tar -xvf lighthouse-v4.0.1-x86_64-unknown-linux-gnu.tar.gz
    sudo cp lighthouse /usr/local/bin/lighthouse
  3. 关键验证 (Version Check): 在启动前,必须确认新程序包含了硬分叉的代码逻辑。

    复制代码
    /usr/local/bin/geth version
    # Output: Version: 1.11.5-stable
    # Check flags: ShanghaiTime = 1681338479

    看到这个时间戳,我就放心了。

  4. 启动服务: 使用 Day 1 写好的 systemd 脚本(无需修改,因为目录结构一样)。

    复制代码
    sudo systemctl start geth lighthouse

同步追赶: 因为快照是几小时前打的,Node B 启动后,Lighthouse 迅速连接 Peers,指挥 Geth 开始下载这几个小时落后的区块。

  • journalctl -fu geth 显示:Importing new chain segment

  • 15 分钟后,日志显示 age=4sNode B 已追平主网,且运行着最新版本。


🔀 4. 下午 4:30:无感切换 (Traffic Switch)

现在我有两套环境:

  • Node A (旧) : 172.31.20.100,正在承载 Scanner 流量。

  • Node B (新) : 172.31.20.101,已同步,空闲。

我在 Node A 上配置了 Nginx(参见 Day 4),现在只需要修改 Nginx 的后端指向,就能把流量引到 Node B。虽然这会引入一次跨机器的内网跳转(约 1ms 延迟),但为了平滑升级,这是值得的。

修改 Nginx 配置:

复制代码
# /etc/nginx/sites-available/ethereum-rpc.conf

upstream geth_backend {
    # [旧配置] 指向本机 (注释掉)
    # server 127.0.0.1:8545;
    
    # [新配置] 指向 Node B 的内网 IP
    # 保持长连接 (keepalive) 以减少 TCP 握手开销
    server 172.31.20.101:8545;
    keepalive 32;
}

执行切换命令:

复制代码
# 检查配置语法
sudo nginx -t 
# 平滑重载 (不中断现有连接)
sudo nginx -s reload

✅ 5. 下午 5:00:验证与收尾

切换的一瞬间,我盯着三个窗口:

  1. Scanner 业务日志 :一片祥和,没有 502,没有 Timeout。业务方甚至没感觉到发生了变化。

  2. Node B 监控:CPU 和网络流量瞬间上来,开始处理请求。

  3. Node A 监控:流量归零,变成了一台安静的备用机。

后续处理: 我并没有立即销毁 Node A。

  • 我登录 Node A,把它的软件也升级到了最新版。

  • 我把它保留作为 Cold Standby (冷备)

  • 如果明天 Node B 所在的 AWS 可用区 (Availability Zone) 挂了,或者新硬盘坏了,我只需要把 Nginx 配置改回 127.0.0.1,一秒钟就能切回来。

今日总结: Web3 的升级比 Web2 更残酷,因为涉及"共识"。一旦掉队,就是两个世界的差别。 但运维的本质是不变的------利用冗余架构(AWS 快照 + 蓝绿部署)来对抗不确定性


📚 Day 5 特别附录:硬分叉与网络架构详解

1. "Shanghai Upgrade" (上海升级) 是什么意思?是在上海进行升级吗?

Alen 的回答: 哈哈,不是的。这只是一个 "代号"

  • 命名规则 :以太坊的每一次重大升级,通常会用 "Devcon(开发者大会)举办过的城市" 来命名。

  • 历史

    • 比如以前有 "London Upgrade"(伦敦升级,EIP-1559 燃烧机制)。

    • 这次叫 "Shanghai Upgrade"(上海升级,允许信标链质押提款)。

    • 下次可能叫 "Cancun Upgrade"(坎昆升级)。

  • 本质 :这就像 Android 系统用甜点命名(安卓 8 是 Oreo,安卓 9 是 Pie),或者 macOS 用加州地名命名(Mojave, Catalina)一样。它只是指代 v1.11.5 这个版本引入的一系列新功能,跟物理地点毫无关系。


2. "确认了最终高度",是说老版本到了这个高度就必须换新版本?

Alen 的回答: 是的,绝对必须换。

  • 原理:区块链的代码里其实写了一段像"定时炸弹"一样的逻辑:

    复制代码
    if current_block_height >= 18,500,000:
        use_new_rules()  # 使用上海升级的新规则(比如允许提款)
    else:
        use_old_rules()  # 继续用老规则
  • 老版本的 Geth :它的代码里没有 new_rules() 这部分逻辑。

  • 后果 :当区块高度达到 18,500,000 时,全网都在用新规则打包区块。你的老版本 Geth 会看着新区块说:"咦?这个区块格式不对啊,我不认!" 于是,你的老节点就会拒绝同步接下来的所有新区块,或者卡死,或者走上一条错误的路。


3. "Scanner 读到假数据,用户充值到了但我们看不到"是什么意思?(通俗解释)

Alen 的回答: 这是最可怕的后果。我们用 "火车变轨" 来打比方。

  • 场景

    • 区块链就像一条铁轨,所有节点都是火车,跑在同一条轨道上。

    • 高度 18,500,000 是一个 "变轨点" (Switch)

  • 正常情况(升级了的节点)

    • 到了变轨点,大家按照新地图,向 "左" 拐,继续在那条繁华的 主网 (Mainnet) 上跑。

    • 用户的充值交易(比如 100 ETH),都在这条 主网 上。

  • 异常情况(没升级的 Alen 节点)

    • 到了变轨点,Alen 的老节点没有新地图,它不知道要向左拐。

    • 它会直直地向 "右" 冲过去,进入一条 "废弃的岔路" (Forked Chain)

    • 关键点:这条岔路可能也会生成区块(虽然是无效的),Alen 的节点会以为自己还在正常跑。

  • 结果

    • 用户 :在 主网(左边)充了 100 ETH。Etherscan 上显示到账了。

    • Alen 的 Scanner :连着 Alen 的老节点,盯着 废弃岔路 (右边)。废弃岔路上没有这笔 100 ETH 的交易。

    • 悲剧:Scanner 告诉公司数据库:"没有充值"。用户怒了:"链上明明有钱,你们交易所吞我钱!"

这就是所谓的 "跑到分叉链上" ,Scanner 读到的全是那条废弃链上的 "假数据"(或者说是平行宇宙里的无效数据)。


4. Nginx 指向另一台机器 (Node B),会有网络延迟影响吗?

Alen 的回答: 你非常敏锐!这里确实有网络拓扑的变化,但在这个场景下是 可以接受的

我们来对比一下 "不能跨机器""能跨机器" 的区别:

A. 为什么 Geth 和 Lighthouse 不能跨机器(或最好别跨)?
  • 通信频率:极高。每秒钟可能交互几百次。

  • 协议:Engine API。

  • 敏感度 :这是共识层 。如果延迟高了,会导致验证签名超时,直接导致节点漏块。这是毫秒必争的。

B. 为什么 Nginx 和 Geth 可以跨机器?
  • 通信频率:中等。Scanner 业务每秒发几百个请求查询余额。

  • 协议:HTTP / JSON-RPC。

  • 敏感度 :这是业务层

    • 内网延迟 :AWS 同一个 VPC 内网(同可用区),服务器 A 访问服务器 B,延迟通常在 0.5ms ~ 1ms 左右。

    • 业务容忍度 :Scanner 查询一个余额,Geth 处理需要 20ms。加上 Nginx 的转发 1ms,变成 21ms。对业务来说,这 1ms 的差距完全无感。

结论 : 在"蓝绿部署"这种特殊升级时刻,为了保证 0 停机,引入这 1ms 的内网延迟是完全划算的交易。等升级稳定了,Alen 其实可以把 Nginx 再改回指向 Localhost,或者干脆就把 Node B 当成新的主节点用下去。


相关推荐
代码游侠1 小时前
学习笔记——Linux内核与嵌入式开发2
linux·运维·arm开发·嵌入式硬件·学习·架构
Fᴏʀ ʏ꯭ᴏ꯭ᴜ꯭.1 小时前
Nginx性能调优与压测实战指南
运维·nginx
wefg12 小时前
【Linux】进程地址空间深入理解
linux·运维·服务器
leisigoyle2 小时前
SQL Server 2025安装教程
大数据·运维·服务器·数据库·人工智能·计算机视觉·数据可视化
Linux运维技术栈2 小时前
Magento 2.3.5 宝塔Linux环境完整安装指南(避坑版+图文详解)
linux·运维·服务器
龙飞052 小时前
Kubernetes 排障实战:PVC 一直 Pending 的原因与解决方案
运维·学习·云原生·容器·kubernetes
酣大智2 小时前
FTP--文件传输协议
运维·网络·网络协议·tcp/ip·华为
古月-一个C++方向的小白2 小时前
Linux——命令行参数与环境变量
linux·运维
qinyia2 小时前
使用AI助手完成服务器系统备份迁移任务
linux·运维·服务器