Skip to content

Conversation

@jhlee0409
Copy link
Member

@jhlee0409 jhlee0409 commented Feb 6, 2025

🚀 트랜잭션 락 방지를 위한 아웃박스 패턴 도입

📝 변경 사항

  • 아웃박스 패턴 및 카프카 통합 구현
  • 주식 거래(BuyStock, SellStock) 처리 로직 개선
  • 비동기 메시지 처리 스케줄러 구현

🔍 배경

  • 동시에 100건 이상의 BuyStock 요청 발생 시 트랜잭션 락으로 인한 서비스 지연
  • 카프카 장애 시 전체 트랜잭션 롤백 문제 발생
  • 대량 동시 처리 요구사항 충족 필요

📊 개선 효과

  • 트랜잭션 락 발생 감소: DB 락 경합 최소화로 동시 처리 성능 향상
  • 장애 격리: 카프카 장애 시에도 주식 거래 트랜잭션 안정적 수행
  • 확장성 향상: 배치 처리 및 비동기 메시지 처리로 시스템 부하 분산

🛠️ 구현 내용

  • MongoDB 기반 아웃박스 테이블 설계 및 구현
  • 3초 주기 메시지 처리 및 30초 주기 실패 메시지 재시도 스케줄러
  • 배치 메시지 처리 및 토픽별 그룹화 최적화
  • 장애 대응 및 재시도 메커니즘 구현

📋 확인 사항

  • 주식 거래 기능이 정상적으로 동작하는가?
  • 트랜잭션 락 문제가 해결되었는가?
  • 카프카 장애 시에도 시스템이 안정적으로 동작하는가?
  • 성능 요구사항을 충족하는가?

@@ -0,0 +1,37 @@
services:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docker-compose.yml 파일은 docker폴더 안에 두는 것 보다
루트폴더에 두는게 좋을듯 해요.

GPT 피셜

  • 표준 관행: Docker Compose 파일은 일반적으로 프로젝트의 루트 디렉토리나 서비스 디렉토리의 바로 아래에 위치하는 것이 일반적입니다.
  • 단순성: 불필요한 중첩 디렉토리를 제거함으로써 프로젝트 구조가 더 단순해집니다.
  • 접근성: 다른 개발자들이 프로젝트를 살펴볼 때 docker-compose.yml 파일을 더 쉽게 찾을 수 있습니다.
  • 명령어 실행의 편의성: docker-compose 명령을 실행할 때 별도의 경로 지정 없이 더 쉽게 실행할 수 있습니다.

@jhlee0409 jhlee0409 marked this pull request as ready for review March 7, 2025 20:47
@jhlee0409 jhlee0409 changed the title Feat/kafka-setting: 카프카 초기 세팅 테스트 Feat/kafka-setting: 트랜잭션 락 최소화를 위한 성능 개선 Mar 7, 2025
environment:
- DYNAMIC_CONFIG_ENABLED=true
- KAFKA_CLUSTERS_0_NAME=koi_kafka
- KAFKA_CLUSTERS_0_NAME=stock-service
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sdc-stock 으로 변경해도 괜찮을까요?

PollModule,
StockModule,
PartyModule,
KafkaModule.forRootAsync({
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feature-nest-stock 에서 KafkaModule.forFeature 쓸 수 있을까요?

private readonly logger = new Logger(KafkaService.name);

private kafka = new Kafka({
brokers: ['localhost:9094'],
Copy link
Collaborator

@omizha omizha Mar 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

환경변수로 브로커 주소 받아주세요
lib-nest-kafka 로 재사용 가능하게 구성한다면 options.broker 입력 받아주세요

inject?: Array<Type<unknown> | string | symbol | Abstract<unknown> | Function>;
}

@Module({
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

KafkaModule을 package/library/lib-nest-kafka 로 옮길 수 있을까요?

imports: [MongooseModule.forFeature([{ name: Outbox.name, schema: OutboxSchema }]), KafkaModule],
providers: [OutboxRepository, OutboxProcessor, OutboxService],
})
export class OutboxModule {}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아웃박스 패턴이 무엇인지 주석이나 README.md 가 필요할 것 같아요

constructor(private readonly outboxService: OutboxService, private readonly kafkaService: KafkaService) {}

@Cron(CronExpression.EVERY_5_SECONDS)
async processOutboxMessages(): Promise<void> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 함수가 무엇인지 더 자세히 적을 필요가 있을듯 해요!
Cron을 5초마다 걸어둔 배경도 궁금해요 (주석으로)

async setStockPhase(stockId: string, phase: StockPhase): Promise<Stock> {
if (phase === 'INTRO_RESULT') {
await this.userService.alignIndexByOpenAI(stockId);
await this.userService.alignIndex(stockId);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 변경점의 의도는 무엇인가요?

- DYNAMIC_CONFIG_ENABLED=true
- KAFKA_CLUSTERS_0_NAME=koi_kafka
- KAFKA_CLUSTERS_0_NAME=stock-service
- KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS=kafka:9092
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저희 카프카 서버 9092와 9094 서버의 차이가 무엇인가요? 각자 역할이 뭔지 궁금해요

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants