Nodejs

NestJS 마이크로서비스 - NotificationMicroservice를 gRPC 기반으로 변경하기

 

 

1. 기존 구조

기존의 NotificationService는 OrderMicroservice와의 통신을 이벤트 기반(emit) 으로 처리했습니다.

// 기존 메시지 큐 방식 (주석 처리된 부분)
// this.orderMicroservice.emit(
//   {
//     cmd: 'delivery_started',
//   },
//   { id },
// );

이 방식은 결제 알림을 생성하고 이메일 전송을 시뮬레이션한 뒤, 주문 서비스로 delivery_started 이벤트를 발행하는 구조였습니다. 그러나 메시지 기반 이벤트만으로는 명확한 계약(Contract)이나 응답 값을 보장하기 어렵다는 한계가 있었습니다.

 

 

2. gRPC 방식으로 전환

gRPC 클라이언트 주입

NestJS의 ClientGrpc를 사용해 OrderMicroservice와 gRPC 기반 통신을 하도록 코드를 변경했습니다.

constructor(
  @InjectModel(Notification.name)
  private readonly notificationModel: Model<Notification>,

  @Inject(ORDER_SERVICE)
  private readonly orderMicroservice: ClientGrpc,
) {}

서비스 초기화

모듈 초기화 시점에 gRPC 기반의 OrderService를 가져옵니다.

onModuleInit() {
  this.orderService =
    this.orderMicroservice.getService<OrderMicroservice.OrderServiceClient>(
      'OrderService',
    );
}

 

 

3. 결제 알림 전송 로직

NotificationService는 결제 완료 후 사용자에게 이메일 알림을 보내고, 주문 서비스에 배송 시작 이벤트를 알립니다.

async sendPaymentNotification(data: SendPaymentNotificationDto) {
  // 1. 알림 생성 (DB 저장)
  const notification = await this.createNotifiction(data.to);

  // 2. 이메일 전송 (Mock)
  await this.sendEmail();

  // 3. 알림 상태 업데이트
  await this.updateNotificationStatus(
    notification._id.toString(),
    NotificationStatus.sent,
  );

  // 4. 배송 시작 메시지 전송 (gRPC 기반)
  this.sendDeliveryStartedMessage(data.orderId);

  return this.notificationModel.findById(notification._id);
}

 

 

4. gRPC 기반 주문 서비스 호출

핵심 변경점은 주문 서비스로 배송 시작 메시지를 보낼 때 gRPC 메서드 호출을 사용한다는 점입니다.

sendDeliveryStartedMessage(id: string) {
  this.orderService.deliveryStarted({ id });
}

기존 메시지 큐 기반 emit을 제거하고, proto에서 정의된 deliveryStarted RPC 메서드를 호출하도록 변경했습니다. 이를 통해 서비스 간 명확한 계약과 응답 타입을 보장할 수 있습니다.

 

 

5. 부가 기능들

알림 상태 업데이트

알림의 상태를 pending → sent로 갱신합니다.

async updateNotificationStatus(id: string, status: NotificationStatus) {
  return await this.notificationModel.findByIdAndUpdate(id, { status });
}

이메일 전송 시뮬레이션

실제 메일 서버를 붙이지 않고 1초 대기 후 완료 처리합니다.

async sendEmail() {
  await new Promise((resolve) => setTimeout(resolve, 1000));
}

알림 생성

MongoDB에 알림 문서를 생성합니다.

async createNotifiction(to: string) {
  return this.notificationModel.create({
    from: 'test@gmail.com',
    to: to,
    subject: '배송이 시작됐습니다.',
    content: `${to}님! 주문하신 물건이 배송이 시작됐습니다!`,
  });
}

 

6. 정리

이번 작업으로 NotificationMicroservice는 gRPC 기반으로 전환되었으며, 다음과 같은 장점을 확보했습니다:

  • 서비스 간 명확한 계약 보장 (proto 기반)

  • 더 빠른 통신 속도 (HTTP/2 기반)

  • 결제 → 알림 → 주문 서비스로 이어지는 프로세스가 더욱 견고해짐

 

 

 

about author

PHRASE

Level 60  라이트

자신은 할 수 없다고 생각하고 있는 동안은 그것을 하기 싫다고 다짐하고 있는 것이다. 그러므로 그것은 실행되지 않는 것이다. -스피노자

댓글 ( 0)

댓글 남기기

작성