Определены два bean-компонента ThreadPoolTaskScheduler, но все запланированные задачи работают над одним ⇐ JAVA

Программисты JAVA общаются здесь
Anonymous
Определены два bean-компонента ThreadPoolTaskScheduler, но все запланированные задачи работают над одним

Сообщение Anonymous »

Я хочу создать два bean-компонента, возвращающих один и тот же тип объекта:

Код: Выделить всё

    @SuppressWarnings("unused")
@Configuration
@EnableScheduling
public class SchedulingConfig {

@Bean(name = "schedulerHikari")
public ThreadPoolTaskScheduler schedulerHikari() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(1);
scheduler.setThreadNamePrefix("scheduler-hikari-hc-");
return scheduler;
}

@Bean(name = "schedulerJVM")
public ThreadPoolTaskScheduler schedulerJVM() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(1);
scheduler.setThreadNamePrefix("scheduler-jvm-hc-");
return scheduler;
}
}
для создания классов HealthCheck:

Код: Выделить всё

    @Component
@AllArgsConstructor
@Slf4j
@SuppressWarnings("unused")
public class HikariCPCheck implements ApplicationListener,         SchedulingConfigurer {

private final HikariDataSource dataSource;
@Qualifier("schedulerHikari")
private final ThreadPoolTaskScheduler schedulerHikari;
@Value("${healthcheck.datasource.hikari.max-awaiting}")
private final int maxAwaitingConnections;
@Value("${healthcheck.datasource.hikari.scheduler-hikari-delay}")
private final int initialDelay;
@Value("${healthcheck.datasource.hikari.scheduler-hikari-rate}")
private final int fixedRate;

@Override
public void onApplicationEvent(@NonNull ContextRefreshedEvent event) {
try (Connection connection = dataSource.getConnection()) {
log.info("Successfully obtained connection from HikariCP");
} catch (SQLException e) {
if (e.getMessage().contains("Timeout")) {
log.error("HikariCP pool initialization failed: Connection timeout", e);
} else {
log.error("Failed to obtain connection from HikariCP", e);
}
}
}

@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(schedulerHikari);
PeriodicTrigger trigger = new PeriodicTrigger(Duration.ofMinutes(fixedRate));
trigger.setInitialDelay(Duration.ofMinutes(initialDelay));
taskRegistrar.addTriggerTask(
this::logConnectionPoolStatus,
trigger
);
}

private void logConnectionPoolStatus() {
HikariPoolMXBean hikariPoolMXBean = dataSource.getHikariPoolMXBean();
HikariConfigMXBean hikariConfigMXBean = dataSource.getHikariConfigMXBean();

log.info("HikariCP Pool Name: {}", dataSource.getPoolName());
log.info("HikariCP Total Connections: {}", hikariPoolMXBean.getTotalConnections());
if (hikariPoolMXBean.getActiveConnections() >= hikariConfigMXBean.getMaximumPoolSize()) {
log.warn("HikariCP Active Connections reached max pool size {active connections: {}, max pool size: {}}.", hikariPoolMXBean.getActiveConnections(), hikariConfigMXBean.getMaximumPoolSize());
} else {
log.info("HikariCP Active Connections: {active connections: {}, max pool size: {}}.", hikariPoolMXBean.getActiveConnections(), hikariConfigMXBean.getMaximumPoolSize());
}
log.info("HikariCP Idle Connections: {}.", hikariPoolMXBean.getIdleConnections());
if (hikariPoolMXBean.getThreadsAwaitingConnection() >  maxAwaitingConnections) {
log.error("HikariCP Threads Awaiting Connection greater then limit {awaiting threads: {}, max: {}}.", hikariPoolMXBean.getThreadsAwaitingConnection(), maxAwaitingConnections);
} else {
log.info("HikariCP Threads Awaiting Connection: {awaiting threads: {}, max: {}}.", hikariPoolMXBean.getThreadsAwaitingConnection(), maxAwaitingConnections);
}
}
}
второй класс:

Код: Выделить всё

    @Component
@AllArgsConstructor
@Slf4j
@SuppressWarnings("unused")
public class JVMHealthCheck implements SchedulingConfigurer{

private final OperatingSystemMXBean osMXBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
private final MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
@Qualifier("schedulerJVM")
private final ThreadPoolTaskScheduler schedulerJVM;
@Value("${healthcheck.jvm.processor.threshold}")
private final int processorThreshold;
@Value("${healthcheck.jvm.heap-memory.threshold}")
private final int heapMemoryThreshold;
@Value("${healthcheck.jvm.non-heap-memory.threshold}")
private final int nonHeapMemoryThreshold;
@Value("${healthcheck.jvm.scheduler-jvm-delay}")
private final int initialDelay;
@Value("${healthcheck.jvm.scheduler-jvm-rate}")
private final int fixedRate;

@PostConstruct
public void logConnectionConfigStatus() {
MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();
log.info("JVM Available Processors: {}", osMXBean.getAvailableProcessors());
log.info("JVM Init Heap Memory Usage: {}", memoryMXBean.getHeapMemoryUsage().getInit() / (1024 * 1024));
log.info("JVM Max Heap Memory Usage: {}", memoryMXBean.getHeapMemoryUsage().getMax() / (1024 * 1024));
log.info("JVM Init Non Heap Memory Usage: {}", memoryMXBean.getNonHeapMemoryUsage().getInit() / (1024 * 1024));
log.info("JVM Committed Non Heap Memory Usage: {}", memoryMXBean.getNonHeapMemoryUsage().getCommitted() / (1024 * 1024));
}

@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(schedulerJVM);
PeriodicTrigger trigger = new PeriodicTrigger(Duration.ofMinutes(fixedRate));
trigger.setInitialDelay(Duration.ofMinutes(initialDelay));
taskRegistrar.addTriggerTask(
this::logJVMUsageStatus,
trigger
);
}

private void logJVMUsageStatus() {
log.error("wtf");
if (osMXBean.getProcessCpuLoad()*100 > processorThreshold) {
log.warn("JVM Process CPU usage reached threshold {usage: {}, threshold: {}}.", osMXBean.getProcessCpuLoad()*100, processorThreshold);
}
if (osMXBean.getProcessCpuLoad()*100 >= 99) {
log.error("JVM Process CPU usage reached max {usage: {}, max: 100}.", osMXBean.getProcessCpuLoad()*100);
}

MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();
double usedHeapMemory = (double) heapMemoryUsage.getUsed() / heapMemoryUsage.getMax();
double roundedHeapMemoryPercentage = Math.round(usedHeapMemory * 100 * 100.0) / 100.0;

if (roundedHeapMemoryPercentage > heapMemoryThreshold) {
log.warn("JVM Heap Memory usage reached threshold {usage: {}, threshold: {}}.", memoryMXBean.getHeapMemoryUsage().getUsed() / memoryMXBean.getHeapMemoryUsage().getMax(), heapMemoryThreshold);
}
if (roundedHeapMemoryPercentage >= 99) {
log.warn("JVM Heap Memory usage reached max {usage: {}, max: {}}.", roundedHeapMemoryPercentage, heapMemoryUsage.getMax());
}

MemoryUsage nonHeapMemoryUsage = memoryMXBean.getNonHeapMemoryUsage();
double usedNonHeapMemory = (double) nonHeapMemoryUsage.getUsed() / nonHeapMemoryUsage.getMax();
double roundedNonHeapMemoryPercentage = Math.round(usedNonHeapMemory * 100 * 100.0) / 100.0;

if (roundedNonHeapMemoryPercentage >  nonHeapMemoryThreshold) {
log.warn("JVM Non Heap Memory usage reached threshold {usage: {}, threshold: {}}.",  roundedNonHeapMemoryPercentage, nonHeapMemoryThreshold);
}
if (roundedNonHeapMemoryPercentage >= 99) {
log.warn("JVM Non Heap Memory usage reached max {usage: {}, max: {}}.", roundedNonHeapMemoryPercentage, nonHeapMemoryUsage.getMax());
}
}

}
lombok.config:

Код: Выделить всё

lombok.copyableAnnotations+=org.springframework.beans.factory.annotation.Qualifier
свойства приложения:

Код: Выделить всё

spring.main.allow-bean-definition-overriding=false
но все задачи выполняются в одном потоке одного планировщика:

Код: Выделить всё

2024-10-17 20:43:28,682 INFO  [scheduler-jvm-hc-1] b.c.h.HikariCPCheck: HikariCP Pool Name: name
2024-10-17 20:43:28,682 INFO  [scheduler-jvm-hc-1] b.c.h.HikariCPCheck: HikariCP Total Connections: 10
2024-10-17 20:43:28,682 INFO  [scheduler-jvm-hc-1] b.c.h.HikariCPCheck: HikariCP Active Connections: {active connections: 1, max pool size: 10}.
2024-10-17 20:43:28,683 INFO  [scheduler-jvm-hc-1] b.c.h.HikariCPCheck: HikariCP Idle Connections: 9.
2024-10-17 20:43:28,683 INFO  [scheduler-jvm-hc-1] b.c.h.HikariCPCheck: HikariCP Threads Awaiting Connection: {awaiting threads: 0, max: 3}.
2024-10-17 20:43:28,684 ERROR [scheduler-jvm-hc-1] b.c.h.JVMHealthCheck: wtf
Я пробовал использовать отдельные классы компонентов для обоих компонентов — не получилось. Я пытался использовать @Resource, но тоже не работает. В чем причина и как это исправить?

Подробнее здесь: https://stackoverflow.com/questions/790 ... working-on

Вернуться в «JAVA»