본문 바로가기
Dart/Dart Server

[고급] Dart 서버 마이크로서비스 아키텍처 / 마이크로서비스 개념과 Dart의 적용 가능성

by Maccrey Coding 2024. 9. 14.
728x90
반응형

 

현대 소프트웨어 아키텍처의 핵심 트렌드 중 하나는 마이크로서비스(Microservices)입니다.

여러 대형 IT 기업이 이 아키텍처를 통해 시스템 확장성과 유지보수성을 크게 향상시켰습니다.

이 글에서는 마이크로서비스의 개념Dart로 이를 어떻게 구현할 수 있는지 설명하여, 초보 개발자들도 쉽게 이해할 수 있도록 안내합니다.

1. 마이크로서비스(Microservices)란?

마이크로서비스는 소프트웨어 개발에서 작고 독립적인 서비스들로 시스템을 구성하는 아키텍처입니다.

각 서비스는 독립적으로 배포, 관리, 확장할 수 있으며, 다른 서비스와는 최소한의 연결을 유지합니다.

 

마이크로서비스의 주요 특징

  • 독립성: 각 서비스는 고유한 기능을 담당하며, 독립적으로 개발되고 배포됩니다.
  • 분산 아키텍처: 여러 개의 서비스가 네트워크를 통해 통신하며, 분산된 환경에서 작동합니다.
  • 개발 속도 향상: 작은 단위로 나누어져 있기 때문에 여러 개발 팀이 동시에 작업할 수 있습니다.
  • 유지보수 용이: 문제가 발생한 특정 서비스만 수정하면 되므로, 전체 시스템에 영향을 미치지 않습니다.

2. 마이크로서비스의 장점과 단점

장점

  • 확장성: 특정 기능에 대한 트래픽이 증가하면 그 기능만 확장하여 처리할 수 있습니다.
  • 유지보수 용이: 작은 서비스 단위로 나누어져 있어 각 서비스의 복잡도가 낮습니다.
  • 기술 선택의 유연성: 각 마이크로서비스는 서로 다른 기술 스택을 사용할 수 있어 최적화된 기술을 선택할 수 있습니다.

단점

  • 복잡한 네트워크 관리: 서비스 간의 통신이 많아지면서 네트워크 관리가 복잡해질 수 있습니다.
  • 데이터 일관성 문제: 여러 서비스가 분산되어 있어 데이터 일관성을 유지하는 데 어려움이 있을 수 있습니다.
  • 배포 및 운영 복잡도: 많은 서비스가 각각 배포되고 모니터링되므로, 배포와 운영 관리가 복잡해질 수 있습니다.

3. Dart와 마이크로서비스

Dart는 웹과 서버 개발에 적합한 언어로, 특히 Flutter를 통해 모바일 및 웹 애플리케이션 개발에서 널리 사용되고 있습니다.

Dart는 서버 측 개발에도 충분히 적합하며, 마이크로서비스 아키텍처에서도 활용할 수 있습니다.

Dart의 장점

  • 경량성: Dart는 빠르고 가벼운 런타임을 제공하여, 마이크로서비스와 같은 작은 서비스에서 이상적입니다.
  • 강력한 비동기 프로그래밍 지원: Dart의 async와 await는 비동기 작업을 쉽게 처리할 수 있어, 마이크로서비스의 병렬 작업 처리에 적합합니다.
  • 모듈화: Dart는 패키지 관리가 용이하여, 마이크로서비스의 각 구성 요소를 독립적으로 관리할 수 있습니다.

4. Dart로 마이크로서비스 구현하기

Dart에서 마이크로서비스를 구현하기 위해 두 가지 주요 프레임워크를 사용할 수 있습니다: **Shelf**와 Aqueduct. 아래에서는 각각의 프레임워크를 사용하여 마이크로서비스를 구현하는 방법을 소개합니다.

4.1 Shelf 프레임워크

Shelf는 Dart의 기본 HTTP 서버 프레임워크로, 매우 간단하게 RESTful API를 구축할 수 있습니다.

Shelf로 간단한 마이크로서비스 구축 예제

 

1. pubspec.yaml 파일 설정

먼저, pubspec.yaml 파일에 shelf 패키지를 추가합니다.

dependencies:
  shelf: ^1.2.0
  shelf_router: ^1.3.0

 

2. 서버 코드 작성

다음으로, lib/server.dart 파일을 만들어 서버 코드를 작성합니다.

import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as io;

// 요청을 처리할 핸들러 함수
Response _echoRequest(Request request) =>
    Response.ok('마이크로서비스에서 받은 요청: ${request.url}');

// 메인 함수: 서버 시작
void main() async {
  // 파이프라인을 통해 요청을 로깅하고 핸들러에 전달
  var handler = const Pipeline()
      .addMiddleware(logRequests())
      .addHandler(_echoRequest);

  // 서버를 localhost의 8080 포트에서 실행
  var server = await io.serve(handler, 'localhost', 8080);
  print('서버가 실행 중입니다. http://${server.address.host}:${server.port}');
}

 

  • import 'package:shelf/shelf.dart';: shelf 패키지를 가져와 HTTP 서버를 구축할 수 있게 합니다.
  • Response _echoRequest(Request request): 요청을 처리하고 응답을 반환하는 함수입니다. 요청의 URL을 포함한 응답 메시지를 반환합니다.
  • void main() async {}: 비동기 main 함수로 서버를 시작합니다.
  • Pipeline: 요청을 처리하기 위한 미들웨어를 정의합니다. 여기서는 logRequests() 미들웨어를 추가하여 요청 로그를 기록합니다.
  • io.serve(): 서버를 시작하고, localhost와 8080 포트에서 요청을 받습니다.

3.2 Aqueduct 프레임워크

Aqueduct는 좀 더 기능이 풍부한 프레임워크로, 데이터베이스 연동과 같은 고급 기능을 지원합니다.

Aqueduct로 API 구축 예제

 

1. pubspec.yaml 파일 설정

Aqueduct 패키지를 추가합니다.

dependencies:
  aqueduct: ^3.3.0

 

2. API 코드 작성

lib/channel.dart 파일에 API 코드를 작성합니다.

import 'package:aqueduct/aqueduct.dart';

class HelloWorldController extends ResourceController {
  @Operation.get()
  Future<Response> getHelloWorld() async {
    return Response.ok({"message": "안녕하세요, 마이크로서비스입니다!"});
  }
}

class HelloWorldChannel extends ApplicationChannel {
  @override
  Controller get entryPoint {
    final router = Router();
    router.route("/hello").link(() => HelloWorldController());
    return router;
  }
}

 

  • import 'package:aqueduct/aqueduct.dart';: Aqueduct 패키지를 가져와 서버와 API를 설정합니다.
  • class HelloWorldController extends ResourceController: ResourceController를 상속받아 API 요청을 처리할 컨트롤러를 정의합니다.
  • @Operation.get(): HTTP GET 요청을 처리하는 메서드를 정의합니다.
  • Response.ok({"message": "안녕하세요, 마이크로서비스입니다!"}): JSON 형식의 응답 메시지를 반환합니다.
  • class HelloWorldChannel extends ApplicationChannel: 애플리케이션의 진입점을 정의하는 클래스입니다.
  • Router(): 경로와 핸들러를 설정합니다. /hello 경로에 대한 요청을 HelloWorldController로 연결합니다.

5. Dart 마이크로서비스의 실용적 적용

Dart로 구현된 마이크로서비스는 다양한 클라우드 서비스컨테이너화 기술을 활용하여 배포할 수 있습니다. Docker와 같은 도구를 사용하면, 각 마이크로서비스를 독립적으로 관리하고 배포할 수 있어 효율적입니다.

Docker 예제

Dockerfile을 사용하여 Dart 마이크로서비스를 컨테이너화할 수 있습니다.

1. Dockerfile 작성

# Dart SDK가 포함된 이미지 사용
FROM dart:stable

# 작업 디렉토리 설정
WORKDIR /app

# 프로젝트 파일 복사
COPY . .

# 의존성 설치
RUN dart pub get

# 서버 실행
CMD ["dart", "run", "bin/server.dart"]

 

  • FROM dart:stable: Dart의 안정적인 버전이 포함된 Docker 이미지를 사용합니다.
  • WORKDIR /app: 작업 디렉토리를 /app으로 설정합니다.
  • COPY . .: 현재 디렉토리의 모든 파일을 컨테이너의 /app 디렉토리로 복사합니다.
  • RUN dart pub get: Dart의 의존성을 설치합니다.
  • CMD ["dart", "run", "bin/server.dart"]: 컨테이너가 시작될 때 Dart 서버를 실행합니다.

Dart는 마이크로서비스 아키텍처를 구현하기 위한 강력한 도구입니다.

Shelf와 Aqueduct와 같은 프레임워크를 사용하면, Dart로도 복잡한 서버 사이드 애플리케이션을 구축할 수 있습니다.

Dart의 비동기 처리 능력과 경량성은 마이크로서비스 아키텍처에서 특히 유용하며, 클라이언트와 서버 간의 코드 일관성도 유지할 수 있습니다.


이 블로그에서 소개한 개념과 예제를 통해, Dart로 마이크로서비스를 구축하는 데 필요한 기본적인 이해를 돕기를 바랍니다.

 

구독!! 공감과 댓글은 저에게 큰 힘이 됩니다.

Starting Google Play App Distribution! "Tester Share" for Recruiting 20 Testers for a Closed Test.

 

Tester Share [테스터쉐어] - Google Play 앱

Tester Share로 Google Play 앱 등록을 단순화하세요.

play.google.com

 

 

728x90
반응형