如何在Spring应用中查询Amazon S3存储桶的总容量和剩余可用容量
Spring 应用查询 S3 存储桶容量实现方案
注意:Amazon S3 默认没有存储桶容量上限,你提到的「总容量」通常指你主动为存储桶配置的存储配额。如果未配置配额,存储桶总容量无上限,剩余容量也同样为无上限。
步骤1:引入依赖
推荐使用 AWS SDK for Java v2 配合 Spring Cloud AWS 简化配置,Maven 依赖示例如下:
<!-- AWS S3 核心依赖 --> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>s3</artifactId> <version>2.20.150</version> </dependency> <!-- AWS CloudWatch 依赖,用于高效查询存储用量 --> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>cloudwatch</artifactId> <version>2.20.150</version> </dependency> <!-- Spring Cloud AWS starter,自动初始化S3、CloudWatch客户端 --> <dependency> <groupId>io.awspring.cloud</groupId> <artifactId>spring-cloud-aws-starter-s3</artifactId> <version>3.1.0</version> </dependency>
步骤2:配置AWS凭证与区域
在 application.yml 中添加配置,对应账号需要具备 s3:GetBucketQuota、cloudwatch:GetMetricStatistics 权限:
spring: cloud: aws: credentials: access-key: 你的AWS访问密钥ID secret-key: 你的AWS秘密访问密钥 region: static: 存储桶所在区域,例如cn-north-1
生产环境不建议硬编码凭证,推荐使用IAM角色、环境变量或者密钥管理服务存储敏感信息。
步骤3:核心业务代码实现
推荐通过 CloudWatch 指标查询存储桶已用容量,避免遍历全桶对象导致的性能损耗,代码示例如下:
import org.springframework.stereotype.Service; import software.amazon.awssdk.services.cloudwatch.CloudWatchClient; import software.amazon.awssdk.services.cloudwatch.model.*; import software.amazon.awssdk.services.s3.S3Client; import software.amazon.awssdk.services.s3.model.GetBucketQuotaRequest; import java.time.Instant; import java.util.Comparator; import java.util.List; @Service public class S3StorageService { private final S3Client s3Client; private final CloudWatchClient cloudWatchClient; public S3StorageService(S3Client s3Client, CloudWatchClient cloudWatchClient) { this.s3Client = s3Client; this.cloudWatchClient = cloudWatchClient; } /** * 查询存储桶已用容量,单位为字节 * @param bucketName 存储桶名称 * @param storageType 存储类型,标准存储传 StandardStorage,其他类型按需修改 */ public Long getUsedStorage(String bucketName, String storageType) { Instant end = Instant.now(); Instant start = end.minusDays(1); // S3存储用量指标每日更新一次,取最近24小时的统计值 GetMetricStatisticsRequest request = GetMetricStatisticsRequest.builder() .namespace("AWS/S3") .metricName("BucketSizeBytes") .dimensions( Dimension.builder().name("BucketName").value(bucketName).build(), Dimension.builder().name("StorageType").value(storageType).build() ) .startTime(start) .endTime(end) .period(86400) .statistics(Statistic.AVERAGE) .build(); List<Datapoint> datapoints = cloudWatchClient.getMetricStatistics(request).datapoints(); if (datapoints.isEmpty()) { return 0L; } // 取最新的统计数据 datapoints.sort(Comparator.comparing(Datapoint::timestamp).reversed()); return datapoints.get(0).average().longValue(); } /** * 查询存储桶配置的总配额,单位为字节,未配置配额返回null代表无上限 */ public Long getTotalQuota(String bucketName) { try { return s3Client.getBucketQuota(GetBucketQuotaRequest.builder().bucket(bucketName).build()) .quota() .limit() * 1024 * 1024 * 1024; // 接口返回单位为GB,转换为字节 } catch (Exception e) { // 未配置配额时接口会抛出异常,返回null代表无上限 return null; } } /** * 查询剩余可用容量,单位为字节,无上限时返回null */ public Long getRemainingStorage(String bucketName, String storageType) { Long totalQuota = getTotalQuota(bucketName); if (totalQuota == null) { return null; } Long used = getUsedStorage(bucketName, storageType); return totalQuota - used; } }
注意事项
- S3 的存储用量指标为日级统计,不是实时数据,如果需要近实时统计,可以用分页遍历全桶对象累加大小的方式,仅适合小容量、对象数量少的存储桶使用
- 如果存储桶存在多种存储类型,需要分别查询对应类型的用量再累加
- 以上代码默认返回单位为字节,可按需转换为MB、GB等单位展示
内容的提问来源于stack exchange,提问作者NVJ
相关产品推荐
相关产品推荐

