gpt4 book ai didi

Spring-Boot + Camel + producerTemplate = 千线程

转载 作者:行者123 更新时间:2023-12-01 15:42:40 25 4
gpt4 key购买 nike

---更新---
事实证明,堆在一段时间后会被清空。然而,线程的数量只会无休止地增长。在我有 8Gb RAM 的 Mac 上我很好,但是在有 1Gb 的生产机器上我得到:

Exception in thread "Thread-341" java.lang.OutOfMemoryError: unable to create new native thread


我确实使用 Spring Boot (1.2.7.RELEASE) 和 Apache Camel (2.15.0) 编写了一个简单的应用程序。该应用程序很简单,只有 1 个路由:计时器将每隔 1 秒调用一个 bean 上的方法。调用的方法将使用 ProducerTemplate 通过 ssh 连接到远程机器,执行一个小脚本,并将输出打印到控制台。很简单吧?
但是,在对此进行分析时,我可以看到线程数,并且堆通过了屋顶!似乎为 ssh 创建的任何线程都不会被杀死,而是被停放。因此,我运行 OOM 的速度非常快。
让我向您展示一些探查器输出: heap/threads monitor threads list heap cleaned

如您所见,线程/堆的增长速度非常快。应用程序代码很少,所以我会在这里全部提供以供引用。
pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>tests</groupId>
<artifactId>camel-producer-template-testing</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<start-class>app.Application</start-class>
<camel.version>2.15.0</camel.version>
<spring-boot.version>1.2.7.RELEASE</spring-boot.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring-boot</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-ftp</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-ssh</artifactId>
<version>${camel.version}</version>
</dependency>
</dependencies>

<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<build>
<finalName>${project.artifactId}-${project.version}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>

应用程序.java:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import java.util.TimeZone;

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {
public static void main(String[] args) {
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
SpringApplication application = new SpringApplication(Application.class);
application.run(args);
}
}

MyAppContext.java:

import org.apache.camel.CamelContext;
import org.apache.camel.RoutesBuilder;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.spring.SpringCamelContext;
import org.apache.sshd.common.keyprovider.FileKeyPairProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@PropertySource("application.properties")
public class MyAppContext {

private final String sshKeyPath = "/Users/gruszd/.ssh/id_rsa";

@Autowired
private ApplicationContext applicationContext;

@Bean
public CamelContext camelContext() {
return new SpringCamelContext(applicationContext);
}

@Bean
FileKeyPairProvider keyPairProvider() {
return new FileKeyPairProvider(new String[]{sshKeyPath});
}

@Bean
RoutesBuilder myRouter() {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
from("timer://foo?period=1000").to("bean:sftpStager?method=stage");
}
};
}
}

SftpStager.java:

import org.apache.camel.ProducerTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class SftpStager {

@Autowired
private ProducerTemplate producerTemplate;

public void stage() throws Exception {
String response = producerTemplate.requestBody(
"ssh://_remote.machine.url.here_?username=_username_&keyPairProvider=#keyPairProvider",
"/home/_username_/some_temp_script.sh",
String.class);
System.out.println("----");
System.out.println(response);
System.out.println("----");
}
}

如您所见,该应用非常精简,而且可以正常运行(我可以在运行该应用的控制台中看到远程脚本的输出)。但正如我所说,它会像新鲜 cookies 一样消耗内存!
现在我读了this .但是,在我的应用程序中,ProducerTemplate 是由 Camelcontext 本身实例化的 bean。因此我不能 producerTemplate.stop() 因为下一个触发器会抛出一个异常,说明模板没有启动...
所以我的主要问题是:我是否以错误的方式使用了 ProducerTemplate?如果我这样做,我应该如何使用它?
如果我没有做错什么,那是错误吗?我应该报告吗?

最佳答案

如原发帖者所述:

Turns out it is a bug in Apache Camel itself, should be [and was] fixed in 2.16.2: Jira Issue here

关于Spring-Boot + Camel + producerTemplate = 千线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33671567/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com