# s3-perf **Repository Path**: fly_zero/s3-perf ## Basic Information - **Project Name**: s3-perf - **Description**: 对象存储性能测试工具 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-16 - **Last Updated**: 2026-09-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # s3-perf 一个基于 C、libcurl 和 OpenSSL 的 S3 PUT 压测工具。它使用多个工作线程和 libcurl multi 接口持续发送并发上传请求,并按 AWS S3 V1 规则生成 `AWS :` 认证签名。 ## 功能 - 多线程、多连接并发发送 HTTP PUT 请求。 - 每次启动时从 `/dev/random` 读取一份固定大小的随机数据,所有上传请求复用这份数据。 - 使用路径风格 URL:`//s3-perf-<启动时间>-<序号>`。 - 为每个请求生成 `Date` 和 AWS S3 V1 `Authorization` 请求头。 - 显式设置上传长度,使用 `Content-Length`,并关闭 `Expect: 100-continue`。 - 实时显示 QPS、带宽、成功数和失败数,并在退出时输出汇总。 - 收到 `SIGINT` 或 `SIGTERM` 后停止创建新请求,回收在途请求并正常退出。 当前实现使用 HTTP URL,暂未提供 TLS、HTTPS、命令行选项或配置文件支持。 ## 依赖 构建环境需要: - C 编译器 - CMake 3.10 或更高版本 - libcurl 开发文件(**7.28.0 或更高版本**;目前在 7.61.1 和 8.18 上验证) - OpenSSL 开发文件 - pthread(通常由系统 C 工具链提供) 在 Debian 或 Ubuntu 上可以安装: ```bash sudo apt install build-essential cmake libcurl4-openssl-dev libssl-dev ``` ## 编译 在项目根目录执行: ```bash cmake -S . -B build cmake --build build ``` 编译完成后,可执行文件位于 `build/s3-perf`。 ## 使用方法 ```text ./build/s3-perf ``` 参数说明: | 参数 | 说明 | | --- | --- | | `host` | 目标主机和端口,例如 `127.0.0.1:9000` | | `bucket` | S3 bucket 名称 | | `ak` | Access Key | | `sk` | Secret Key,用于生成 HMAC-SHA1 签名 | | `thread_count` | 工作线程数,必须大于 0;最大值会限制为在线 CPU 核数的两倍 | | `concurrency_count` | 每个线程的并发请求数,必须大于 0 | | `file_size` | 每个 PUT 请求的上传字节数,必须大于 0 | 例如,向本地监听 `9000` 端口的 S3 兼容服务发送请求: ```bash ./build/s3-perf \ 127.0.0.1:9000 \ example-bucket \ AKIDEXAMPLE \ SECRETKEYEXAMPLE \ 2 \ 8 \ 1048576 ``` 上例会创建 2 个工作线程,每个线程维持最多 8 个并发请求,每个对象上传 1 MiB。 程序会持续运行,直到收到 `Ctrl-C`(`SIGINT`)或 `SIGTERM`。 ## 输出 运行期间每 200 ms 刷新一行实时统计: ```text qps 1579.7 | bw 12.34 MiB/s | ok 2280 (+15) | fail 0 (+0) | 1.0s ``` 退出时输出累计统计: ```text elapsed : 1.006 s requests ok : 2281 requests fail : 0 requests abort : 4 avg qps : 2267.40 avg bandwidth : 17.72 MiB/s total uploaded : 17.82 MiB ``` 统计口径如下: - 只有 curl 传输成功且 HTTP 状态码为 `2xx` 的请求计入 `requests ok`、QPS 和带宽。 - 传输错误或非 `2xx` 响应计入 `requests fail`。 - 收到退出信号时仍在途、随后被中止的请求计入 `requests abort`。 - `total uploaded` 按成功请求数乘以 `file_size` 计算。 ## 测试 测试使用 Python 标准库在本地随机端口启动 HTTP 抓包服务器,不需要真实的 S3 服务。 测试会在缺少或过期的 `build/s3-perf` 时自动执行 CMake 构建。 ```bash python3 -m unittest discover -s test -v ``` 也可以使用 pytest(如果环境中已安装): ```bash python3 -m pytest test/ -v ``` 测试覆盖: - PUT 请求方法、路径、Host、Content-Length 和请求体。 - `/dev/random` 只读取一次,以及各请求复用同一份上传数据。 - Date 格式、AWS S3 V1 Authorization 和 HMAC-SHA1 签名。 - QPS、带宽、成功/失败/中断统计。 - 失败响应下 stderr 不刷屏。 - SIGINT 和 SIGTERM 的优雅退出。 ## 项目结构 ```text main.c C 实现 CMakeLists.txt CMake 构建配置 test/s3_harness.py 本地抓包服务器和测试 harness test/s3_case.py 测试基类 test/test_s3_request.py test/test_s3_signature.py test/test_stats.py ``` ## 注意事项 - 等待 socket 事件统一使用 `curl_multi_wait()`(libcurl 7.28.0 起提供),而不是需要 7.66.0 以上的 `curl_multi_poll()`。`curl_multi_wait()` 在没有可等待的 fd 时会立即 返回——7.66.0 之前的 libcurl 在多线程解析域名期间不提供任何 fd,裸调用会忙等烧满 CPU——所以程序用单调时钟补睡到「调用方 timeout 与 `curl_multi_timeout()` 中的较早 者」,与 `curl_multi_poll()` 的语义保持一致,同时不会延迟 `SIGINT`/`SIGTERM` 的响应。 - `sk` 会作为命令行参数传入进程,请注意 shell 历史记录和进程列表中的凭据暴露风险。 - `/dev/random` 读取可能受系统熵池状态影响;大文件会占用对应大小的内存。 - `thread_count * concurrency_count` 决定理论上的总并发规模,请根据目标服务和本机资源谨慎设置。 - 程序面向 S3 兼容服务的基础 PUT 压测,不实现对象重试、鉴权配置管理或结果持久化。