☰
Docker Swarm 高可用 Web 集群搭建实战:从选型到运维
2026/10/21 13:25:05 网站建设 项目流程

1. 为什么我最终选了 Docker Swarm 而不是 K8s

1.1 一个真实的需求场景

去年下半年,我接手了一个内部工具平台的部署改造。背景很简单:一套 Web 服务,日活不高但要求 7x24 在线,之前跑在一台单机上,用 systemd 管着几个进程,每次发版靠脚本 kill 掉再拉起来,中间有十几秒的服务中断。业务方虽然嘴上不说,但监控群里偶尔冒出来的 502 报警截图,大家都心知肚明。

需求拆下来其实就三条:第一,服务不能有明显中断,滚动更新是底线;第二,节点挂了要能自动把容器调度到别的机器上;第三,运维成本要低,团队里没有专职的容器平台工程师,谁都能上手改配置、看状态。

摆在面前的选择无非就是 Docker Swarm 和 Kubernetes。K8s 生态确实强大,但它的学习曲线和运维复杂度对于这个体量的项目来说,属于典型的杀鸡用牛刀。我算过一笔账:上 K8s 意味着至少要维护 etcd、apiserver、controller-manager、scheduler 这一整套控制面,再加上 CNI 网络插件、Ingress Controller、监控栈,光是 YAML 文件就能堆出几十个。而 Swarm 是 Docker 引擎内置的,docker swarm init一条命令就能起一个集群,节点加入只需要一个 token。

最终我选了 Swarm。不是说它比 K8s 好,而是在这个具体场景下,它的投入产出比最高。这篇文章就把我从零搭这套高可用 Web 集群的完整过程拆开讲,包括架构设计、参数选择、踩过的坑,以及那些文档里不会写的实操细节。

1.2 Swarm 的架构到底是怎么回事

很多人对 Swarm 的印象停留在"Docker 自带的那个编排工具",但具体它怎么工作的说不清楚。我用一个类比来解释:Swarm 集群就像一家连锁餐厅,Manager 节点是店长,Worker 节点是厨师。

Manager 节点负责决策——哪个菜(容器)放到哪个厨师(节点)那里做,现在有几个订单(服务副本),需不需要加人。Worker 节点只管执行,收到任务就干活。Manager 之间通过 Raft 协议保持一致,这意味着如果有 3 个 Manager,挂掉 1 个集群照样运转,挂掉 2 个就歇菜了。所以生产环境 Manager 数量必须是奇数,3 个是性价比最高的选择。

这里有个关键点容易被忽略:Manager 节点默认也可以跑任务。也就是说如果你只有 3 台机器,全做成 Manager,它们既管调度又跑容器。小集群这样没问题,但如果 Manager 负载高了,Raft 心跳可能延迟,影响调度决策。我的做法是给 Manager 打上availability=drain标签,让它们只做管理不跑业务容器,业务全部调度到 Worker 上。

Swarm 的调度粒度是 Service,一个 Service 定义了你想要的状态——用哪个镜像、跑几个副本、暴露哪个端口、怎么更新。Swarm 会持续对比"期望状态"和"实际状态",不一致就自动纠正。这就是声明式编排的核心:你告诉它你要什么,它负责达成,而不是你一步步指挥它怎么做。

1.3 高可用的三个层次

"高可用"这个词被用烂了,但在 Swarm 集群里,它其实对应三个不同层次的东西,得分开看。

第一层是服务高可用。同一个 Service 跑多个副本,分散在不同节点上。一个容器挂了,Swarm 在几秒内会在别的节点重新拉起一个。这解决的是单容器进程崩溃的问题。

第二层是节点高可用。一台物理机或虚拟机宕机,上面的容器全部消失,Swarm 检测到节点失联后,会把这些容器重新调度到健康节点上。这解决的是单机故障。

第三层是入口高可用。所有外部流量打进来的入口不能是单点。Swarm 内置了 Routing Mesh(路由网格),每个节点都监听服务发布的端口,流量可以在任意节点进入,然后转发到实际运行容器的节点。这意味着你前面挂一个负载均衡器指向所有节点就行,不需要关心容器具体在哪台机器上。

这三层缺一不可。我见过有人只做了副本数 3,但入口只有一个节点,结果那个节点一挂整个服务就不可达了。所以设计的时候要把这三层都想清楚。

2. 集群搭建前的准备工作与关键决策

2.1 机器规划与网络设计

我用了 5 台虚拟机,配置如下表。这个规模对于中小型 Web 集群足够用了,再大就得考虑更多 Manager 和网络分段。

角色数量配置说明
Manager32C4G只做管理,不跑业务容器
Worker24C8G跑 Web 服务和缓存
负载均衡11C2G独立机器,跑反向代理

网络方面,所有节点必须在同一个二层网络里能互相通信,这是 Swarm 的硬性要求。Swarm 节点之间需要开放的端口包括:2377(集群管理)、7946(节点间通信,TCP 和 UDP)、4789(VXLAN overlay 网络,UDP)。如果机器之间有防火墙,这三个端口必须放行,否则节点加不进来或者 overlay 网络不通。

注意:4789 端口是 UDP 的,很多防火墙默认只配 TCP 规则,这个坑我踩过,表现是节点能加入集群但跨节点容器互相 ping 不通。

主机名也要提前规划好,因为 Swarm 用主机名标识节点。我统一用node-01到node-05这种命名,方便在docker node ls里一眼看出是哪台。主机名改完记得改/etc/hosts,确保每台机器都能解析所有节点的主机名,这能避免很多莫名其妙的通信问题。

2.2 Docker 安装与系统参数调优

Docker 的安装本身不复杂,但有几个系统参数必须调,否则集群跑起来会出各种诡异问题。

首先是vm.max_map_count,默认值 65530 对于容器密集的场景偏低,调到 262144。然后是文件描述符限制,Docker daemon 和容器都需要大量的 fd,我在/etc/security/limits.conf里把 nofile 调到 65536。还有net.ipv4.ip_forward=1,这是容器网络转发的基础,必须开启。

# 系统参数调优 cat >> /etc/sysctl.conf <<EOF vm.max_map_count = 262144 net.ipv4.ip_forward = 1 net.bridge.bridge-nf-call-iptables = 1 EOF sysctl -p # 文件描述符限制 cat >> /etc/security/limits.conf <<EOF * soft nofile 65536 * hard nofile 65536 EOF

Docker 的安装我建议用官方仓库而不是系统自带的版本,系统自带的往往版本偏旧,一些新特性用不了。安装完成后,编辑/etc/docker/daemon.json,配置日志驱动和存储驱动。日志驱动我用的json-file并限制了单个日志文件大小和数量,不然容器跑久了日志能把磁盘撑爆。

{ "log-driver": "json-file", "log-opts": { "max-size": "50m", "max-file": "3" }, "storage-driver": "overlay2", "live-restore": true }

live-restore这个参数值得说一下。开启后,Docker daemon 重启时容器不会跟着停,这对于需要升级 Docker 版本的场景非常有用,能避免升级过程中的服务中断。

2.3 初始化集群的正确姿势

集群初始化在第一个 Manager 节点上执行。这里有个关键参数--advertise-addr,必须指定为其他节点能访问到的 IP,不能是 127.0.0.1,否则其他节点加不进来。

docker swarm init --advertise-addr 10.0.1.11 --default-addr-pool 10.20.0.0/16

--default-addr-pool指定了 overlay 网络的地址池,默认是 10.0.0.0/8,这个范围可能和你的内网网段冲突。我就遇到过内网用了 10.0.x.x 网段,结果 overlay 网络和物理网络打架,容器跨节点通信直接失败。所以提前规划一个不冲突的地址池很重要,我用的 10.20.0.0/16。

初始化完成后,会输出加入集群的命令,包含 token。Manager 的加入 token 和 Worker 的加入 token 不一样,别搞混了。token 可以用docker swarm join-token manager和docker swarm join-token worker随时查看。

在另外两台 Manager 上执行加入命令,注意要加--advertise-addr指定自己的 IP。三个 Manager 都加入后,用docker node ls应该能看到三个节点都是 Ready 状态,其中一个 Leader,两个 Reachable。

Worker 节点加入就简单了,用 worker token 执行 join 命令即可。全部加入后,我给 Manager 节点打上 drain 标签:

docker node update --availability drain node-01 docker node update --availability drain node-02 docker node update --availability drain node-03

这样业务容器就只会调度到 Worker 节点上了。

3. 核心服务的编排与部署实操

3.1 用 Stack 文件定义整个应用

Swarm 部署服务有两种方式:docker service create一条条命令敲,或者用docker stack deploy配合 compose 文件。生产环境我强烈建议用后者,因为整个应用的状态都写在一个文件里,可以版本控制,可以 review,可以一键重建。

我用的 compose 文件版本是 3.8,这是目前 Swarm 模式支持最完整的版本。整个文件定义了 Web 服务、缓存服务、网络和配置。下面我拆开讲每个部分的设计考量。

version: "3.8" services: web: image: registry.internal/app:1.0.0 ports: - target: 8080 published: 80 protocol: tcp mode: ingress deploy: replicas: 4 update_config: parallelism: 1 delay: 10s order: start-first failure_action: rollback rollback_config: parallelism: 1 order: stop-first restart_policy: condition: on-failure delay: 5s max_attempts: 3 window: 120s placement: constraints: - node.role == worker preferences: - spread: node.id resources: limits: cpus: "1.0" memory: 512M reservations: cpus: "0.25" memory: 128M healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/health"] interval: 15s timeout: 5s retries: 3 start_period: 30s networks: - app-net environment: - REDIS_HOST=cache - LOG_LEVEL=info

3.2 副本数与调度策略的计算

replicas: 4这个数字不是拍脑袋定的。我有 2 个 Worker 节点,每个节点上跑 2 个 Web 容器。为什么不是 3 或 5?因为 Swarm 的spread调度策略会尽量把副本均匀分布到各节点,4 个副本在 2 个节点上正好每个 2 个。如果设成 3,分布就是 2+1,那个跑 1 个的节点资源利用率低,而且一旦跑 2 个的节点挂了,剩下 1 个节点要扛 3 个副本,压力不均。

副本数的下限是 2,因为 1 个副本没有高可用可言。上限取决于节点资源,我每个容器限制 1 核 512M,Worker 是 4C8G,理论上每个节点能跑 8 个,但还要留资源给系统和其他服务,所以 2 个是稳妥的。

placement里的constraints确保容器只调度到 Worker 节点,preferences里的spread: node.id让 Swarm 尽量均匀分布。这两个配合使用,既限定了范围又保证了均衡。

3.3 滚动更新的参数怎么调

update_config是滚动更新的核心配置,每个参数都影响更新时的服务可用性。

parallelism: 1表示每次只更新 1 个副本。为什么不一次更新多个?因为如果新版本有 bug,一次更新多个会导致大面积故障。一次一个,出问题影响面最小。

delay: 10s是更新完一个副本后等 10 秒再更新下一个。这 10 秒是给新容器启动和健康检查用的。如果健康检查的start_period是 30 秒,那 delay 至少要大于这个值,否则新容器还没通过健康检查,下一个更新就开始了,可能导致所有旧容器都被替换掉而新容器还没就绪。

order: start-first是关键。默认是stop-first,意思是先停旧容器再起新容器,这中间有一个副本不可用。改成start-first后,先起新容器,等它健康了再停旧容器,实现零中断。代价是需要额外的资源来同时运行新旧容器。

failure_action: rollback表示更新失败自动回滚。配合rollback_config使用,回滚时用stop-first因为要尽快恢复到已知good状态。

3.4 健康检查的设计细节

健康检查看起来简单,但设计不好会引发连锁问题。我的检查是curl -f http://localhost:8080/health,这个/health端点需要应用自己实现,返回 200 表示健康。

interval: 15s是检查间隔,timeout: 5s是单次检查超时,retries: 3是连续失败 3 次才判定不健康。这意味着从容器出问题到被判定不健康,最长需要 153 + 53 = 60 秒。这个时间窗口内,负载均衡可能还在往这个容器转发流量,所以应用本身要做好优雅关闭。

start_period: 30s是启动宽限期,这期间健康检查失败不计入 retries。对于启动慢的应用,这个值要调大,否则容器还没启动完就被判定不健康然后被杀掉,陷入重启循环。

实操心得:健康检查端点不要检查太多依赖。我见过有人把数据库连接也放进健康检查,结果数据库抖动一下,所有 Web 容器全被判定不健康,整个服务雪崩。健康检查只检查本进程能否正常响应即可,依赖问题让应用自己处理。

3.5 Overlay 网络与入口流量

网络部分我定义了一个 overlay 网络app-net,Web 和缓存服务都接在这个网络上,它们之间可以用服务名互相访问。Swarm 内置了 DNS 解析,cache这个服务名会自动解析到缓存容器的 IP。

入口流量走的是ingress模式的端口发布。published: 80表示所有 Swarm 节点都监听 80 端口,流量从任意节点进入后,通过 Routing Mesh 转发到实际运行容器的节点。这就是前面说的入口高可用。

但这里有个性能问题:Routing Mesh 的转发会经过一层 IPVS,有一定的性能损耗。对于高并发场景,可以用host模式发布端口,这样端口只在实际运行容器的节点上监听,流量不经过额外的转发。代价是负载均衡器需要知道哪些节点上有容器,配置会复杂一些。我的场景并发不高,用 ingress 模式足够了。

负载均衡器我用的是独立的一台机器跑反向代理,后端指向 3 个 Manager 节点的 80 端口。为什么指向 Manager 而不是 Worker?因为 Routing Mesh 是所有节点都参与的,Manager 也能转发流量。而且 Manager 通常负载低,转发性能更稳定。

4. 高可用验证与故障演练

4.1 容器故障自愈验证

集群搭好了不能只看docker service ls显示 4/4 就完事,得实际验证故障自愈能力。

我做的第一个测试是手动杀掉一个 Web 容器。在容器所在节点执行docker kill <container-id>,然后立刻用watch docker service ps web观察。大概 3 到 5 秒后,Swarm 检测到副本数不足,开始在一个节点上拉起新容器。新容器启动到健康检查通过大约 20 秒,这期间服务副本数是 3,但因为有负载均衡,用户无感知。

这里有个细节:Swarm 默认的restart_policy是condition: any,意思是容器退出就重启。我改成了on-failure,因为如果是正常退出(exit code 0),说明是计划内的停止,不需要重启。配合max_attempts: 3和window: 120s,如果容器在 120 秒内连续失败 3 次,Swarm 就放弃重启,把它标记为 Failed。这能防止一个必然崩溃的容器无限重启消耗资源。

4.2 节点宕机演练

容器故障是小打小闹,节点宕机才是真正考验。我直接关掉了一台 Worker 节点(shutdown -h now)。

Swarm 的节点失联检测大约需要 30 到 60 秒(取决于心跳超时配置)。失联后,节点状态变成Down,上面的容器被标记为Shutdown,然后 Swarm 开始在健康节点上重新调度这些容器。因为我的副本数是 4,分布在 2 个节点上各 2 个,挂掉一个节点后,剩下 2 个副本,Swarm 会在健康节点上再拉起 2 个,恢复到 4 个。

整个过程从节点关机到副本数恢复,大约花了 90 秒。这 90 秒内服务是可用的,只是容量减半。如果流量大,可能会变慢,但不会中断。

注意:节点宕机后重新上线,上面的容器不会自动恢复,因为 Swarm 已经把副本调度到别处了。重新上线的节点是空的,需要等下次调度或者手动 rebalance。可以用docker service update --force web强制重新平衡。

4.3 滚动更新实战与回滚

更新服务用docker service update --image registry.internal/app:1.0.1 web,或者改 compose 文件后docker stack deploy。我更喜欢后者,因为文件是版本化的。

更新过程中用docker service ps web能看到新旧容器交替的过程。start-first策略下,你会看到新容器先变成 Running,然后旧容器才变成 Shutdown。整个过程服务副本数始终不低于 4。

如果新版本有问题,健康检查会失败,failure_action: rollback触发自动回滚。我故意部署了一个健康检查会失败的版本测试,观察到的行为是:新容器启动后健康检查连续失败 3 次,被判定不健康,Swarm 停止更新并开始回滚,把旧版本容器重新拉起来。整个过程大约 2 分钟,服务始终可用。

手动回滚用docker service rollback web,它会回到上一个版本。但注意,Swarm 只保留最近一次的历史版本,再往前就回不去了。所以重要的版本变更前,最好在镜像仓库里保留旧版本镜像。

4.4 常见问题速查表

下面这张表是我在实际运维中整理的问题排查速查表,覆盖了大部分会遇到的坑。

现象可能原因排查命令解决方法
节点加入失败2377 端口不通telnet manager-ip 2377检查防火墙规则
跨节点容器不通4789 UDP 未放行docker network inspect app-net放行 VXLAN 端口
服务副本数上不去资源不足或约束不满足docker service ps web查看 Pending 原因
更新卡住健康检查一直失败docker service logs web检查应用日志和健康端点
入口 502容器未就绪或端口不对curl node-ip:80检查 published 端口和容器端口
节点状态 Down节点失联或 daemon 挂了docker node ls检查节点网络和 Docker 服务
overlay 网络冲突地址池与内网重叠docker network inspect重建集群指定新地址池

这张表里的每一条我都是实际遇到过的。特别是 overlay 网络冲突那条,当时排查了很久,因为现象是部分节点通信正常部分不正常,很迷惑。后来用docker network inspect看到 overlay 网段是 10.0.0.0/8,而内网正好有 10.0.x.x 的机器,路由冲突了。重建集群时指定--default-addr-pool 10.20.0.0/16后问题消失。

5. 生产环境才懂的运维经验

5.1 日志与监控的落地方式

Swarm 环境下看日志比单机麻烦,因为容器可能在任何节点上。docker service logs web能聚合所有副本的日志,但只保留最近的,而且容器重建后日志就没了。生产环境必须把日志收集到中心化存储。

我的做法是每个节点跑一个日志收集容器,挂载/var/lib/docker/containers目录,把容器日志文件采集走。这样不管容器怎么调度,日志都不会丢。应用日志统一输出到 stdout,由 Docker 的 json-file 驱动写到磁盘,再由采集器读取。

监控方面,Swarm 暴露了每个节点的 metrics 接口,但更实用的是监控 Service 级别的状态。我写了一个简单的脚本,定时docker service ls和docker node ls,把副本数、节点状态推送到监控系统。副本数不等于期望值就告警,节点状态不是 Ready 就告警。这两个指标能覆盖 90% 的异常情况。

5.2 资源限制与预留的平衡

resources里的limits和reservations是两个容易混淆的概念。limits是硬上限,容器用超了会被限制(CPU 被 throttle,内存超了被 OOM Kill)。reservations是调度依据,Swarm 调度时会确保节点有足够的预留资源。

我设的limits: cpus 1.0, memory 512M,reservations: cpus 0.25, memory 128M。这意味着调度时每个容器只占 0.25 核 128M 的额度,但运行时最多能用 1 核 512M。这样一台 4C8G 的 Worker 理论上能调度 16 个容器(按预留算),但实际运行 4 个就比较满了。

这个比例怎么定?我的经验是 reservations 设为 limits 的 25% 到 50%。太低会导致节点超卖严重,高峰期所有容器抢资源;太高则资源利用率低。对于 Web 服务这种有波峰波谷的,25% 到 30% 比较合适。

实操心得:内存的 limits 一定要设,而且要比应用实际用量高 20% 到 30%。我见过没设内存限制的容器,内存泄漏后把整个节点拖垮,其他容器跟着遭殃。设了限制后,最多是这个容器被杀,不影响别人。

5.3 配置与密钥的管理

应用配置和敏感信息不要硬编码在镜像里,也不要用环境变量明文写在 compose 文件里。Swarm 提供了 config 和 secret 两种对象。

config 用于非敏感配置,比如 nginx 配置文件、应用配置文件。secret 用于密码、密钥等敏感信息。它们都存储在 Swarm 的 Raft 日志里,secret 还会加密存储,并且只挂载到需要它的容器里,其他容器看不到。

echo "my-password" | docker secret create db_password - docker config create nginx_conf ./nginx.conf

在 compose 文件里引用:

services: web: secrets: - db_password configs: - source: nginx_conf target: /etc/nginx/nginx.conf secrets: db_password: external: true configs: nginx_conf: external: true

secret 挂载到容器内的/run/secrets/db_password,应用从这个文件读取。注意 secret 是挂载到内存文件系统的,不会写到磁盘,相对安全。

5.4 备份与灾难恢复

Swarm 集群的备份主要是备份 Raft 数据,它包含了整个集群的状态——服务定义、网络、配置、密钥。备份方法是在 Manager 节点上执行:

docker swarm ca --rotate # 这个不是备份,是轮换CA证书

真正的备份是停掉 Docker daemon 后打包/var/lib/docker/swarm目录。但生产环境不能随便停 daemon,所以更实际的做法是把 compose 文件、config 文件、secret 的创建脚本都纳入版本控制,灾难时用这些文件重建集群。Raft 数据备份作为最后手段,定期在维护窗口做。

我个人的做法是:所有编排文件放 Git 仓库,secret 的值放密码管理器,集群重建脚本化。这样即使整个集群没了,也能在半小时内从零重建。

5.5 版本升级的稳妥路径

Docker 版本升级在 Swarm 集群里要一个一个节点来,不能同时升。顺序是先升 Worker 再升 Manager,Manager 里先升非 Leader 再升 Leader。

升级前先docker node update --availability drain把节点上的容器迁走,等容器都调度到别处后再停 Docker 升级。升级完--availability active恢复。因为有live-restore,其实不 drain 也行,但 drain 更稳妥。

Manager 节点的升级要特别注意,Raft 集群在升级期间要保持多数派可用。3 个 Manager 的情况下,一次只能停 1 个,停 2 个就失去多数派,集群无法调度。所以升级 Manager 要一个一个来,等一个完全恢复再加入下一个。

6. 这套方案适合谁,不适合谁

6.1 什么场景下 Swarm 是甜点区

用了大半年下来,我觉得 Swarm 最适合这几类场景。

第一是中小规模的 Web 服务,副本数在 3 到 20 之间,节点数在 3 到 10 之间。这个规模下 Swarm 的简洁性优势明显,学习成本低,运维负担小。

第二是团队里没有专职容器平台工程师的情况。Swarm 的概念少,命令直观,后端开发自己就能改配置发版,不需要专门学一套复杂的体系。

第三是对稳定性要求高于对弹性要求的情况。Swarm 的调度策略相对保守,不会频繁迁移容器,适合那些启动慢、迁移成本高的应用。

6.2 什么时候该考虑更重的方案

如果出现下面这些信号,说明 Swarm 可能不够用了,该考虑更强大的编排系统。

需要精细的自动扩缩容,根据 CPU、内存、自定义指标自动调整副本数。Swarm 不支持自动扩缩容,只能手动改副本数或者写脚本。

需要复杂的发布策略,比如金丝雀发布、蓝绿发布、A/B 测试。Swarm 只有滚动更新,做不了流量切分。

需要多租户隔离,不同团队共享集群但资源要严格隔离。Swarm 的命名空间和权限控制比较弱。

需要丰富的生态集成,比如服务网格、Operator、CRD。这些是 K8s 的强项,Swarm 基本没有。

我的建议是:先用 Swarm,等它真的成为瓶颈了再迁移。不要为了"以后可能用到"而提前上复杂的方案,那只会增加当下的负担。迁移的成本没有想象中那么高,因为容器镜像、compose 文件这些资产是通用的,迁移主要是改编排层的定义。

6.3 我踩过的几个印象深刻的坑

最后分享几个具体的坑,都是文档里不会写但实际会遇到的。

第一个是时间同步。Swarm 的 Raft 协议对时间敏感,节点之间时间差太大可能导致选举异常。我遇到过一台机器 NTP 没配好,时间差了 5 分钟,结果它一直无法成为 Leader,集群偶尔抖动。所有节点必须配 NTP 同步。

第二个是磁盘空间。Docker 的镜像和日志很占空间,特别是频繁更新时旧镜像不会自动删除。我写了个定时任务清理 dangling 镜像和停止的容器,docker system prune要慎用,会删掉所有未使用的资源,包括你可能还需要的数据卷。

第三个是 DNS 解析。Swarm 内置的 DNS 在容器重启后 IP 会变,应用如果缓存了 IP 就会连不上。正确做法是每次连接都重新解析服务名,或者用连接池并设置合理的过期时间。这个坑在缓存服务上特别明显,Web 容器缓存了缓存容器的 IP,缓存容器一重启,Web 就连不上了。

第四个是健康检查的副作用。健康检查本身会消耗资源,如果检查太频繁或者检查逻辑太重,会给应用增加额外负担。我一开始把 interval 设成 5 秒,结果健康检查的请求占了总请求量的 10%。后来调到 15 秒就合理了。

这套集群到现在跑了快一年,经历过节点宕机、容器崩溃、版本回滚,服务可用性保持在 99.9% 以上。对于这个体量的项目来说,Swarm 交出了一份合格的答卷。如果你也在纠结选型,希望这篇实操记录能帮你少走点弯路。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询