LocalStack 从今年 3 月下旬开始要求账号加令牌才能启动容器,本地跑 AWS 联调这件事多了登录环节。一个叫 fakecloud 的开源项目在这个背景下出现:Rust 编写的本地 AWS 模拟器,单二进制文件,不需要账号,不需要令牌,把 AWS SDK 指向 http://localhost:4566 就能用。本文基于 v0.46.0 在 macOS (Apple Silicon) 上做了完整实测,覆盖存储、队列、数据库、Cognito、SES、Lambda 执行和跨服务联动。

LocalStack 发生了什么
LocalStack 长期是本地 AWS 开发测试的事实标准:容器里跑一个假的 AWS,S3、SQS、Lambda 都能模拟,CI 里不用碰真云。官方博客在 2026 年 3 月 23 日切换到单一镜像模式:localstack/localstack:latest 要求账号加 auth token 才能启动,原本社区版免费的一些服务(Cognito、SES v2、RDS、ElastiCache、API Gateway v2、ECS/ECR)划入付费的 Pro 层。官方定价页的原话是 Community Emulator 属于开源项目但需要注册账号,Pro Emulator 闭源、需要付费许可证。
对个人开发者来说,注册个账号不算大事。对 CI 流水线来说,这意味着每个跑集成测试的环境都要配令牌、消耗配额。Reddit 的 r/devops 板块当时有一轮集中讨论,主题就是 CI 环境的令牌管理和额度消耗。
fakecloud 不是 LocalStack 的分支。它是同一需求的重新实现:作者是旧金山开发者 Lucas Vieira(faisca.dev),仓库 2026 年 4 月创建,AGPL-3.0 许可,目前 598 stars、47 forks,发版到 v0.46.0。

实测:装一个,跑一遍
本机是 Mac mini M4,Homebrew 安装(brew install fakecloud),拉下来的二进制 187 MB(未 strip 的 Rust 产物,GitHub release 页的压缩包在 62-69 MB 之间),fakecloud --version 报 0.46.0。启动到健康检查通过实测 1.36 秒,稳定后驻留内存 27.7 MB,/_fakecloud/health 报告注册了 105 个服务。
不需要 Docker。这一点和 LocalStack 的容器方案是两条路线:fakecloud 自己就是服务器,AWS SDK 指过去就结束。
用 boto3(Python 的 AWS SDK)跑了一轮常规操作:
- S3:建桶、写对象、读回,内容原样返回
- SQS:建队列、发消息、收消息,消息体完整
- DynamoDB:建表(PAY_PER_REQUEST 模式)、put_item、get_item,属性类型(S/N)正确还原
- IAM:create_user 成功,返回标准 ARN(
arn:aws:iam::123456789012:user/blogdemo) - STS:get_caller_identity 返回模拟账号 123456789012
单次操作的延迟在 1-4 毫秒:建桶 4ms,1KB put_object 2ms,get_object 1ms,SQS 发送/接收各 1ms。对比真实 AWS 的几十毫秒网络往返,本地回环的速度对测试套件是数量级的差异。
两个 LocalStack 已划入付费的服务实测可用:
- Cognito User Pools:
create_user_pool直接成功,返回真实格式的池 ID(us-east-1_xxxxxxxx) - SES v2:
create_email_identity、send_email都能跑,发出去的邮件落在/_fakecloud/ses/emails检查点里,发件人、收件人、主题、正文逐字段可查
第二点值多说一句。真实 AWS 里你没法在测试里"读到刚发出去的邮件",通常要配一个收件 S3 桶或者开 SES sandbox 折腾一圈。fakecloud 把每封模拟发送的邮件存成结构化记录,测试代码直接断言字段,这是它作为测试工具而非单纯模拟器的定位差异。
Lambda 是真的在执行
Lambda 的处理方式和大多数模拟器不同:fakecloud 把函数代码丢进真实的 Docker 容器执行,官方文档列了 23 个运行时。实测建了一个 Python 3.12 函数,处理程序返回 {"statusCode": 200, "body": "hello {name}"},invoke 传入 {"name": "linlog"},返回 200 和 {"statusCode": 200, "body": "hello linlog"}。
真的执行意味着真的能踩坑:依赖打包问题、冷启动、超时,这些在纯内存模拟里永远测不出来,在 fakecloud 里会原样暴露。RDS 和 ElastiCache 走同样的路:Postgres、MySQL、MariaDB、Redis、Valkey 都是拉起真实容器,不是数据结构模拟。
跨服务联动是核心卖点
模拟单个服务的 API 响应不难,难的是服务之间的行为串联。实测了 EventBridge 到 SQS 的链路:建队列、建规则(事件模式 {"source": ["blog.demo"]})、把队列挂为目标,然后 put_events 发一条事件。三秒内 SQS 收到了完整的事件封装:version、id、source、detail-type、detail、region 一个不缺。
官方文档列了 15 组以上这类集成:EventBridge 到 Step Functions、S3 事件触发 Lambda、SES 入站邮件进 S3/SNS/Lambda、EventBridge Pipes 的过滤加转换。对做事件驱动架构的团队,这类链路恰恰是集成测试里最容易在生产前漏掉的部分。
状态管理也按测试场景设计了。POST /_fakecloud/reset/{service} 单独重置一个服务,实测重置 SQS 后队列消失,S3 里的对象原样保留,服务之间隔离干净。Cognito 的检查点能列出待确认的注册码、活跃的 access token,甚至能强制过期 token 模拟登录失效。
一致性是怎么验证的
"模拟器靠不靠谱"的核心疑问是:你怎么知道它的行为和真 AWS 一致?fakecloud 的答案是一套四层验证,其中最硬的一层用 AWS 自己的接口模型做基准。
AWS 用 Smithy 定义所有服务的 API 契约(请求字段、类型、约束、错误码),这些模型文件是公开的。fakecloud 把模型提交进仓库,自动生成测试变体,覆盖每个操作的每个字段、每个约束:边界值、枚举全量遍历、可选字段的所有组合、属性化随机生成、官方示例、每个约束的反例。官方数字是 248,557 个生成变体在每次提交时全部通过。
另外三层:端到端测试用真实 AWS SDK 跑跨服务流程;对齐测试(parity)把同一套测试体分别跑在 fakecloud 和一个真实 AWS 沙箱账号上,对比通过与否的差异,捕捉"形状对但语义假"的漂移;Terraform 验收测试直接跑 HashiCorp 官方 terraform-provider-aws 的 TestAcc 用例,完整的 apply/plan/destroy 循环,这套用例是第三方写的,针对真 AWS 的行为,fakecloud 只是拿来自证。

对比表的几个关键行:许可证 AGPL-3.0 对专有;账号令牌不要求对强制;启动约 300 毫秒对约 3 秒;空闲内存约 10 MiB 对约 150 MiB。官方对比页描述的差异更本质:LocalStack 走广度优先,服务目录大但深度不一;fakecloud 走深度优先,服务少一些但行为一致性和跨服务集成做到全量。迁移路径官方给的是一行改动:docker-compose 里镜像名从 localstack/localstack 换成 ghcr.io/faiscadev/fakecloud,端点 URL 和凭证配置都不用动。
还有一处口径问题要说明:仓库自述写 105 个服务,官网对比页写 46 个服务达到"真 100% 一致性"。两者并不矛盾,105 是实现了的操作面,46 是通过了全部一致性变体的子集,但文档之间没有把口径统一说清,使用时按需对号。
测试断言 SDK:和其他模拟器最大的不同
fakecloud 自带六种语言的断言 SDK(TypeScript、Python、Go、PHP、Java、Rust),解决的问题用一段 TypeScript 就能说清:
import { FakeCloud } from "fakecloud";
const fc = new FakeCloud();
// 被测代码用正常 AWS SDK 发邮件
// 测试直接断言副作用
const { emails } = await fc.ses.getEmails();
expect(emails).toHaveLength(1);
await fc.reset();传统做法是 mock AWS SDK 层,问题在于 mock 断言的是"你的代码调了什么方法",而不是"系统真的发生了什么"。断言 SDK 从模拟器一侧读真实副作用:邮件发出去了没有、SNS 消息内容对不对、Lambda 被触发了几次。集成测试的可信度建立在前者上还是后者上,是两种测试哲学的分界。
代价与风险
AGPL-3.0 对使用者基本无感(模拟器不进你的分发物),但对其商业模式是个问号:项目没有付费层,README 里留着 ADOPTERS.md 的征集。这类"开源替代"项目的历史轨迹两种都有:要么长成社区标准,要么维护者热情耗尽后归档。HN 讨论里也有人把 LocalStack 的转轨归为"产品与功能"的老故事:开源时期积累的用户基础,商业化时发现核心用户愿意付费。
安全层面默认是宽松模式:SigV4 签名只解析不校验,IAM 策略只存储不评估,测试环境零配置就能跑。要更接近生产行为,有 --verify-sigv4 和 --iam soft|strict 可开。对把模拟器端口暴露到非本机网络的场景,这些开关值得打开。
安装方式里有 curl | bash 一键脚本,HN 评论区对此有争议(在终端直接执行远程脚本的风险),社区也质疑过作者透明度;可核实的部分是 Lucas Vieira 在 LinkedIn 有真实履历,faisca.dev 下还有其他项目,且 Homebrew、Cargo、Docker 等常规安装渠道都可用,不必用脚本。同赛道的替代品还有 Floci(多云方向)、MiniStack 和 localemu(LocalStack 分支),这个赛道在 LocalStack 转轨后进入了好几个玩家并行的阶段。
什么场景值得用
判断条件就一条:你的测试需不需要"下游真的发生"。如果只是让调用不报错,LocalStack Pro 或任何 mock 方案都够;如果需要 Lambda 真执行、RDS 真写库、事件真的流到队列,fakecloud 目前是免费方案里覆盖最完整的一个。
对用 Claude Code、Cursor 这类 AI 编码工具的团队,README 给了 CLAUDE.md / .cursor/rules 的接入片段,AI 生成的集成测试代码可以直接指向本地 4566 端口跑通再提交。这个用法和上一段说的"下游真的发生"是同一件事:AI 批量生成的测试代码,恰恰最需要在真实行为上验证。
说明
- 实测环境:Mac mini M4 / macOS 27.0 / fakecloud v0.46.0 / boto3 1.43.103 / Docker Desktop(Lambda 执行用)
- fakecloud 数据(服务数、一致性变体、性能数字)来自官方文档与仓库 README;带"实测"字样的数字为本文作者本机测得,不同环境会有差异
- 项目地址:github.com/faiscadev/fakecloud,文档:fakecloud.dev