NestJS

In NestJS's microservice, let it fix that cannot refer another microservice

kahnco 2023. 4. 2. 20:48

NestJS에서 MSA를 구현하다보면, 단순히 Client - Server 구조(https://kahnco.tistory.com/9)로 되어있는 프로젝트를 로컬 환경에서 돌리는 케이스는 별 에러없이 진행됩니다.

 

하지만, Client가 여러 개가 되고 각각의 Client가 Listen하고 있는 포트가 여러 개가 되면 Server(gRPC를 호출하는 쪽)에서 Client(gRPC를 제공하는 쪽)를 onModuleInit을 통해서 호출하고자 할때, override한 onModuleInit 함수가 정상적으로 호출되지 않는 문제가 있습니다.

 

// client-svc.service.ts
@Injectable()
export class ClientSvcService implements OnModuleInit {
  private logger = new Logger(ClientSvcService.name)

  private serverService: IServerService
  @Client(clientGrpcClientOptions) private readonly client: ClientGrpc
  onModuleInit(): any {
    this.logger.debug('ClientSvcService onModuleInit')
    this.serverService = this.client.getService<IServerService>('ServerService')
  }
}
import { NestFactory } from '@nestjs/core'
import { AppModule } from './app.module'
import { grpcClientOptions } from './options/user-grpc.option'

async function bootstrap() {
  const app = await NestFactory.create(AppModule)
  await app.connectMicroservice(grpcClientOptions)
  await app.startAllMicroservices()
}
bootstrap()

 

Server 쪽에서 Client가 제공하는 service를 참조해서 사용하려고 위처럼 코드를 작성하고 main.ts 파일을 entry point로 해서 돌려보아도 debug log가 제대로 찍히지 않는 것을 볼 수 있습니다.

 

[Nest] 1991  - 04/02/2023, 8:24:34 PM     LOG [NestFactory] Starting Nest application...
[Nest] 1991  - 04/02/2023, 8:24:34 PM     LOG [InstanceLoader] AppModule dependencies initialized +21ms
[Nest] 1991  - 04/02/2023, 8:24:34 PM     LOG [InstanceLoader] DatabaseModule dependencies initialized +0ms
[Nest] 1991  - 04/02/2023, 8:24:34 PM     LOG [InstanceLoader] TypeOrmModule dependencies initialized +0ms
[Nest] 1991  - 04/02/2023, 8:24:34 PM     LOG [InstanceLoader] ClientSvcModule dependencies initialized +0ms
[Nest] 1991  - 04/02/2023, 8:24:34 PM     LOG [InstanceLoader] TypeOrmCoreModule dependencies initialized +184ms
[Nest] 1991  - 04/02/2023, 8:24:34 PM     LOG [NestMicroservice] Nest microservice successfully started +40ms

 

문제를 해결하기 위해서 여러 방법을 시도해보았고, 공식 문서도 살펴보았으나 별다른 힌트를 얻지 못했습니다. 그러던 차에, 모든 Client 들이 동일한 기본 gRPC 포트 (50051)를 사용하고 있는 것을 발견했고, 혹시 하는 마음에 Client 쪽에서 제공하는 gRPC 포트를 수정한 이후에 Server 쪽에서 listen하고 있는 포트를 명시적으로 선언해주었습니다.

 

import { NestFactory } from '@nestjs/core'
import { AppModule } from './app.module'
import { grpcClientOptions } from './options/user-grpc.option'

async function bootstrap() {
  const app = await NestFactory.create(AppModule)
  await app.connectMicroservice(grpcClientOptions)
  await app.startAllMicroservices()
  await app.listen(process.env.GRPC_PORT || 50052)
}
bootstrap()

그러자, 정상적으로 Client의 Service를 참조할 수 있었습니다.

 

[Nest] 3008  - 04/02/2023, 8:42:23 PM     LOG [NestFactory] Starting Nest application...
[Nest] 3008  - 04/02/2023, 8:42:23 PM     LOG [InstanceLoader] AppModule dependencies initialized +21ms
[Nest] 3008  - 04/02/2023, 8:42:23 PM     LOG [InstanceLoader] DatabaseModule dependencies initialized +0ms
[Nest] 3008  - 04/02/2023, 8:42:23 PM     LOG [InstanceLoader] TypeOrmModule dependencies initialized +0ms
[Nest] 3008  - 04/02/2023, 8:42:23 PM     LOG [InstanceLoader] ClientSvcModule dependencies initialized +0ms
[Nest] 3008  - 04/02/2023, 8:42:23 PM     LOG [InstanceLoader] TypeOrmCoreModule dependencies initialized +218ms
[Nest] 3008  - 04/02/2023, 8:42:23 PM     LOG [InstanceLoader] TypeOrmModule dependencies initialized +1ms
[Nest] 3008  - 04/02/2023, 8:42:23 PM     LOG [NestMicroservice] Nest microservice successfully started +61ms
[Nest] 3008  - 04/02/2023, 8:42:23 PM     LOG [RoutesResolver] AppController {/}: +3ms
[Nest] 3008  - 04/02/2023, 8:42:23 PM   DEBUG [ClientSvcService] ClientSvcService onModuleInit
[Nest] 3008  - 04/02/2023, 8:42:23 PM     LOG [NestApplication] Nest application successfully started +13ms

 

정확한 내용은 확인할 수 없었지만, 제 추측으로는 MicroService를 bootstrap에서 구성하는 단게에서, 해당 gRPC 서비스를 제공하는 Client 측과 hand shake 비슷한 과정을 거치고 이 과정이 정상적으로 완료되어야지 Client 측의 Service를 정상적으로 참조하는 것으로 보입니다.

 

정확한 내용은 INestApplication의 microservice 쪽을 더 상세하게 파봐야 확인할 수 있을 것 같습니다.

추가적인 내용이 나오면 이 게시글에 덧붙이겠습니다.

반응형