JIGGAG

마이크로서비스 구축과 운영

2020년 8월 9일

MSA 최근에 서비스 설계를 시작하면 항상 생각하게되는 것이 있다. 처음 시작부터 모놀리식을할까 마이크로서비스로 가야할까.

서비스가 소규모라면 굳이 마이크로서비스를 선택하는게 작업이 많이 필요로 하기 때문에 무조건 마이크로서비스로 가는게 좋은건 아니라고 생각을 한다.

그럼에도 마이크로서비스로 가는길을 미리 알아두고 가면 좋지 않을까 생각하며 읽어보자.

마이크로서비스

마이크로서비스를 선택하면 확장성이 높아지고 신기술로 개발할 수 있다는 것이 큰 장점이라고 생각한다. 그러나 신기술을 선택하면서 기존의 서비스와는 다른 기술부채나 서비스 별 나뉘는 조직 구조, 각각의 서비스를 운영해야하는 비용과 신뢰도가 낮아지는것을 보완해야한다.

이 책에서는 각각의 마이크로서비스의 엔드포인트를 연결하고 요청/응답의 흐름과 서로 의존성을 확인해보면 장애가 예상되는 지점을 찾을 수 있고 이런 부분들을 보완하고자 8가지 항목(안정성, 신뢰, 확장, 내결항성, 성능, 모니터링, 문서화, 장애대비) 표준 원칙에 대한 내용을 전달하고 있다.

모놀리식 < 마이크로서비스

새로운 기술을 사용해볼 수 있고 모놀리식보다 상대적으로 작은 규모로 설계되어있어 확장이 용이하고 개발과 배포를 효율적으로 진행할 수 있다는 장점이 있다.

다만 이런 장점들만을 생각하고 신기술만 사용한다거나 무분별한 확장을 하게 된다면 신뢰도가 낮아질 수 있으므로 표준을 정해두고 서비스의 확장을 진행해야한다.

[계층1] 하드웨어
[계층2] 통신
[계층3] 애플리케이션: 개발환경, 테스트, 빌드, 파이프라인, 모니터링, 로깅
[계층4] 마이크로서비스

하드웨어에서는 물리서버, 클라우드 임대, DB, OS, 호스트 수준의 모니터링과 로깅이 구축된다.

통신에서는 네트워크, API 엔드포인트, 메시징, 서비스 레지스트리와 디스커버리, 로드밸런싱으로 배분 라우팅이 구축되어 서비스간에 통신을 유지한다.

애플리케이션은 내부적인 개발 도구로써 개발 환경을 설정하고 테스트, 빌드, 파이프라인과 로그 모니터링을 설정하면서 마이크로서비스가 구축된다.

준비 단계

서비스가 정상적으로 작동한 시간 대비 장애 발생으로 작동하지 않은 시간으로 가용성을 구할 수 있다.

만약 100시간 운영한 서비스에서 99%의 가용성과 99.9%의 가용성은 1시간동안 장애가 발생한 서비스와 6분동안 장애가 발생한 서비스가 있다면 너무나 큰 시간차이로 느껴진다. 어? 왜 이래?하면서 조금 기다렸다가 다시 요청하고 정상 작동한다면 사용자 입장에서는 6분이라는 시간은 잠깐이라고 느낄 수 있지만 1시간동안 서비스가 응답이 없다면 막막하다.

위에서 이야기한 표준화를 위한 원칙 8가지 항목을 검토하면서 가용성을 높일 수 있도록 한다.

[안정성] 개발 사이클, 도입 절차
[신뢰성] 종속성, 장애 대비 계획
[확장성] 병목현상 파악, 확장 가능성, 트래픽 처리
[내결합성] 장애 대비, 테스트
[성능] 효율적인 서비스 자원 활용
[모니터링] 자원 사용률, 요청/응답/API 엔드포인트 상태, 오류 로그
[문서화] 의사소통, 기술부채 최소화

마이크로서비스의 장점인 자율성과 개발 속도, 생산성은 표준화된 항목들이 지켜졌을때 최대치로 주어진다.

안정과 신뢰

개발 사이클(개발 -> 스테이징 -> 카나리아 -> 프로덕션)을 통해 서비스의 안정성을 확인하고 배포하게 된다. 개발이 완료된 후 운영과 동일한 환경의 스테이징 상태에서 1차적으로 테스트 해본 후 5~10% 정도 부분적으로 운영에 배포하는 카나리아도 통과한다면 이 정도면 안정적이다 자신감을 가지고 완전한 배포를 할 수 있다.

만약 운영에 배포한 이후 오류가 발생했을때 핫픽스로 빠르게 오류를 수정하는 것보다는 안정적이였던 버전으로 롤백하는게 더 좋은 선택이 될 수 있다.

서비스 종속성에 대하여 가용성이 낮은 종속성을 장애가 발생했을 경우를 대비해 캐시해둔다면 장애 발생 시 연달아서 장애가 나타나는 것을 방지할 수 있다.

또한 API 엔드포인트가 정상적인 서비스에 연결되어 있는지 확인하기 위해 /health를 정기적으로 호출하거나 테스트, CI 등 관리를 통해 안정성과 신뢰도를 높일 수 있다.

확장과 성능

성장 규모를 파악하고 자원을 효율적으로 사용하여 성능을 높인다. (예를들어 CPU를 많이 사용하고 있는 서비스에 RAM만 확장한다고 성능이 높아지지는 않으니깐...)

확장이 간단하려면 서비스간에 의존성이 낮게 구성하고 트래픽 모니터링을 통해 서비스가 갑자기 중단되지 않도록 확장시기를 관리한다.

또한 데이터베이스도 확장을 준비해야하는데 그동안 서로 관계가 돈독한 RDBMS(MySQL)만 사용해왔으나 서비스 유형에 따라 NoSQL을 선택하는게 확장성이 좋을 수도 있다. 확장이 용이하려면 서로 관계를 낮추는게 좋을 것 같다.

내결합성과 장애대비

서비스가 종속되어있다면 A에서 장애가 발생한 경우 이에 종속된 B와 C에서도 장애가 연달아 발생하게 된다. 실제 장애는 A에서만 발생했을뿐인데 B와 C에서는 정상 작동하도록 아키텍처를 설계하고 개발 과정에서 장애 발생 지점을 예측하여 대비하여야한다.

결론

읽다보니 이건 마이크로서비스에만 적용되는 것이 아니라 모든 서비스에 표준화된 내용이지 않을까 생각된다. 다만 모놀리식에서는 이러한 것들이 하나만 챙기면 되었지만 마이크로서비스에서는 여러개 서비스에서 각각 챙겨줘야하는 것이기에 이러한 표준화된 내용으로 명시해주는 것 같다.

보통 마이크로서비스로 구축하게 될 정도라면 각각의 서비스별로 조직이 구성되게 될텐데 이때 조직과 조직 사이에 공통되는 부분들은 최대한으로 구성하고 서로에게 각각의 뉴스를 전달하는게 가장 큰 표준화 원칙이 될 것 같다. 이걸 써봤는데 소소하더라, 이런거 같이 공유하면 좋을 것 같아요

(최근에 무인 도서 대여 서비스를 이용하는 도서함이 여유가 없는데, 이거야 말로 확장되어야 하지 않을까... 대여함 좀 늘려주세요)