ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • MSA) Spring Cloud Eureka에 FastAPI 서버를 Client로 등록하기
    SpringBoot 2024. 6. 1. 00:21

     

    들어가며

    저희 팀이 계획한 기획에서 python을 활용하여 데이터 분석과 여러 데이터들을 가져와야할 것 같아

    MSA 구조의 팀 프로젝트를 수행하기 전에, 연습하고 해당 내용을 기록하고자 글을 작성했습니다.

     

     

    Python 기반의 백엔드 프레임워크를 Flask를 쓸지 FastAPI를 쓸지는 정확히 확정이 되진 않았지만,

    Flask는 작은 프로젝트에서 다뤄본 경험이 있기도 하고 FastAPI가 좋다고들 하는데 사용해보지는 않아서

    배워볼겸 FastAPI로 진행하고자 합니다.

     

     

    적용한 내용을 보기 쉽게 그림으로 그려보았습니다.

    port 번호는 참고만해주세요!

     

     

     

    FastAPI를 설치하기 전에, 가상환경 세팅하기

    # 가상환경을 만들 디렉토리로 이동
    $ cd {directory}
    
    # 가상환경 만들기
    $ python3 -m venv {venv name}
    
    # 가상환경 활성화
    $ source {venv name}/bin/activate

     

    FastAPI 설치

    # fastapi 설치
    $ pip install fastapi
    
    # uvicorn 설치
    $ pip install uvicorn
    
    # py_eureka_client 설치
    $ pip install py_eureka_client

    uvicorn은 fastapi를 동작시키기 위해 필요한 라이브러리이며, 일반적으로 두 개를 같이 사용하게 됩니다.

    Eureka 서버에 해당 마이크로서비스를 client로 등록하기 위해서 py_eureka_client도 설치해줍니다.

     

     

    테스트 예제 구현 및 실행

    from fastapi import FastAPI
    from contextlib import asynccontextmanager
    import py_eureka_client.eureka_client as eureka_client
    import uvicorn
    import random
    
    port = random.randint(1024, 65535)
    
    @asynccontextmanager
    async def lifespan(app: FastAPI):
        await eureka_client.init_async(eureka_server="http://localhost:8761",
                                       app_name="analysis-service",
                                       instance_host="127.0.0.1",
                                       instance_port=port)
        yield
        await eureka_client.stop_async()
    
    app = FastAPI(lifespan=lifespan)
    
    @app.get("/")
    def health_check_handler():
        return {"status": "healthy"}
    
    if __name__ == "__main__":
        try:
            uvicorn.run(app, host="0.0.0.0", port=port)
        except KeyboardInterrupt:
            pass

     

    우선은 lifespan이라는 비동기 컨텍스트 매니저(@asynccontextmanager)를 정의했습니다.

    이 컨텍스트 매니저는 FastAPI 애플리케이션의 생명 주기 동안 실행되는데,

    애플리케이션이 시작되기 에 실행되어야 하는 코드를 정의하고

    애플리케이션이 종료될 때 실행되어야 하는 코드를 작업하는 역할을 합니다.

     

    lifespan에 대한 자세한 내용은 아래 링크를 참고해주시길 바랍니다!
    https://fastapi.tiangolo.com/advanced/events/

     

     

    그 안에 eureka_client.init_async() 함수는 비동기적으로 Eureka 서버에 서비스를 등록하는 역할을 합니다.

    • Eureka 서버의 주소(eureka_server)
    • 서비스의 이름(app_name)
    • 서비스가 호스트될 IP 주소(instance_host)
    • 서비스가 사용할 포트 번호(instance_port)

     

    마지막으로,

    eureka_client.stop_async() 함수를 사용하여 서비스 등록을 해제합니다.

    즉, 애플리케이션 종료 시 호출되어 서비스를 Eureka 서버에서 제거합니다.

     

    py-eureka-client의 자세한 내용은 아래 링크를 참고해주세요!
    https://github.com/keijack/python-eureka-client

     

     

    Spring Cloud Gateway Route 설정

    FastAPI로 만든 analysis-service를 apigateway 서버에 route 설정을 추가를 해줍니다.

    route 설정을 해주는 이유는

    클라이언트(사용자)가 각 서비스에 요청을 보내는 것이 아니라 API Gateway에게 요청을 보내고,

    API Gateway는 설정에 따라 해당 서비스에게 요청을 전달하고 응답을 받은 뒤

    해당 내용을 다시 클라이언트에게 전달하는

    단일 진입점 역할을 하기 때문입니다.

    spring:
      application:
        name: apigateway-server
      cloud:
        gateway:
          routes:
            - id: analysis-service
              uri: lb://ANALYSIS-SERVICE
              predicates:
                - Path=/analysis-service/**
              filters:
                - RewritePath=/analysis-service/(?<segment>.*), /$\{segment}

     

     

    결과 확인

    Eureka server를 구동하고, 등록되어 있는지 확인해보면

    아래와 같이 analysis-service가 잘 등록되어 있는걸 확인할 수 있습니다.

     

     

     

    이제 apigateway를 통해서 api 요청을 보내보겠습니다.

    apigateway의 port 번호는 8000번 이였고,

    아까 route 설정을 했기 때문에 저희가 실질적으로 요청 보낼 경로는 http://localhost:8000/analysis-service/ 입니다.

     

    현재 apigateway 서버에서 인증/인가 과정을 거치도록 구성해놓았기 때문에,

    user-service에서 로그인을 수행하고 나서 발급된 토큰을 가지고

    api 경로로 요청을 보내니

    성공적으로 응답을 하는 것을 확인할 수 있습니다!

     

    로그인 후 받은 access-token을 가지고 analysis-service로 api 요청

     

    가상환경 종료

    $ deactivate

     

     

     

    MSA 공부하면서 Spring Cloud Eureka와 연동하는 겸,

    FastAPI를 정말 맛보기로 사용해 봤는데

    빠르기도 빠르지만, Swagger를 별도로 세팅 안 해도

    기본으로 탑재되어 있는 점은 너무 매력적인 것 같습니다.

     

    제가 경험해 본 Flask는 날 것 그 자체였던 것에 반해....

     

     

     

     

     

Designed by Tistory.