[NestJS]내장된 기능 활용해 마이크로서비스 구현하기 - 1. 개요 |
[NestJS]내장된 기능 활용해 마이크로서비스 구현하기 - 2. TCP |
[NestJS]내장된기능활용해마이크로서비스구현하기 - 3. MQTT |
[NestJS]내장된 기능 활용해 마이크로서비스 구현하기 - 4. Kafka |
저는 예전에 nest js를 이용한 MSA(마이크로서비스 아키텍처)를 구현하기 위해 nginx를 API Gateway처럼 사용하고, nginx에 들어온 요청을 여러 nest js로 프록시했습니다. 이때 nest js로 이뤄진 마이크로 서비스 간 통신은 전혀 하지 않아서, 이에 대해 고민을 하지 못했습니다. 하지만 더 다양한 기능을 개발하려다 보니 이러한 마이크로 서비스 간 통신도 불가피한 상황이 생겼습니다. 이때 마이크로 서비스 간 통신을 기본적인 HTTP 프로토콜을 이용한 REST API 호출방식을 사용하는 것은 비효율적이지 않나?라는 의심이 생겼고, 이에 대한 조사를 하던 중 NestJS 공식 홈페이지에 설명된 nest js에서 기본으로 제공되는 마이크로 서비스를 위한 기능이 있다는 사실을 알게 되었습니다. 그래서 오늘은 이 내용에 대해 소개해보려 합니다.
Documentation | NestJS - A progressive Node.js framework
Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Rea
docs.nestjs.com
마이크로서비스 간 통신 종류
NestJS에서는 기본적으로 마이크로서비스 간 통신에 TCP 프로토콜을 사용합니다. (예상대로 HTTP 프로토콜은 사용하지 않았습니다) 이외에도 자신이 원하는 프로토콜로 커스텀할 수 있습니다. 그런데 왜 HTTP 프로토콜은 사용하지 않을까요? 이유는 간단합니다. HTTP 프로토콜보다 TCP 프로토콜이 더 빠른 프로토콜이기 때문입니다. 이때 상황에 따라 더 빠른 방식이 존재하기도 합니다. NestJS에서는 이렇게 다양한 마이크로서비스 간 통신 방법 및 프로토콜을 여러 개 제공합니다.
아래는 nest js에서 사용할 수 있는 마이크로서비스 간 통신 프로토콜들입니다.
- TCP
- Redis
- MQTT
- NATS
- RabbitMQ
- Kafka
- gRPC
(Redis(인메모리 데이터 저장소이지만 메시지 큐 기능 사용가능), RabbitMQ, Kafka는 MSA 구조에서 흔하게 사용되는 메시지 큐 시스템입니다. 메시지 큐 시스템이 더 궁금하다면? --> https://sparkit.tistory.com/17)
위 마이크로서비스 간 통신을 구현하는 방식은 두 가지로 나뉩니다. request-response 방식과 event-based 방식입니다.
1) request-response message style
클라이언트가 요청을 보내면, 요청을 받은 마이크로서비스가 응답을 반환하는 방식입니다. 이는 동기적으로 이뤄지는 방식입니다.
2) event-based message style
이벤트가 발생하면 클라이언트가 이를 발행합니다. 그리고 마이크로서비스가 이를 구독하여 이벤트 발생을 감지하고 원하는 작업을 처리하는 방식입니다. 이는 비동기적으로 이뤄지는 방식입니다.
설치
NestJS에서 마이크로서비스를 이용하기 위해서는 아래 패키지를 다운로드 합니다.
npm i --save @nestjs/microservices
기본설정
마이크로서비스(only)
해당 서버를 마이크로서비스로 설정하기 위해서는 아래와 같이 설정합니다.(아래 코드는 NestJS 공식 홈페이지 상 예시 코드입니다)
# main.ts
import { NestFactory } from '@nestjs/core';
import { Transport, MicroserviceOptions } from '@nestjs/microservices';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.createMicroservice<MicroserviceOptions>(
AppModule,
{
transport: Transport.TCP,
},
);
await app.listen();
}
bootstrap();
이때 주의할 점이 있습니다. 저는 로컬에서 각 서버를 도커 컨테이너로 띄우고 이를 도커 컴포즈로 묶어서 실행하는 방식으로 위 코드를 이용해 실습을 해보았는데요. 마이크로서비스에 connect ECONNREFUSED 에러가 나면서 연결이 되지 않았습니다. 그 이유는 바로 options를 설정하지 않아서입니다. 더 정확히 말하면 기본적으로 마이크로서비스 요청은 localhost로 보내고 port는 정해주지 않으면 기본값이 없습니다. 그러므로 외부에서 접근할 수 있게 하기 위해서는 아래와 같이 options 설정을 마무리해줘야 합니다.
# main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';
async function bootstrap() {
const app = await NestFactory.createMicroservice<MicroserviceOptions>(
AppModule, {
transport: Transport.TCP,
options: {
host: '해당 도커 컨테이너명',
port: '원하는 포트',
},
});
await app.listen();
}
bootstrap();
저는 options를 정확히 설정하지 않아서 계속 ERROR [ExceptionsHandler] connect ECONNREFUSED 아이피값:포트값 이런 에러가 계속 나서 고생했었습니다...
마이크로서비스 + HTTP 프로토콜
기본적으로 마이크로서비스는 HTTP 프로토콜을 사용하지 않는다고 했습니다. 그래서 마이크로서비스로 설정하면 설정에 맞는 프로토콜만 사용할 수 있습니다. 예를 들어, TCP 프로토콜을 사용하는 마이크로서비스를 생성하면 HTTP 프로토콜은 사용할 수 없습니다. 하지만 HTTP 프로토콜도 사용하고 TCP 프로토콜 같은 마이크로서비스 간 통신을 위한 프로토콜을 같이 사용하고 싶을 수도 있습니다. 그럴 경우 아래와 같이 두 프로토콜을 같이 사용하는 서버를 설정할 수 있습니다.
# main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// 마이크로서비스를 TCP 포트 3001에서 연결
app.connectMicroservice({
transport: Transport.TCP,
options: {
port: 3001,
},
});
// 모든 마이크로서비스 시작
await app.startAllMicroservices();
// HTTP 서버를 포트 3000에서 시작
await app.listen(3000);
}
bootstrap();
다음 글부터는 각 프로토콜별 구현 코드에 대해 자세히 알아보겠습니다.
'백엔드 > NestJS' 카테고리의 다른 글
[NestJS] 컨트롤러에서 브레이크 포인트 안 걸릴 때 체크해야할 것들! ( 동적 경로, 정적 경로, route parameter ) (0) | 2024.11.25 |
---|---|
[NestJS]Jest를 이용해 테스트하자 - 1. 유닛 테스트(Unit Testing) (0) | 2024.11.12 |
[NestJS]내장된 기능 활용해 마이크로서비스 구현하기 - 4. Kafka (0) | 2024.11.04 |
[NestJS]내장된 기능 활용해 마이크로서비스 구현하기 - 3. MQTT (0) | 2024.11.04 |
[NestJS]내장된 기능 활용해 마이크로서비스 구현하기 - 2. TCP (0) | 2024.11.03 |