Series/스프링 마이크로서비스 코딩 공작소

스프링 마이크로서비스 코딩 공작소 (1)

Hyunec 2022. 10. 2. 01:54
 

GitHub - Hyune-s-lab/optima-growth: 스프링 마이크로서비스 코딩 공작소

스프링 마이크로서비스 코딩 공작소. Contribute to Hyune-s-lab/optima-growth development by creating an account on GitHub.

github.com

Phase 1 
3. 스프링 부트로 마이크로서비스 구축하기
4. 도커
이 글입니다.
Phase 2
5. 스프링 클라우드 컨피그 서버로 구성 관리
6. 서비스 디스커버리
https://hyune-c.tistory.com/54

 

새로 입사한 회사는 제가 생각한 것보다 훨씬 서비스 구분이 많았습니다.
솔직히 이렇게까지 세분화 해야되나? 라는 생각이 들 정도였습니다.
마이크로서비스는 잘 쓰면 높은 생산성과 장애 격리를 가져갈 수 있지만, 높은 설계/운영 난이도와 흐름 추적이 어렵기 때문입니다.
이 문제 때문에 전 회사에서는 api, batch 딱 2개의 서버만 운영하기도 했습니다.
그리고 굳이 바꾸려고 하지도 않았습니다. 스테이지와 어울리는 아키텍처였기 때문이죠.

하지만 전부터 공부하고 싶었던 마이크로서비스이기에 책을 한 권 따라가 보면서 기록해봅니다.
책에서는 java 11 과 maven 을 사용하지만, 이왕이면 최신으로! kotlin 과 gradle 로 따라가 봅니다.

이 시리즈는 책일 읽어가며 조금씩 작성됩니다.
어쩌면 책을 다 읽는 시점에는 지금의 생각과 달라질 수도 있겠네요. ㅎㅎ

필자의 배경 지식은 아래와 같습니다.

- 마이크로서비스의 이론만 조금 알고 있다.
- 간소화된 Saga Orchestration 을 구현해봤다.
- kotlin 연습만 해봤다. 비즈니스 개발 X
- 이미 구성된 Docker 환경을 사용/운영만 해봤다.

 

licensing-service 구현

라이센스 발급, 수정, 삭제를 위한 REST API 를 만들었습니다.
하지만 책과는 달리 국제화도 적용하지 않았고, 너무 쉽기에 따로 설명하지 않습니다.

 

docker-compose & boot script

알면 정말 쉽고 유용하지만, 모르면 손도 못 대는 docker 입니다.
전 회사에서는 팀장님이 구성한 세팅을 사용만 했지만 이제는 조금씩 알려고 합니다.

Dockerfile

# java 17을 사용합니다.
FROM openjdk:17-jdk-slim-buster
# build 를 통해 생성되는 jar 파일 경로를 JAR_FILE 변수를 지정합니다. 
ARG JAR_FILE=licensing-service/build/libs/*.jar
# jar 파일을 복사해 옵니다.
COPY ${JAR_FILE} app.jar
# 실행 합니다.
ENTRYPOINT ["java","-jar","/app.jar"]

docker 는 image 기반으로 작동합니다. 
Dockerfile 은 이 image 를 만들기 위한 환경 파일이라고 할 수 있습니다.

docker-compose.yml

version: "3"
services:
  license-service:
    image: license-service
    ports:
      - "8080:8080"

관련 설정을 매번 스크립트로 칠 필요 없이 yml 로 설정할 수 있습니다.
특히 여러 개의 서비스를 띄울 때 유용합니다.

run.sh

# licensing-service
cd licensing-service
./gradlew bootjar
cd ..

docker build . --tag license-service
docker-compose up

docker 를 띄우는 일련의 과정을 편하게 하기 위한 script 입니다.
git action 등을 사용할 때 활용하면 편합니다.

./run.sh

겨우 하나의 command 로 빌드부터 부팅에 성공했습니다!

생성된 image 를 보고 싶다면 확인해볼 수도 있습니다.

 

서비스 라우팅 & 서비스 디스커버리

처음 마이크로서비스를 접했을 때, 가장 크게 든 의문은 2개였습니다.

  • 내부 서비스 간에 어떻게 인증/인가를 하는 거지?
  • 서비스간 통신이 필요한 유스 케이스는 어떻게 처리하지?

이제는 실무를 하고 공부를 하면서 조금은 답이 생겼기에, 책의 내용과 함께 좀 더 얘기해보려고 합니다.

서비스 라우팅 (API 게이트웨이)

모놀리식 아키텍처에서는 접근 포인트가 단일 서버이기에 라우팅의 필요성이 낮았습니다.
과거에는 웹서버가 분리되기도 했지만, 현대에는 AWS 에서 ALB, Shield 등의 솔루션을 제공해주면서 분리된 이유도 있습니다.
하지만 마이크로서비스에서의 API 게이트웨이는 한 단계 더 나아갑니다.

책의 그림에는 인증에 대한 영역만 있지만, 전 회사에서는 SSO 를 고려한 인가까지를 구상했었습니다.
물론 인가까지 고려한다면 화면번호나 도메인 등의 서비스 디펜던시가 생길 수 있습니다.
하지만 각 서비스에서는 인가에 대한 부담을 덜 수 있어 더 좋은 아키텍처라고 생각합니다. (AWS IAM)

혹자는 서비스 간의 통신 시간을 고민합니다.
하지만 API 게이트웨이 이후는 private VPC 로 묶고 gRPC 등의 통신방식 변경으로 해결할 수 있다고 생각합니다.
현대의 개발은 더 많은 개발자가 더 많은 서비스를 병렬적으로 개발하는 것이 더 중요하기 때문입니다.

마지막으로 API 게이트웨이는 필연적으로 이 시스템에서 가장 많은 트래픽을 받게 되는 서비스입니다.
따라서 이벤트와 같이 일회성이거나 순간적 트랙픽이 몰리는 서비스는 분리하는 것도 좋다고 생각합니다.

 

서비스 디스커버리 (유레카)

이미 인증/인가가 끝난 요청을 포팅만 하는 쉬운 서비스라고 볼 수도 있지만, 헬스 체크와 서킷 브레이커의 아이디어가 필요할 것 같습니다. 그리고 비교적 자주 바뀌고 추가되는 개념인 end-point 를 유기적으로 관리할 수 있는 방법도 궁금해졌습니다.

 

마치며

첫 번째 글이라서 조금 짧습니다.
그래서 쓸까 말까 고민했지만, 하나의 큰 글보다 여러 개의 작은 글이 더 가치 있다고 생각하는 요즘입니다.

그리고 아키텍처를 고민하는 것은 항상 재미있다고 느끼는 요즘입니다.