Skip to content

Commit

Permalink
perf($Thread): enhance thread pool size
Browse files Browse the repository at this point in the history
  • Loading branch information
johnnymillergh committed Oct 2, 2021
1 parent 0a49320 commit 8a35ceb
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 35 deletions.
2 changes: 0 additions & 2 deletions auth-center/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,6 @@ spring:
min-idle: 0
quartz:
job-store-type: JDBC
scheduler-name: ${spring.application.name}-scheduler
wait-for-jobs-to-complete-on-shutdown: true
jdbc:
initialize-schema: NEVER
properties:
Expand Down
2 changes: 0 additions & 2 deletions maf-mis/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,6 @@ spring:
min-idle: 0
quartz:
job-store-type: JDBC
scheduler-name: ${spring.application.name}-scheduler
wait-for-jobs-to-complete-on-shutdown: true
jdbc:
initialize-schema: NEVER
properties:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
WebSecurityConfiguration.class,
RestTemplateConfiguration.class,
AsyncConfiguration.class,
SchedulingConfiguration.class,
RabbitmqConfiguration.class,
MinioConfiguration.class,
JacksonConfiguration.class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration;
import org.springframework.boot.task.TaskExecutorCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
Expand All @@ -19,10 +20,14 @@
import java.util.concurrent.Callable;
import java.util.concurrent.Executor;

import static cn.hutool.core.text.CharSequenceUtil.format;
import static org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME;

/**
* Description: AsyncConfiguration, change description here.
*
* @author 钟俊(zhongjun), email: zhongjun@toguide.cn, date: 1/29/2021 4:39 PM
* @see TaskExecutionAutoConfiguration
**/
@Slf4j
@EnableAsync
Expand All @@ -42,34 +47,38 @@ public class AsyncConfiguration {
* @return customized async task executor
* @see ThreadPoolTaskExecutor
*/
@Bean(name = "asyncTaskExecutor")
public AsyncTaskExecutor asyncTaskExecutor() {
val executor = new ThreadPoolTaskExecutor();
@Bean
public TaskExecutorCustomizer asyncTaskExecutorCustomizer() {
val corePoolSize = Runtime.getRuntime().availableProcessors() * 2;
log.info("corePoolSize = {}, for AsyncTaskExecutor", corePoolSize);
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(corePoolSize * 3);
executor.setQueueCapacity(QUEUE_CAPACITY);
executor.setBeanName("asyncTaskExecutor");
executor.setThreadNamePrefix(String.format("%s-async-", this.mafProjectProperties.getProjectArtifactId()));
// Specify the RejectedExecutionHandler to use for the ExecutorService.
// Default is the ExecutorService's default abort policy.
executor.setRejectedExecutionHandler(
(runnable, executor1) ->
log.error("Captured rejected execution. Runnable: {}, executor task count: {}",
runnable.toString(), executor1.getTaskCount()));
// It is no longer necessary to manually call the 'executor.initialize()'
log.warn("Initial bean: '{}'", AsyncTaskExecutor.class.getSimpleName());
return executor;
return taskExecutor -> {
taskExecutor.setCorePoolSize(corePoolSize);
taskExecutor.setMaxPoolSize(corePoolSize * 3);
taskExecutor.setQueueCapacity(QUEUE_CAPACITY);
taskExecutor.setBeanName("asyncTaskExecutor");
taskExecutor.setThreadNamePrefix(format("{}-async-", this.mafProjectProperties.getProjectArtifactId()));
// Specify the RejectedExecutionHandler to use for the ExecutorService.
// Default is the ExecutorService's default abort policy.
taskExecutor.setRejectedExecutionHandler(
(runnable, executor1) ->
log.error(
"Captured rejected execution. Runnable: {}, executor task count: {}",
runnable.toString(), executor1.getTaskCount()
)
);
log.warn("Enhanced taskExecutor. corePoolSize = {}, maxPoolSize = {}, queueCapacity = {}",
taskExecutor.getCorePoolSize(), taskExecutor.getMaxPoolSize(), QUEUE_CAPACITY);
};
}

@Bean
public AsyncConfigurer asyncConfigurer(@Qualifier("asyncTaskExecutor") AsyncTaskExecutor asyncTaskExecutor) {
public AsyncConfigurer asyncConfigurer(
@Qualifier(APPLICATION_TASK_EXECUTOR_BEAN_NAME) ThreadPoolTaskExecutor threadPoolTaskExecutor
) {
log.warn("Initial bean: '{}'", AsyncConfigurer.class.getSimpleName());
return new AsyncConfigurer() {
@Override
public Executor getAsyncExecutor() {
return asyncTaskExecutor;
return threadPoolTaskExecutor;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.jmsoftware.maf.springcloudstarter.configuration;

import com.jmsoftware.maf.springcloudstarter.property.MafProjectProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration;
import org.springframework.boot.task.TaskSchedulerCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;

import static cn.hutool.core.text.CharSequenceUtil.format;

/**
* <h1>SchedulingConfiguration</h1>
* <p>
* Change description here.
*
* @author Johnny Miller (鍾俊), email: johnnysviva@outlook.com, 10/2/21 2:30 PM
* @see TaskSchedulingAutoConfiguration
**/
@Slf4j
@EnableScheduling
@RequiredArgsConstructor
public class SchedulingConfiguration {
public static final int TASK_SCHEDULER_POOL_SIZE = 2;
private final MafProjectProperties mafProjectProperties;

@Bean
public TaskSchedulerCustomizer taskSchedulerCustomizer() {
return taskScheduler -> {
taskScheduler.setPoolSize(TASK_SCHEDULER_POOL_SIZE);
taskScheduler.setThreadNamePrefix(
format("{}-task-scheduler-", this.mafProjectProperties.getProjectArtifactId())
);
taskScheduler.setAwaitTerminationSeconds(10);
log.warn("Enhanced taskScheduler. poolSize = {}", taskScheduler.getPoolSize());
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
import com.jmsoftware.maf.springcloudstarter.quartz.controller.QuartzJobConfigurationController;
import com.jmsoftware.maf.springcloudstarter.quartz.service.QuartzJobConfigurationService;
import com.jmsoftware.maf.springcloudstarter.quartz.service.impl.QuartzJobConfigurationServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.quartz.Scheduler;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration;
import org.springframework.boot.autoconfigure.quartz.QuartzProperties;
import org.springframework.boot.autoconfigure.quartz.SchedulerFactoryBeanCustomizer;
import org.springframework.context.annotation.Bean;
Expand All @@ -17,25 +19,35 @@
import java.util.Map;
import java.util.Properties;

import static cn.hutool.core.text.CharSequenceUtil.format;
import static org.springframework.scheduling.quartz.SchedulerFactoryBean.PROP_THREAD_COUNT;

/**
* Description: QuartzConfiguration, change description here.
*
* @author Johnny Miller (锺俊), email: johnnysviva@outlook.com, date: 7/13/2021 10:44 PM
* @see QuartzAutoConfiguration
**/
@Slf4j
@RequiredArgsConstructor
@ConditionalOnClass({Scheduler.class, SchedulerFactoryBean.class, PlatformTransactionManager.class})
public class QuartzConfiguration {
private final MafProjectProperties mafProjectProperties;

@Bean
public SchedulerFactoryBeanCustomizer threadPoolCustomizer(QuartzProperties quartzProperties) {
public SchedulerFactoryBeanCustomizer schedulerFactoryBeanCustomizer(QuartzProperties quartzProperties) {
val cpuCoreCount = Runtime.getRuntime().availableProcessors();
val threadCount = String.valueOf(cpuCoreCount * 2);
quartzProperties.getProperties().put(PROP_THREAD_COUNT, threadCount);
return schedulerFactoryBean -> {
val cpuCoreCount = Runtime.getRuntime().availableProcessors();
val threadCount = String.valueOf(cpuCoreCount * 2);
quartzProperties.getProperties().put(PROP_THREAD_COUNT, threadCount);
schedulerFactoryBean.setQuartzProperties(this.asProperties(quartzProperties.getProperties()));
log.warn("Quartz thread pool enhanced by current cpuCoreCount: {}, threadCount: {}", cpuCoreCount,
threadCount);
schedulerFactoryBean.setQuartzProperties(this.asProperties(quartzProperties.getProperties()));
schedulerFactoryBean.setSchedulerName(
format("{}-quartz-scheduler", this.mafProjectProperties.getProjectArtifactId())
);
schedulerFactoryBean.setWaitForJobsToCompleteOnShutdown(true);
schedulerFactoryBean.setBeanName("schedulerFactoryBean");
};
}

Expand All @@ -46,9 +58,9 @@ private Properties asProperties(Map<String, String> source) {
}

@Bean
public GreetingBean greetingBean(MafProjectProperties mafProjectProperties) {
public GreetingBean greetingBean() {
log.warn("Initial bean: '{}'", GreetingBean.class.getSimpleName());
return new GreetingBean(mafProjectProperties);
return new GreetingBean(this.mafProjectProperties);
}

@Bean
Expand All @@ -60,9 +72,8 @@ public QuartzJobConfigurationController quartzJobConfigurationController(
}

@Bean
public QuartzJobConfigurationService quartzJobConfigurationService(SchedulerFactoryBean schedulerFactoryBean,
MafProjectProperties mafProjectProperties) {
public QuartzJobConfigurationService quartzJobConfigurationService(SchedulerFactoryBean schedulerFactoryBean) {
log.warn("Initial bean: '{}'", QuartzJobConfigurationServiceImpl.class.getSimpleName());
return new QuartzJobConfigurationServiceImpl(schedulerFactoryBean, mafProjectProperties);
return new QuartzJobConfigurationServiceImpl(schedulerFactoryBean, this.mafProjectProperties);
}
}

0 comments on commit 8a35ceb

Please sign in to comment.