[spring-projects/spring-boot]WebFlux 3.0 + micrometer-tracing-bridge-brave + enableAutomaticContextPropagation 中的内存泄漏

2024-06-26 529 views
2

你好,

在生产中,我从 spring boot webflux + zipkin 2.7.x App 升级到 spring boot webflux + zipkin 3.0.4,并且我注意到堆中存在内存泄漏。

我将问题归结为 WebFlux 3.0 + micrometer-tracing-bridge-brave + enableAutomaticContextPropagation 的组合存在内存泄漏。https ://github.com/davidmelia/spring-cloud-function-zipkin/tree/memory_leak显示了一个例子。如果你运行应用程序并 ping 健康检查,那么随着时间的推移,堆会填满

#!/bin/bash
for i in {1..500}
do
   curl http://localhost:8080/actuator/health
done

您会注意到 brave.baggage.CorrelationUpdateScope$Multiple 从未被垃圾收集完全回收,并且随着时间的推移而累积:

图像

我已将堆转储插入 eclipse 内存分析器,看起来 react.netty.resources.DefaultLoopResources$EventLoop 正在控制线程本地:

图像

深入到线程本地,有一个巨大的 brave.baggage.CorrelationUpdateScope$Multiple 数组

图像

注意:我知道这看起来像是 Hooks.enableAutomaticContextPropagation 或 micrometer-tracing-bridge-brave 的问题,但它在 Spring Boot Webflux 中表现出来

(与https://github.com/spring-projects/spring-boot/issues/34201相关)

回答

9

我已经升级到 1.0.4-SNAPSHOT (https://github.com/davidmelia/spring-cloud-function-zipkin/blob/memory_leak_potential_fix/pom.xml)但遇到了另一个问题

    *__checkpoint ⇢ HTTP GET "/actuator/health" [ExceptionHandlingWebHandler]
Original Stack Trace:
        at io.micrometer.tracing.handler.TracingObservationHandler.getRequiredSpan(TracingObservationHandler.java:183) ~[micrometer-tracing-1.0.4-SNAPSHOT.jar:1.0.4-SNAPSHOT]
        at io.micrometer.tracing.handler.PropagatingReceiverTracingObservationHandler.onStop(PropagatingReceiverTracingObservationHandler.java:97) ~[micrometer-tracing-1.0.4-SNAPSHOT.jar:1.0.4-SNAPSHOT]

嗯嗯……

1

哇,我现在也看到了(我当时肯定没有错误的情况)——让我看看

8

哇,这很奇怪,以前如果你用 运行你的应用程序,-ea就会抛出异常,这个问题已经解决了,我认为这就是根本原因。我需要进一步调查这个问题

3

抱歉@marcingrzejszczak,当我说同样的问题时,它现在确实有效(即没有堆栈跟踪),但我得到了原始的内存泄漏。

7

我有一个解决方法来消除内存泄漏。设置此属性

management:
  tracing:
    baggage:
      correlation:
        enabled: false

并设置这个 bean

@Bean
  @Order(1)
  CorrelationScopeCustomizer myCorrelationFieldsCorrelationScopeCustomizer(TracingProperties tracingProperties) {
    return (builder) -> {
      List<String> correlationFields = tracingProperties.getBaggage().getCorrelation().getFields();
      for (String field : correlationFields) {
        builder.add(CorrelationScopeConfig.SingleCorrelationField.newBuilder(BaggageField.create(field))
                .build());
      }
    };
  }

本质上,它删除了导致内存泄漏的 Brave 更新时刷新功能。我们仍在调查整个问题。

顺便说一句@wilkinsona我认为这个错误适用于所有Webflux项目,我们现在应该默认禁用更新时刷新功能

6

谢谢,@marcingrzejszczak。距离下一个 Boot 版本发布还有大约一个月的时间,届时我们可以这样做。也许这会给我们一些时间来找出不同的解决方案。

8

你好,

关于此问题的真正修复还有什么更新吗?

2

我们在发布微米追踪功能时遇到了问题,修复后我们会通知您

9

@marcingrzejszczak 这是关于您在此处给出的修复。我还面临此类 brave.baggage.CorrelationUpdateScope$Single 的内存泄漏问题,它占用了实例数量/大小的 55%,并且即使在一起工作了几个小时也没有被垃圾收集。我的环境 - spring boot 2.7.6 + spring cloud sleuth。这是我的 gradle 文件。

plugins {
    id 'org.springframework.boot' version '2.7.6'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
    id 'com.github.sherter.google-java-format' version '0.9'
    id 'jacoco'
    id 'com.gorylenko.gradle-git-properties' version '2.3.1'
}

group = 'com.xxx.yyy'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

def lombokVersion ='1.18.22'
def openApiVersion = '1.6.7'

repositories {
    mavenCentral()
}

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

ext {
    set('springCloudVersion', "2021.0.5")
    set('openFeignVersion', "11.8")
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
        mavenBom "org.springframework.session:spring-session-bom:2021.1.2"
    }
}

dependencies {
    implementation(
            "org.springframework.cloud:spring-cloud-starter-circuitbreaker-resilience4j",
            "org.springframework.cloud:spring-cloud-starter-circuitbreaker-reactor-resilience4j",
            "org.springframework.cloud:spring-cloud-starter-gateway",
            "org.springframework.cloud:spring-cloud-starter-openfeign",
            'org.springframework.cloud:spring-cloud-starter-sleuth',
            "io.github.openfeign:feign-jackson:${openFeignVersion}",
            "org.springframework.boot:spring-boot-starter-security",
            "org.springframework.boot:spring-boot-starter-oauth2-client",
            "org.springframework.boot:spring-boot-starter-tomcat",
            "org.springframework.security:spring-security-oauth2-resource-server",
            "org.projectlombok:lombok:${lombokVersion}",
            "org.freemarker:freemarker:2.3.31",
            'commons-codec:commons-codec:1.15',
            'org.apache.commons:commons-lang3:3.12.0',
            "com.squareup.okhttp3:okhttp:4.9.3",
            'net.logstash.logback:logstash-logback-encoder:6.6',
            'org.springframework.boot:spring-boot-starter-actuator',
            "org.springframework.boot:spring-boot-starter-cache",
            "org.springframework.cloud:spring-cloud-sleuth-zipkin",
            "commons-validator:commons-validator:1.7",
            "org.springdoc:springdoc-openapi-webflux-core:${openApiVersion}",
            "org.springdoc:springdoc-openapi-webflux-ui:${openApiVersion}",
            "org.springdoc:springdoc-openapi-security:${openApiVersion}",
            "org.springframework.boot:spring-boot-starter-webflux",
            "org.springframework.session:spring-session-data-redis",
            "io.lettuce:lettuce-core:6.1.8.RELEASE"
    )
}

当我尝试设置 bean 时

  @Bean
  @Order(1)
  CorrelationScopeCustomizer myCorrelationFieldsCorrelationScopeCustomizer(TracingProperties tracingProperties) {
    return (builder) -> {
      List<String> correlationFields = tracingProperties.getBaggage().getCorrelation().getFields();
      for (String field : correlationFields) {
        builder.add(CorrelationScopeConfig.SingleCorrelationField.newBuilder(BaggageField.create(field))
                .build());
      }
    };
  }

我收到错误“无法解析 TracingProperties”。我在当前的 gradle deps 中找不到 TracingProperties 类。有什么想法吗?

1

我不明白你想做什么。这是一个有关 Spring Boot 3 的问题,而你却向我们展示了 Spring Cloud Sleuth :耸肩:

6

确实。在我看来这似乎与主题无关。@siganapathy 请在 Stack Overflow 上提问。

4

Micrometer Tracing 1.0.6 和 1.1.1 已发布,Boot 已在使用这些版本,下一个版本应该包含它们。您可以:

  1. 升级您的依赖项并强制修复 Micrometer Tracing 版本。
  2. 等待 Boot 发布(计划于明天发布)
0

它在 SB 3.1.0 @jonatan-ivanov 中修复了吗?

0

@jonatan-ivanov 谢谢你的信息 - 关闭状态让我不确定 ;)

2

有一个for: external-project标签表明实际决定并非在这里做出。

0

那么在 SB 3.1.x 中这个问题已经消失,不再需要解决方法了?如果您能确认的话@marcingrzejszczak。

提前致谢!

1

因此,在我们发布 Micrometer 1.10.10 和所有前向合并分支(该版本将在下个月的某个时间发布)之前,问题应该已经解决。您需要添加代码片段


@Configuration
class class Config {

   @Autowired ObservationRegistry or;

   @PostConstruct
   void setup() {
      ObservationThreadLocalAccessor.getInstance().setObservationRegistry(or);
   }
}

我们发布微米项目的下一个补丁版本后,可以删除此代码。

8

谢谢@marcingrzejszczak。需要说明的是 - 在 SB 3.1.x 中,没有必要将这些更改全部添加进去application.yml(就像您在上面的一些帖子中提到的那样) CorrelationScopeCustomizer myCorrelationFieldsCorrelationScopeCustomizer

只有这个@PostConstruct配置,只能等待新版本吗?

5

@davidmelia 正确