Spring Integration 和 ThreadPoolTaskExecutor

huangapple go评论79阅读模式
英文:

Spring Integration and ThreadPoolTaskExecutor

问题

我正在处理一个基于注解配置的Spring Integration项目。
我们从另一个团队继承了这个项目,现在正在努力弄清楚ThreadPoolTaskExecutors是否被正确使用。以下是TaskExecutors的配置:

@Bean
public TaskExecutor businessTaskExecutor() {
    ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
    pool.setCorePoolSize(30);
    pool.setMaxPoolSize(Integer.MAX_VALUE);
    pool.setQueueCapacity(Integer.MAX_VALUE);
    return pool;
}

@Bean
public TaskExecutor eventTaskExecutor() {
    ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
    pool.setCorePoolSize(30);
    pool.setMaxPoolSize(Integer.MAX_VALUE);
    pool.setQueueCapacity(Integer.MAX_VALUE);
    return pool;
}

如上所示,定义了5个TaskExecutor。虽然我不是专家,但我确定它们应该被不同地配置。这些执行器的使用如下所示:

@Bean
public MessageChannel inputChannel() {
    return new PublishSubscribeChannel(businessTaskExecutor());
}

@Bean
public MessageChannel outputChannel() {
    PublishSubscribeChannel outputChannel = new PublishSubscribeChannel(
            businessTaskExecutor());
    outputChannel
            .addInterceptor(new WireTap(eventTrackerChannel()));
    return outputChannel;
}

@Bean
public MessageChannel eventTrackerChannel() {
    return new ExecutorChannel(eventTaskExecutor());
}

输入和输出通道在一些ServiceActivator中被使用。eventTrackerChannel用于拆分Spring Integration流程并将某些事件写入数据库。这些只是为了理解项目结构而提供的示例。

现在的问题是,TaskExecutor是否被正确使用?如果我们消除了ThreadPoolTaskExecutors并且没有为通道提供它们,Spring是否会管理线程?采用这种第二种方法是否可能出现问题?

我想尽量学好Spring Integration,对于这些问题的答案将会帮助很多。在此提前感谢那些将帮助我理解这种行为的人。

英文:

I'm working on a Spring Integration Project with annotation based configuration.
We inherited this project from another team and are trying to figure out if the ThreadPoolTaskExecutors are being used correctly. Below is a configuration of TaskExecutors:

@Bean
public TaskExecutor businessTaskExecutor() {
	ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
	pool.setCorePoolSize(30);
	pool.setMaxPoolSize(Integer.MAX_VALUE);
	pool.setQueueCapacity(Integer.MAX_VALUE);
	return pool;
}

@Bean
public TaskExecutor eventTaskExecutor() {
	ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
	pool.setCorePoolSize(30);
	pool.setMaxPoolSize(Integer.MAX_VALUE);
	pool.setQueueCapacity(Integer.MAX_VALUE);
	return pool;
}

There are 5 TaskExecutor defined as indicate above. I'm not an expert but I know for sure they should be configured differently. These executors are used as follows:

@Bean
public MessageChannel inputChannel() {
	return new PublishSubscribeChannel(businessTaskExecutor());
}

@Bean
public MessageChannel outputChannel() {
	PublishSubscribeChannel outputChannel = new PublishSubscribeChannel(
			businessTaskExecutor());
	outputChannel
			.addInterceptor(new WireTap(eventTrackerChannel()));
	return outputChannel;
}

@Bean
public MessageChannel eventTrackerChannel() {
	return new ExecutorChannel(eventTaskExecutor());
}

The input and output channels are used in some ServiceActivator. The eventTrackerChannel is used to split the Spring Integration flow and write some events on DB. These are just examples to understand how the project is structured.

Now the question is, are taskexecutors used correctly? If we eliminate the ThreadPoolTaskExecutors and they are not provided for the channels, should Spring manage the threads? Could there be problems in proceeding with this second approach?

I would like to learn Spring Integration as best I can and the answers to these questions would help a lot. I thank in advance who will help me understand this behavior.

答案1

得分: 2

ThreadPool是一个辅助工具,可以在一些不依赖顺序的进程运行时,避免阻塞主线程。但并非必须使用这些线程池,但如果不使用它们,您可能会丧失性能或增加失败的机会,因为这些机制通常除了池化之外还具有某种控制,比如在池已满时排队事件或重用线程。当然,每种情况都需要进行检查,以确定哪种方式更合适,但我认为如果您不需要这些事件按特定顺序发生,建议保持原样。

我发现不同的是您设置的线程池大小。但我不了解您的要求,因此无法对此做出任何结论。我通常看到的是PoolSize大约为5,maxSize大约为10。另一件事是也许您不需要为每个任务都单独创建一个线程池,一个线程池可能就足够了。但正如我所说,我无法断言什么是对的或错误的,因为每个系统都有自己的要求。

最后一个可能改进的细节是不要将此设置硬编码,而是在您的application.properties中放入这些信息,比如maxThreadPoolSize=10threadPoolSize=5,然后在设置bean的时候访问它。

英文:

ThreadPool is a helper for us to not hold the main thread while some process that not depend of order is running. But it's not mandatory to use theses pools, but I am afraid that you may lose performance or increase the chance of failure without them, since these mechanisms normally has some kind of control besides pooling, like queuing events when the pool is full or reusing threads. Of course each case needs to be checked to see what fits better, but I believe if you don't need these events happening in a specifically order, I suggest you let this how it's.

What I've found different is how big your pools were set. But I don't know your requirements, so I can't conclude anything about this. What I normally see is the PoolSize something like 5 and maxSize like 10. Another thing is maybe you don't need each pool for each thing, one for all maybe it's suitable. But as I said, I can't say what's right or wrong, since each system has its own requirements.

The last detail that could be better is not hardcoding this setup, put in your application.properties these information like maxThreadPoolSize=10 or threadPoolSize=5 and then access it in the moment you setup the bean.

huangapple
  • 本文由 发表于 2020年9月15日 17:31:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/63899008.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定