study/λ°±μ—”λ“œ

πŸ“Œ NestJS + Kubernetes & λ§ˆμ΄ν¬λ‘œμ„œλΉ„μŠ€ 배포: μ‹€μ „ κ°€μ΄λ“œ - NestJS μ‹€μ‹œκ°„ κΈ°λŠ₯ 섀계: WebSocket + GraphQL Subscriptions

octo54 2025. 4. 10. 10:41
λ°˜μ‘ν˜•

πŸ“Œ NestJS + Kubernetes & λ§ˆμ΄ν¬λ‘œμ„œλΉ„μŠ€ 배포: μ‹€μ „ κ°€μ΄λ“œ

9. NestJS μ‹€μ‹œκ°„ κΈ°λŠ₯ 섀계: WebSocket + GraphQL Subscriptions


ν˜„λŒ€ μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œλŠ” μ‹€μ‹œκ°„ 데이터 μ²˜λ¦¬κ°€ ν•„μˆ˜κ°€ λ˜μ—ˆμŠ΅λ‹ˆλ‹€.
NestJSλŠ” WebSocket, GraphQL Subscriptions, Redis Pub/Sub 등을 톡해 λ‹€μ–‘ν•œ μ‹€μ‹œκ°„ κΈ°λŠ₯을 μ†μ‰½κ²Œ κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
이번 κΈ€μ—μ„œλŠ” NestJSμ—μ„œ μ‹€μ‹œκ°„ μ±„νŒ…, μ•Œλ¦Ό, λŒ€μ‹œλ³΄λ“œ μ—…λ°μ΄νŠΈμ™€ 같은 κΈ°λŠ₯을 κ΅¬μΆ•ν•˜κΈ° μœ„ν•œ μ‹€μ „ μ „λž΅μ„ μ†Œκ°œν•©λ‹ˆλ‹€. πŸš€


βœ… 1. μ‹€μ‹œκ°„ κΈ°λŠ₯이 ν•„μš”ν•œ 이유

  • μ‹€μ‹œκ°„ μ±„νŒ…, ν˜‘μ—… 툴, κ²Œμž„
  • λŒ€μ‹œλ³΄λ“œ μ§€ν‘œ μžλ™ κ°±μ‹ 
  • μ‹€μ‹œκ°„ μ•Œλ¦Ό(Notification) κΈ°λŠ₯
  • IoT λ””λ°”μ΄μŠ€ μƒνƒœ λͺ¨λ‹ˆν„°λ§

πŸ’‘ REST APIλŠ” ν΄λΌμ΄μ–ΈνŠΈκ°€ 주기적으둜 pollingν•΄μ•Ό ν•˜λ―€λ‘œ λΉ„νš¨μœ¨μ 
→ WebSocket or Subscription 기반의 push ꡬ쑰둜 κ°œμ„  ν•„μš”


βœ… 2. NestJSμ—μ„œ μ§€μ›ν•˜λŠ” μ‹€μ‹œκ°„ 기술

기술 μ„€λͺ… μž₯점

WebSocket (Socket.IO) μ–‘λ°©ν–₯ 톡신, ν΄λΌμ΄μ–ΈνŠΈ ↔ μ„œλ²„ 직접 μ—°κ²° κ°„λ‹¨ν•˜κ³  빠름
GraphQL Subscriptions GraphQL 기반 μ‹€μ‹œκ°„ 데이터 슀트림 GraphQL API와 톡합 용이
Redis Pub/Sub 닀쀑 μΈμŠ€ν„΄μŠ€ κ°„ λ©”μ‹œμ§€ λΈŒλ‘œλ“œμΊμŠ€νŠΈ μŠ€μΌ€μΌμ•„μ›ƒμ— 유리

βœ… 3. WebSocket (Socket.IO) 기반 μ‹€μ‹œκ°„ 톡신

βœ… 1) μ„€μΉ˜ 및 μ„€μ •

npm install @nestjs/websockets @nestjs/platform-socket.io

πŸ“‚ chat.gateway.ts

@WebSocketGateway({ cors: true })
export class ChatGateway {
  @WebSocketServer() server: Server;

  @SubscribeMessage('chat')
  handleChat(@MessageBody() msg: string): void {
    this.server.emit('chat', msg);
  }
}

βœ… 2) ν΄λΌμ΄μ–ΈνŠΈ 예제 (HTML + JS)

<script src="/socket.io/socket.io.js"></script>
<script>
  const socket = io('http://localhost:3000');
  socket.emit('chat', 'μ•ˆλ…•ν•˜μ„Έμš”!');
  socket.on('chat', msg => console.log('λ©”μ‹œμ§€:', msg));
</script>

βœ… 4. GraphQL Subscriptions 기반 μ‹€μ‹œκ°„ 섀계

βœ… 1) μ„€μΉ˜

npm install @nestjs/graphql graphql graphql-subscriptions graphql-ws

βœ… 2) μ„€μ •

πŸ“‚ app.module.ts

GraphQLModule.forRoot({
  autoSchemaFile: true,
  subscriptions: {
    'graphql-ws': true,
  },
})

βœ… 3) μ‹€μ‹œκ°„ μ•Œλ¦Ό 예제

πŸ“‚ notifications.resolver.ts

@Resolver()
export class NotificationResolver {
  constructor(@Inject('PUB_SUB') private pubSub: PubSub) {}

  @Mutation(() => String)
  sendNotification(): string {
    this.pubSub.publish('notificationAdded', {
      notificationAdded: 'μƒˆλ‘œμš΄ μ•Œλ¦Ό!',
    });
    return '보냄';
  }

  @Subscription(() => String)
  notificationAdded() {
    return this.pubSub.asyncIterator('notificationAdded');
  }
}

βœ… ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ subscription { notificationAdded } λ₯Ό κ΅¬λ…ν•˜λ©΄ μ„œλ²„μ—μ„œ μ•Œλ¦Ό push


βœ… 5. Redis 기반 Pub/Sub 섀계 (λ©€ν‹° μΈμŠ€ν„΄μŠ€ λŒ€μ‘)

πŸ“‚ pubsub.module.ts

const redisOptions = {
  host: 'localhost',
  port: 6379,
};

@Module({
  providers: [
    {
      provide: 'PUB_SUB',
      useFactory: () => new RedisPubSub({ connection: redisOptions }),
    },
  ],
  exports: ['PUB_SUB'],
})
export class PubSubModule {}

πŸ’‘ μ„œλ²„κ°€ μ—¬λŸ¬ 개일 λ•Œ, Redis Pub/Sub을 μ‚¬μš©ν•˜λ©΄ λ©”μ‹œμ§€λ₯Ό λͺ¨λ“  μΈμŠ€ν„΄μŠ€μ— λΈŒλ‘œλ“œμΊμŠ€νŠΈ κ°€λŠ₯!


βœ… 6. μ‹€μ „ κ΅¬ν˜„ μ‹œ 고렀사항

ν•­λͺ© λ‚΄μš©

인증 JWT λ˜λŠ” μ„Έμ…˜ 기반 인증 적용 (socket.handshake)
λ©”μ‹œμ§€ λ³΄μ•ˆ λ©”μ‹œμ§€ λ‚΄μš© μ•”ν˜Έν™” λ˜λŠ” κΆŒν•œ 검증 ν•„μš”
ν™•μž₯μ„± Redis Pub/Sub λ˜λŠ” Kafka ν™œμš©
μ—°κ²° 수 관리 WebSocket μ—°κ²° 수 λͺ¨λ‹ˆν„°λ§ + μ œν•œ 적용 (Rate Limit)
λŒ€μ²΄ μ „λž΅ polling fallback → 였래된 λΈŒλΌμš°μ € κ³ λ €

βœ… 7. μ‹€μ‹œκ°„ κΈ°λŠ₯ + Kubernetes 연동 팁

  • Ingress μ„€μ •: WebSocket μ‚¬μš© μ‹œ nginx.ingress.kubernetes.io/backend-protocol: "WS" μΆ”κ°€ ν•„μš”
  • Sticky Session: ν΄λŸ¬μŠ€ν„° ν™˜κ²½μ—μ„œ νŠΉμ • μ‚¬μš©μž μ—°κ²° μœ μ§€ ν•„μš” μ‹œ
  • Redis Pod 별도 운영: μ‹€μ‹œκ°„ λ©”μ‹œμ§•μ€ Redis μ˜μ‘΄λ„κ°€ λ†’μœΌλ―€λ‘œ λͺ¨λ‹ˆν„°λ§ μ€‘μš”

βœ… κ²°λ‘ : NestJS둜 μ‹€μ‹œκ°„ μ‹œμŠ€ν…œ 섀계 λ§ˆμŠ€ν„°ν•˜κΈ°

βœ… WebSocket을 ν™œμš©ν•œ μ‹€μ‹œκ°„ μ–‘λ°©ν–₯ 톡신
βœ… GraphQL Subscriptions둜 GraphQL API λ‚΄ μ‹€μ‹œκ°„ κΈ°λŠ₯ κ΅¬ν˜„
βœ… Redisλ₯Ό ν†΅ν•œ λΈŒλ‘œλ“œμΊμŠ€νŠΈ 및 μŠ€μΌ€μΌμ•„μ›ƒ
βœ… Kubernetesμ—μ„œλ„ μ‹€μ‹œκ°„ 톡신 μ•ˆμ •μ μœΌλ‘œ 운영 κ°€λŠ₯

λ‹€μŒ κΈ€μ—μ„œλŠ” NestJS ν”„λ‘œμ νŠΈμ—μ„œ κ΄€μ°°μ„±(Observability)을 λ†’μ΄λŠ” 방법 – OpenTelemetry, Distributed Tracing, 둜그 μˆ˜μ§‘ μ „λž΅μ„ λ‹€λ£Ήλ‹ˆλ‹€! πŸ”


πŸ” λ‹€μŒ κΈ€ 예고: NestJS Observability – 둜그, 좔적, μ§€ν‘œ 톡합 μ „λž΅

πŸ“Œ λ‹€μŒ 편: 10. NestJS Observability: 둜그, λͺ¨λ‹ˆν„°λ§, 좔적 톡합 κ°€μ΄λ“œ


 

NestJS WebSocket,NestJS μ‹€μ‹œκ°„ κΈ°λŠ₯,NestJS GraphQL Subscriptions,NestJS Redis PubSub,NestJS μ‹€μ‹œκ°„ μ±„νŒ…,NestJS μ•Œλ¦Ό κΈ°λŠ₯,NestJS μ†ŒμΌ“ μ„€μ •,NestJS μ‹€μ‹œκ°„ λŒ€μ‹œλ³΄λ“œ,NestJS μ„œλ²„ ν‘Έμ‹œ,NestJS μ‹€μ‹œκ°„ 톡μ‹