10分钟用Floci搭建零成本本地AWS开发环境

45 次阅读 0 点赞 0 评论 14 分钟原创技术教程

告别付费测试与Mock Bean!本文手把手教你用开源工具Floci在本地一键跑起完整AWS模拟器。学完后你能独立配置SDK指向本地端点,完成S3+DynamoDB+SQS的集成调试,断网开发、CI验证效率翻倍。

#本地开发环境 #AWS模拟器 #Docker #Java #Spring Boot #微服务 #DevOps
10分钟用Floci搭建零成本本地AWS开发环境

还在为本地测试 AWS 服务掏钱?教你免费搭建全量本地云环境

写业务代码时,你一定碰到过这种场景:

团队微服务依赖 S3 存文件、DynamoDB 记状态、SQS 削峰,但开发阶段总得连真实的 AWS 账号——不仅费钱,断网调试、CI 流水线跑起来都麻烦。有人用 Mock Bean 糊过去,但 mock 和真实行为总有差异,上了生产才发现问题。

今天我来教你用一个叫 Floci 的开源工具,在本地一键跑起完整的 AWS 模拟器。不需要 AWS 账号,不需要 Token,不需要付费,只要你有 Docker。整个环境占内存不到 20MB,启动只要几十毫秒。跟着这篇走一遍,你就能把 S3、DynamoDB、SQS 等数十个服务搬到 localhost:4566,开发测试效率直接翻倍。


前置条件

  • Docker(推荐 Docker Compose V2):Floci 本身就是容器化运行,Docker 是硬性要求
  • JDK 17+:本文 Java 示例基于 AWS SDK v2
  • AWS CLI(可选):方便快速验证服务连通性
  • 基础认知:了解 AWS SDK 的基本使用即可

为什么强调 Docker? 因为 Floci 的 Lambda、RDS、ECS 等服务直接跑真实的 Docker 容器,而不是浅层 mock,保证了和本地真实 AWS 服务的高度一致性。这也是它比早年各种 Mock Bean 方案靠谱的核心原因。


第一步:启动 Floci

最推荐的方式是 Docker Compose,配置清晰、容易管理。在你项目根目录创建 compose.yaml:

yaml 复制代码
services:
  floci:
    image: floci/floci:latest
    ports:
      - "4566:4566"
    environment:
      - FLOCI_STORAGE_MODE=hybrid   # 重启不丢数据,推荐开发用

这里 FLOCI_STORAGE_MODE=hybrid 的意思是:数据主要驻留内存以保证读写速度,同时每 5 秒异步刷盘。这样即使容器重启,你的 Bucket 和表还在,不用每次重新建。如果你跑的是 CI 流水线,改成 memory 即可。

启动:

bash 复制代码
docker compose up -d

等几秒后,Floci 会在后台监听 localhost:4566。你可以先验证一下:

bash 复制代码
curl http://localhost:4566/_floci/ui

返回非空说明服务已就绪。如果浏览器访问 http://localhost:4566/_floci/ui,还能看到 Floci 自带的 Web Console,可视化查看所有本地资源。

端口说明:4566 是 Floci 统一的入口端口,所有 AWS 服务的 API 请求都走这里,由 Floci 内部路由分发到对应的服务处理器。这比早年每个服务占一个端口方便太多了。


第二步:配置 AWS 客户端指向本地

无论是 CLI、SDK 还是 Terraform,核心思路都一样:把 endpoint 指向本地,并提供一组合法的(但不需要真实的)凭证。

手动配置方式:

bash 复制代码
export AWS_ENDPOINT_URL=http://localhost:4566
export AWS_DEFAULT_REGION=us-east-1
export AWS_ACCESS_KEY_ID=test
export AWS_SECRET_ACCESS_KEY=test

为什么凭证可以随便填? 据 Floci README 与 多账号文档:默认不校验 SigV4 签名,Access Key / Secret 填任意非空值即可(例如 test/test);若要严格验签,可设环境变量 FLOCI_AUTH_VALIDATE_SIGNATURES=true。本地开发用默认即可。

配置完成后,用 CLI 创建一个 S3 Bucket 试试:

bash 复制代码
aws --endpoint-url http://localhost:4566 s3 mb s3://my-dev-bucket
aws --endpoint-url http://localhost:4566 s3 ls
## 输出应包含 my-dev-bucket

能正常输出,说明你的本地环境已经通畅。


第三步:Java SDK 实战演练

光跑 CLI 不过瘾,下面用一个完整的 Java 示例,同时操作 S3、DynamoDB、SQS,模拟一个「用户上传图片 → 生成缩略图任务入队 → 任务状态入库」的流程。

最关键的点:Java SDK 要同时满足 endpointOverride 和 credentials。很多新手踩坑就在这里——忘了覆盖 endpoint 导致 SDK 还是去请求真正的 AWS。

java 复制代码
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.sqs.SqsClient;
import software.amazon.awssdk.services.dynamodb.model.*;
import software.amazon.awssdk.services.sqs.model.*;

import java.net.URI;
import java.util.Map;

public class FlociDemo {

    private static final String ENDPOINT = "http://localhost:4566";
    private static final String REGION = "us-east-1";
    private static final StaticCredentialsProvider CRED =
        StaticCredentialsProvider.create(
            AwsBasicCredentials.create("test", "test"));

    public static void main(String[] args) {
        // 1. 创建 DynamoDB 客户端并建表(状态表)
        var dynamo = DynamoDbClient.builder()
            .endpointOverride(URI.create(ENDPOINT))
            .region(Region.of(REGION))
            .credentialsProvider(CRED)
            .build();

        dynamo.createTable(CreateTableRequest.builder()
            .tableName("thumbnail-tasks")
            .billingMode(BillingMode.PAY_PER_REQUEST)
            .attributeDefinitions(
                AttributeDefinition.builder()
                    .attributeName("taskId").attributeType(ScalarAttributeType.S).build())
            .keySchema(
                KeySchemaElement.builder()
                    .attributeName("taskId").keyType(KeyType.HASH).build())
            .build());

        // 2. 创建 SQS 队列(任务队列)
        var sqs = SqsClient.builder()
            .endpointOverride(URI.create(ENDPOINT))
            .region(Region.of(REGION))
            .credentialsProvider(CRED)
            .build();

        var queueUrl = sqs.createQueue(
            CreateQueueRequest.builder().queueName("thumbnail-jobs").build() ).queueUrl();

        // 3. 模拟:上传文件描述 + 任务入队 + 状态落库
        String taskId = "task-001";
        String fileName = "photo.jpg";

        sqs.sendMessage(SendMessageRequest.builder()
            .queueUrl(queueUrl)
            .messageBody(fileName).build());

        dynamo.putItem(PutItemRequest.builder()
            .tableName("thumbnail-tasks")
            .item(Map.of("taskId", AttributeValue.builder().s(taskId).build(),
                         "status", AttributeValue.builder().s("PENDING").build(),
                         "file",   AttributeValue.builder().s(fileName).build()))
            .build());

        // 4. 验证:查表和消息
        var scanResult = dynamo.scan(ScanRequest.builder().tableName("thumbnail-tasks").build());
        System.out.println("[DynamoDB] 记录数: " + scanResult.count());

        var msgResult = sqs.receiveMessage(ReceiveMessageRequest.builder()
            .queueUrl(queueUrl).maxNumberOfMessages(1).build());
        msgResult.messages().forEach(m -> System.out.println("[SQS] 收到消息: " + m.body()));

        System.out.println("[OK] Floci 本地环境验证完成");
    }
}

POM 中需要引入 software.amazon.awssdk:aws-sdk-java-bom 管理版本。代码里的 endpointOverride(...) 是所有 SDK 客户端共用的关键步骤,不能漏。Floci 完全兼容 AWS SDK v2 的调用协议,你的线上代码改个 endpoint 就能直接跑本地。


常见问题与踩坑提醒

1. 启动报端口占用

4566 是 Floci 默认端口。如果你之前跑过 LocalStack,很可能它还在占着这个端口。docker ps 检查一下,停掉旧容器即可。Floci 设计为 LocalStack 的平滑替代品,镜像名直接换过来就能用。

2. 多项目并行时资源隔离

如果你的本地 Floci 环境同时跑多个项目,可以用多账号隔离能力。当 AWS_ACCESS_KEY_ID 是 12 位纯数字时(如 111111111111),Floci 会把它当做独立账号 ID,不同账号的资源完全隔离。项目 A 用 111111111111、项目 B 用 222222222222 即可互不干扰。

3. Spring Boot 集成测试

推荐使用 Testcontainers 官方模块 io.floci:testcontainers-floci(Testcontainers 1.x 用 1.14.0,2.x / Spring Boot 4.x 用 2.15.0),可以自动在测试方法级别拉起隔离的 Floci 实例,避免共享状态和端口冲突:

java 复制代码
@Testcontainers
class S3IntegrationTest {
    @Container static FlociContainer floci = new FlociContainer();
    // floci.getEndpoint() / floci.getRegion() / floci.getAccessKey()... 直接取用
}

总结

这篇带你走完了从零搭建本地 AWS 开发环境的完整流程:

  1. Docker Compose 一键拉起 Floci,内存不到 20MB
  2. 手动导出环境变量,让 CLI/SDK 指向 localhost:4566
  3. Java SDK 示例演示 S3+DynamoDB+SQS 联动,核心只是加一个 endpointOverride
  4. 掌握了持久化模式选择、多账号隔离、Testcontainers 集成三大实用技巧

你可以拿这套环境做:断网调试、本地 CI 验证、学习 AWS 服务 API 行为。GitHub 上 floci-io/floci 已经有 2.7w Star,完全 MIT 开源,没有任何付费锁或 Token 门槛。

下一步建议:打开 http://localhost:4566/_floci/ui 把玩 Web Console,尝试用 Terraform 本地编排资源,或者把你的 Spring Boot 集成测试从 Mock 全部换成 Testcontainers + Floci,感受真实 API 带来的测试信心提升。如果你有本地开发 AWS 应用的经验想分享,欢迎一起交流。

最后更新:2026-10-25T10:02:21

评论 (0)

发表评论

blog.comments.form.loading
0/500

暂无评论,快来发表第一条评论吧!