DAY31

yejichoi·2022년 12월 18일
0
post-thumbnail

1. Algorithm Study

2. Backend Class

Microservice

모놀리식 아키텍처(Monolithic Architecture)

로그인, 파일 업로드, 결제 등 필요한 역할별로 개발을 하고, 개발이 완료되면 하나로 묶어서 배포

  • 단순하지만, 여러 모듈이 함께 있기 때문에 다른 부분에 영향을 줄 수가 있어 엉켜버리는 문제 발생

마이크로서비스 아키텍처(Microservice Architecture)

한 프로젝트를 여러 작은 서비스로 분리하여 개발하고 운영, 배포하는 방법 → 여러 모듈로 분리했기 때문에 팀별로 독립적으로 개발 가능 → 마이크로서비스로 분리하게 되면 어떠한 기능에 장애가 생겨도 해당 API만 사용이 불가능하고, 다른 기능에는 문제없이 서비스 운영 가능

  • 전체적인 기술 복잡도가 증가

마이크로서비스 파이프라인

인증/인가를 담당하는 auth API를 따로 분리하고, 나머지 부분을 resource로 분리


Nest기반 Rest-API의 마이크로서비스 분리

api-gateway, auth, resource 필요

//auth 폴더의 main.ts
import { NestFactory } from '@nestjs/core';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.createMicroservice<MicroserviceOptions>(
    AppModule,
    {
      transport: Transport.TCP, // 마이크로서비스는 기본적으로 TCP 레이어 사용,
      //네트워크 전송 계층 지정
      options: { host: 'auth-service', port: 3001 },
      //두번째 값으로는 host 이름과 port를 지정
    },
  );

  await app.listen();
}
bootstrap();
//resource 폴더의 main.ts
import { NestFactory } from '@nestjs/core';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.createMicroservice<MicroserviceOptions>(
    AppModule,
    {
      transport: Transport.TCP,
      options: { host: 'resource-service', port: 3002 },
    }, // 포트와 호스트이름 변경 
  );

  await app.listen();
}
bootstrap();
//auth 폴더의 app.controller.ts 파일에 login API
import { Controller } from '@nestjs/common';
import { AppService } from './app.service';
import { MessagePattern } from '@nestjs/microservices';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @MessagePattern({ cmd: 'login' })
  //메세지 패턴을 통해 gateway에서 각각의 API로 요청을 전달
  login(data) {
    console.log(data);
    return 'login 성공!!';
  }
}
//resource 폴더의 app.controller.ts 
import { Controller, Get } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @MessagePattern({ cmd22: 'fetchBoards' })
  fetchBoards(data) {
    console.log(data);
    return 'fetchBoards 게시글 데이터 보내주기';
  }
}
//api-gateway 폴더의 app.controller.ts
import { Controller, Get, Inject } from '@nestjs/common';
import { ClientProxy } from '@nestjs/microservices';

@Controller()
export class AppController {
  constructor(
    @Inject('AUTH_SERVICE') private readonly clientAuthService: ClientProxy,
    @Inject('RESOURCE_SERVICE')
    private readonly clientResourceService: ClientProxy,
  ) {}

  @Get('/auth/login')
  login() {
    return this.clientAuthService.send({ cmd: 'login' }, { name: '철수' });
  }//API에 넘겨줄 데이터 값이 있다면 두번째 인자로 지정

  @Get('boards')
  fetchBoards() {
    return this.clientResourceService.send({ cmd: 'fetchBoards' }, { age: 13 });
  }
}

Nest기반 GQL-API의 마이크로서비스 분리

// auth 폴더의 main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3001);
}
bootstrap();

Rest-API 파일 설정과는 다르게 GraphQL-API은 각각 독립적으로 움직이므로 별다른 설정 없이 각 서비스들의 포트번호 설정값만 변경

//api-gateway 폴더의 app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloGatewayDriver, ApolloGatewayDriverConfig } from '@nestjs/apollo';
import { IntrospectAndCompose } from '@apollo/gateway';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloGatewayDriverConfig>({
      driver: ApolloGatewayDriver,
      gateway: {
        supergraphSdl: new IntrospectAndCompose({
          subgraphs: [
            { name: 'auth', url: 'http://auth-service:3001/graphql' },
            { name: 'resource', url: 'http://resource-service:3002/graphql' },
          ],
        }),
      },
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Nest에서 GraphQL을 마이크로서비스로 분리하기 위해 Federation을 사용

//auth 폴더의 app.module.ts의  Federation을 사용
//resource 폴더의 app.module.ts의  Federation을 사용
import { Module } from '@nestjs/common';
// import { AppController } from './app.controller';
import { AppService } from './app.service';
import { GraphQLModule } from '@nestjs/graphql';
import { AppResolver } from './app.resolver';
import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      autoSchemaFile: 'src/commons/graphql/schema.gql',
    }),
  ],
  // controllers: [AppController],
  providers: [AppService, AppResolver],
})
export class AppModule {}

3. HW

0개의 댓글