Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
707e855
README.md 작성 및 DTO 네이밍 컨벤션에 맞게 리팩토링 (#239)
jihukimme Oct 1, 2025
c6b84f9
다이어그램 파일명 수정 (#240)
jihukimme Oct 1, 2025
ccc7a2c
Spring Quartz에 Cluster를 이용한 schedule, workflow 실시간 반영 (#238)
bwnfo3 Oct 2, 2025
8bc6a27
docs: 다이어그램 및 시연 영상 업로드
jihukimme Oct 2, 2025
bb32fb1
docs: 시연 영상 유튜브 링크 업로드
jihukimme Oct 2, 2025
bc755b5
docs: 시연영상 목차 추가
can019 Oct 8, 2025
1a850e2
목차 및 각 콘텐츠 앵커 링크 도입 (#242)
can019 Oct 8, 2025
29b9b4c
docs: ERD 추가 및 시퀀스 다이어그램 경로 수정 (#244)
jihukimme Oct 9, 2025
283723e
Merge branch 'main' into develop
jihukimme Oct 9, 2025
1c6963d
서버 장애 발생으로 인해 중단된 워크플로우 자동 복구 및 이어하기(Resume) 기능 구현 (#246)
jihukimme Jan 22, 2026
b6af254
refactor: 워크플로우 재개(Resume) 로직 개선 및 README 문서 보완 (#248)
jihukimme Jan 22, 2026
b92b249
Merge branch 'main' into develop
jihukimme Jan 22, 2026
6c1607d
refactor: 통신 기술 스택 변경 (RestTemplate -> RestClient) 및 E2E 테스트 안정화 (#249)
jihukimme Feb 10, 2026
63f11dc
[Refactor] 가상 스레드 도입을 통한 비동기 처리 최적화 (#251)
jihukimme Feb 13, 2026
fbda4bb
Feature/async optimization (#253)
jihukimme Feb 14, 2026
3d5a51e
refactor: update MyBatis type-aliases-package to use domain instead o…
jihukimme Feb 14, 2026
fdce465
chore: 장기실행작업(워크플로우)에 대해서만 가상스레드 설정
jihukimme Feb 14, 2026
d85e420
chore: increase HikariCP pool size and refine semaphore initializatio…
jihukimme Feb 14, 2026
90c70f9
chore: increase HikariCP pool size and refine semaphore initializatio…
jihukimme Feb 14, 2026
5d146fc
Revert "refactor: 통신 기술 스택 변경 (RestTemplate -> RestClient) 및 E2E 테스트 …
jihukimme Feb 14, 2026
d8e0e19
Merge branch 'main' into develop
jihukimme Feb 14, 2026
fae43d9
chore: replace ThreadPoolTaskExecutor with SimpleAsyncTaskExecutor an…
jihukimme Feb 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,31 +1,42 @@
package site.icebang.global.config.asnyc;
package site.icebang.global.config.async;

import java.lang.reflect.Method;
import java.util.concurrent.Executor;

import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.core.task.TaskDecorator;
import org.springframework.core.task.support.ContextPropagatingTaskDecorator;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Configuration
@EnableAsync
@RequiredArgsConstructor
public class AsyncConfig implements AsyncConfigurer {

private final SemaphoreTaskDecorator semaphoreTaskDecorator;

@Bean("traceExecutor")
public ThreadPoolTaskExecutor traceExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(50);
executor.setQueueCapacity(100);
executor.setTaskDecorator(new ContextPropagatingTaskDecorator()); // 필수
public Executor traceExecutor() {
SimpleAsyncTaskExecutor executor = new SimpleAsyncTaskExecutor();
executor.setVirtualThreads(true);
executor.setThreadNamePrefix("trace-");
executor.initialize();

// MDC 전파 데코레이터 생성
TaskDecorator contextDecorator = new ContextPropagatingTaskDecorator();

// 두 데코레이터의 조합:
// Context 설정(MDC 복사) 후 Semaphore 제어가 적용되도록 구성
executor.setTaskDecorator(
runnable -> contextDecorator.decorate(semaphoreTaskDecorator.decorate(runnable)));

return executor;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package site.icebang.global.config.async;

import java.util.concurrent.Semaphore;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.task.TaskDecorator;
import org.springframework.stereotype.Component;

import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class SemaphoreTaskDecorator implements TaskDecorator {

@Value("${spring.datasource.hikari.maximum-pool-size:10}")
private int maximumPoolSize;

private Semaphore semaphore;

@PostConstruct
public void init() {
int safetyBuffer = 5;
int taskConcurrencyLimit = Math.max(1, maximumPoolSize - safetyBuffer);

this.semaphore = new Semaphore(taskConcurrencyLimit);
log.info(
"SemaphoreTaskDecorator 초기화: DB 풀({}) - 여유분({}) = 동시 실행 제한 수({})",
maximumPoolSize,
safetyBuffer,
taskConcurrencyLimit);
}

@Override
public Runnable decorate(Runnable runnable) {
return () -> {
try {
semaphore.acquire();
runnable.run();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error("비동기 작업 실행 대기 중 인터럽트 발생", e);
} finally {
semaphore.release();
}
};
}
}
4 changes: 2 additions & 2 deletions apps/user-service/src/main/resources/application-develop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ spring:
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
maximum-pool-size: 10
minimum-idle: 5
maximum-pool-size: 30
minimum-idle: 10
pool-name: HikariCP-MyBatis

quartz:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ spring:
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
maximum-pool-size: 10
minimum-idle: 5
maximum-pool-size: 30
minimum-idle: 10
pool-name: HikariCP-MyBatis

# Gmail 연동 설정
Expand All @@ -39,7 +39,7 @@ spring:

mybatis:
mapper-locations: classpath:mybatis/mapper/**/*.xml
type-aliases-package: site.icebang.dto
type-aliases-package: site.icebang.domain
configuration:
map-underscore-to-camel-case: true

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ spring:

mybatis:
mapper-locations: classpath:mybatis/mapper/**/*.xml
type-aliases-package: site.icebang.dto
type-aliases-package: site.icebang.domain
configuration:
map-underscore-to-camel-case: true

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ spring:

mybatis:
mapper-locations: classpath:mybatis/mapper/**/*.xml
type-aliases-package: site.icebang.dto
type-aliases-package: site.icebang.domain
configuration:
map-underscore-to-camel-case: true

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ spring:

mybatis:
mapper-locations: classpath:mybatis/mapper/**/*.xml
type-aliases-package: site.icebang.dto
type-aliases-package: site.icebang.domain
configuration:
map-underscore-to-camel-case: true

Expand Down
Loading