You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java 21+Spring Boot 3环境下AWS Lambda重复创建S3Client引发IdentityProperty重复冲突的解决方法咨询

Java 21+Spring Boot 3环境下AWS Lambda重复创建S3Client引发IdentityProperty重复冲突的解决方法咨询

我最近在Java 21 + Spring Boot 3的环境下开发AWS Lambda,遇到了一个和S3 Client相关的诡异问题,想请教各位大佬怎么解决。

先介绍下我的配置:我的Lambda需要用到S3客户端,所以写了这样一个配置类:

@Configuration
public class AwsConfig {
    @Bean
    public S3Client awsS3Client() {
        return S3Client.builder()
                .region(Region.US_WEST_2)
                .build();
    }
}

问题表现

当我连续多次触发这个Lambda的时候,AWS环境似乎会在之前的S3Client实例被垃圾回收前就创建新的实例,直接抛出了如下错误:

No duplicate IdentityProperty names allowed but both IdentityProperties 7890fbf9 and 25f0f461 have the same namespace (java.lang.String) and name (Bucket). IdentityProperty should be referenced from a shared static constant to protect against erroneous or unexpected collisions.

但奇怪的是,如果我间隔5-7分钟再去触发Lambda,一切又能正常运行,完全没问题!

调试后的根源分析

我跟进了AWS SDK的源码,发现这个错误来自IdentityProperty类。这个类里维护了一个静态的并发集合,用来记录已经注册过的属性:

private static final ConcurrentMap<Pair<String, String>, IdentityProperty<?>> NAME_HISTORY = new ConcurrentHashMap<>();

private void ensureUnique() {
    IdentityProperty<?> prev = NAME_HISTORY.putIfAbsent(Pair.of(namespace, name), this);
    Validate.isTrue(prev == null, "No duplicate IdentityProperty names allowed but both IdentityProperties %s and %s have the same "
            + "namespace (%s) and name (%s). IdentityProperty should be referenced from a shared static constant to "
            + "protect against erroneous or unexpected collisions.",
            Integer.toHexString(System.identityHashCode(prev)),
            Integer.toHexString(System.identityHashCode(this)),
            namespace, name);
}

问题出在这个NAME_HISTORY是静态变量,第一次Lambda调用后,这个集合并没有被清空。后续调用Lambda时,新创建的S3Client会尝试注册同一个"java.lang.String"/"Bucket"键,而集合里已经存在这个键了,所以触发了校验失败的错误。这个校验逻辑是被S3ExpressAuthSchemeProvider调用的,最终由DefaultS3ClientBuilder触发执行。

我已经尝试过的方案(均无效)

  • 将S3Client声明为类的静态成员变量
  • 给S3Client的Bean加上@Scope("prototype")(临时hack,但没解决问题)
  • 用反射强行清空NAME_HISTORY集合,结果又出现了其他属性的重复冲突错误
  • 调整各种Bean的生命周期和实例化策略,比如尝试用@Lazy等,都没效果

想请教大家,有没有什么靠谱的方法能解决这个问题?怎么才能让Lambda连续多次调用时,不会触发这个IdentityProperty的重复冲突呢?

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 12:50:27