본문 바로가기

정리/IT공부

[Python] 빠르게 Flask를 이용해 Microservice Architecture 구현

728x90

Flask를 사용하여 간단한 MSA(Microservices Architecture)를 구현하는 방법은 여러 가지가 있지만, 아래에서 저는 두 개의 간단한 마이크로서비스 예제를 보여주겠습니다. 이 예시에서는 "UserService"와 "OrderService"라는 두 개의 Restful  서비스를 구현하고자 했으며 "UserService"에서는 사용자 정보를 관리하고 "OrderService"에서는 주문 정보를 관리합니다. 설명에 앞서 목차를 보여드리겠습니다.

[목차]

1. MSA(Microservice Architecture)란?

2. Flask 를 이용한 Backend MSA 준

3. Flask 를 이용한 Backend MSA 구현 상세

 

1. MSA(Microservice Architecture)란?

마이크로서비스 아키텍처(MSA)는 복잡한 애플리케이션을 작은, 독립적으로 배포 가능한 서비스로 나누는 아키텍처 패턴입니다. 보편적인 MSA 구현에서 나타나는 특징은 다음과 같습니다:


- 독립적인 서비스:
각 서비스는 독립적으로 개발, 배포, 운영됩니다.
하나의 서비스의 장애가 다른 서비스에 영향을 미치지 않아야 합니다.

- API 기반 통신:
서비스 간 통신은 주로 API를 기반으로 합니다. RESTful API 또는 메시징 시스템을 사용합니다.
표준화된 데이터 포맷(일반적으로 JSON 또는 XML)을 사용하여 상호작용합니다.

- 자체 데이터 관리:
각 서비스는 자체 데이터베이스를 가지며, 데이터 관리는 서비스 내에서 이루어집니다.
서비스 간 데이터 공유는 API 호출을 통해 이루어집니다.

- 서비스 디스커버리:
서비스 디스커버리를 통해 각 서비스의 위치와 인스턴스를 자동으로 찾을 수 있습니다.
서비스 디스커버리는 서비스의 동적인 확장과 로드 밸런싱에 도움을 줍니다.

- 가상화 및 컨테이너 기반 배포:
서비스는 가상화 기술과 컨테이너 기반의 배포를 사용하여 독립적으로 실행됩니다.
Docker와 Kubernetes와 같은 도구를 통해 가상화 및 컨테이너 오케스트레이션을 구현합니다.

- 데브옵스(DevOps) 자동화:
CI/CD(Continuous Integration/Continuous Deployment) 파이프라인을 통해 자동화된 빌드, 배포, 테스트가 이루어집니다.
서비스의 빠른 배포와 업데이트가 가능하도록 합니다.

- 서비스 간 실패 처리:
회복성이 중요하며, 서비스 간의 통신이 실패할 경우를 대비한 실패 처리 및 재시도 전략을 수립합니다.
Circuit Breaker 패턴 등을 사용하여 시스템의 안정성을 유지합니다.

- 서비스 간 보안:
각 서비스는 자체적으로 보안을 갖추며, 인증 및 권한 부여를 통해 서비스 간의 보안을 유지합니다.
API 게이트웨이를 사용하여 보안 정책을 집중 관리할 수 있습니다.

등의 주요 특징을 가지고 있습니다.

 

2. Flask 를 이용한 Backend MSA 준비

구현에 앞서 다음의 라이브러리 두 개를 설치합니다.

pip install Flask Flask-Restful

참고로 Flask 라이브러리는 마이크로 웹 프레임워크로서, Jinja2 템플릿 엔진과 Werkzeug 웹 서버를 기반으로 하며, URL 라우팅, 플라스크 확장(extensions), 세션 관리, 플라스크 블루프린트(blueprint) 등을 지원합니다.

Flask-Restful  라이브러리는 RESTful API를 구축하기 위한 많은 편의 기능과 도구를 제공하여 개발자들이 API를 빠르게 구현할 수 있도록 도와줍니다. 여기서는 Resource 와 Api 클래를 사용하기 위해 해당 라이브러리를 사용하는데요.

Resource 클래스는 해당 리소스에 대한 CRUD(Create, Read, Update, Delete) 연산을 정의하며, 클라이언트의 HTTP 요청에 응답하는 메서드를 제공합니다. get, post, put, delete 가 각각의 CRUD에 해당합니다. 

- get(self, *args, **kwargs): 리소스의 정보를 조회하는 메서드. 일반적으로 읽기 작업에 사용됩니다.
- post(self, *args, **kwargs): 새로운 리소스를 생성하는 메서드. 데이터를 전송하여 새로운 엔터티를 만듭니다.
- put(self, *args, **kwargs): 기존 리소스를 업데이트하는 메서드. 전체 엔터티를 갱신합니다.
- delete(self, *args, **kwargs): 리소스를 삭제하는 메서드.

Api 클래스는 애플리케이션에 RESTful 엔드포인트를 추가하고, 이를 통해 리소스와 연결됩니다.Api를 통해 리소스를 등록하면, 해당 리소스가 클라이언트의 HTTP 요청에 대해 어떻게 동작할지 정의된 메서드를 호출합니다. add_resource 메서드는  RESTful API에 리소스를 등록하는 역할을 합니다. 

 

 

3. Flask 를 이용한 Backend MSA 구현 상세

UserService 코드 :

from flask import Flask
from flask_restful import Resource, Api

app = Flask(__name)
api = Api(app)

users = {}

class UserResource(Resource):
    def get(self, user_id):
        if user_id in users:
            return users[user_id]
        else:
            return {"message": "User not found"}, 404

    def put(self, user_id):
        users[user_id] = {"user_id": user_id, "name": "User " + user_id}
        return users[user_id], 201

api.add_resource(UserResource, '/user/<user_id>')

if __name__ == '__main__':
    app.run(port=5000)

OrderService 코드 : 

 
from flask import Flask
from flask_restful import Resource, Api

app = Flask(__name)
api = Api(app)

orders = {}

class OrderResource(Resource):
    def get(self, order_id):
        if order_id in orders:
            return orders[order_id]
        else:
            return {"message": "Order not found"}, 404

    def put(self, order_id):
        orders[order_id] = {"order_id": order_id, "product": "Product " + order_id}
        return orders[order_id], 201

api.add_resource(OrderResource, '/order/<order_id>')

if __name__ == '__main__':
    app.run(port=5001)

위의 코드에서 "UserService"와 "OrderService"는 각각 서로 다른 서비스로 실행됩니다. 두 서비스는 /user/<user_id> 및 /order/<order_id>와 같은 엔드포인트를 노출하며, 사용자 및 주문 정보를 관리합니다.

각 서비스는 특정 도메인(사용자 또는 주문)에 특화되어 있습니다. 이는 각 서비스가 특정 비즈니스 도메인을 관리하고 독립적으로 확장하고 업데이트할 수 있도록 합니다. 이러한 설계는 MSA의 핵심 원칙 중 일부를 보여주고 있으며, 각 서비스가 독립적으로 개발, 배포, 확장될 수 있도록 하는데 중점을 두고 있습니다.

이 예시는 매우 단순화되었으며, 실제 마이크로 서비스 아키텍처에서는 데이터베이스, 인증, 보안, 서비스 디스커버리, 로드 밸런싱 등을 포함해야 합니다. 또한 각 서비스 간의 통신 및 오류 처리를 추가로 구현해야 합니다.