최근에 BFF에 대해서 공부를 해 보아야 할 필요성을 느껴서 블로그에 정리해 보았다.
BFF에 대한 설명을 하기 전에 먼저 MSA에 대해서 이야기를 해 보려고 한다.
MSA
MSA는 작은 자율 서비스 컬렉션으로 구성된다. 각 서비스는 독립적이며 제한된 컨텍스트 내에서 단일 비즈니스 기능을 구현해야 한다. 제한된 컨텍스트는 비즈니스 내의 자연스러운 분할이며 도메인 모델이 존재하는 명시적 경계를 제공한다.
마이크로 서비스란 다음과 같은 특성을 가지고 있다.
- 작고, 독립적이며, 느슨하게 결합되어 있다.
- 각 서비스는 작은 개발팀이 관리할 수 있다.
- 서비스를 독립적으로 배포할 수 있다. 팀이 전체 어플리케이션을 빌드한 후 재배치하지 않고도 기존 서비스를 업데이트 할 수 있다.
- 서비스가 잘 정의된 API를 사용하여 서로 통신한다. 각 서비스의 내부 구현 정보는 다른 서비스에서 숨겨진다.
- 다중 저장소 프로그래밍을 지원한다. 예를 들어 서비스가 동일한 기술 스택, 라이브러리 또는 프레임워크를 공유할 필요가 없다.
서비스 자체 외에도 다음 구성 요소들이 기존 MSA에 나타난다.
- 관리/오케스트레이션 : 이 구성 요소는 노드에 서비스 배치, 실패 식별, 노드 간에 서비스 부하 조정 등의 작업을 담당한다. 일반적으로 이 구성요소는 사용자 지정 빌드가 아닌, 쿠버네티스 같은 기성 기술이다.
- API 게이트웨이 : API 게이트웨이는 클라이언트의 진입점이다. 클라이언트는 서비스를 직접 호출하는 대신, 호출을 백엔드의 적절한 서비스에 전달하는 API 게이트웨이를 호출한다.
- API 게이트웨이를 사용할 때 장점은 다음과 같다.
- 클라이언트와 서비스가 분리된다. 모든 클라이언트를 업데이트 하지 않고도 서비스 버전을 관리하거나 서비스를 리팩터링 할 수 있다.
- 서비스가 웹 우호적이 아닌 AMQP 등의 메시징 프로토콜을 사용할 수 있다.
- API 게이트웨이는 인증, 로깅, SSL 종료, 부하 분산 등의 다른 교차 기능을 수행할 수 있다.
- 제한, 캐싱, 변환, 또는 유효성 검사과 같은 즉시 사용 가능한 정책을 쓸 수 있다.
- API 게이트웨이를 사용할 때 장점은 다음과 같다.
MSA를 도입했을 때 이점은 다음과 같다.
- 민첩성 : 마이크로 서비스는 독립적으로 배포가 되기 때문에 버그 수정 및 기능 릴리즈를 관리하기가 더 쉽다.
- 전체 어플리케이션을 다시 배포하지 않고 서비스를 업데이트 할 수 있고, 문제가 발생하면 서비스를 롤백할 수 있다.
- 기존의 많은 어플리케이션의 경우, 버그가 어플리케이션의 한 부분에서 발견되면, 전체 릴리즈 프로세스를 차단할 수 있다. 버그 수정이 통합, 테스트 및 게시될 때까지 새로운 기능은 보류될 수 있다.
- 집중화된 소규모 팀 : 마이크로 서비스는 규모가 작아서 한 기능 팀에서 충분히 구축, 테스트 및 배포할 수 있다.
- 소규모 코드 기준 : 모놀리식 어플리케이션의 경우 시간이 경과하면서 코드 종속성이 얽히는 경향이 있다.
- 새 기능을 추가하려면 여러 지점의 코드를 손을 보아야 한다.
- MSA는 코드나 데이터 저장소를 공유하지 않으므로 종속성이 최소화되며 그 결과 새로운 기능을 추가하기 쉽다.
- 결함 격리 : 개별 마이크로 서비스를 사용할 수 없게 되더라도, 장애를 제대로 처리하도록 업스트림 마이크로 서비스를 설계하면 (예: 회로 단락 구현) 전체 어플리케이션에 방해가 되지 않는다.
- 확장성 : 서비스는 별도로 확장될 수 있어 전체 어플리케이션 규모를 확장하지 않고도 리소스가 더 많이 필요한 하위 시스템의 규모를 확장할 수 있다.
- 쿠버네티스와 같은 오케스트레이터를 사용하면 단일 호스트에 서비스를 보다 높은 밀도로 패킹할 수 있기 때문에 리소스를 보다 효율적으로 활용할 수 있다.
- 데이터 격리 : 단일 마이크 서비스만 영향을 받기 때문에 스키마 업데이트를 수행하는 것이 훨씬 쉽다.
- 모놀리식 어플리케이션에서는 스키마 업데이트가 매우 어려울 수 있다.
- 어플리케이션의 다양한 부분이 모두 동일한 데이터에 영향을 미칠 수 있어서 스키마를 변경하는 것이 위험하기 때문이다.
MSA를 도입했을 때 해결해야 하는 과제(=단점)는 다음과 같다.
- 복잡성 : 마이크로 서비스 어플리케이션에는 동등한 모놀리식 어플리케이션보다 작동 부분이 더 많다.
- 각 서비스는 단순하지만 전체 시스템이 더 복잡하다.
- 개발 및 테스트 : 다른 종속 서비스에 의존하는 소규모 서비스를 작성하려면 기존의 모놀리식 또는 계층화된 어플리케이션을 작성하는 것과 다른 접근 방식이 필요하다.
- 기존 도구는 항상 서비스 종속성 작업에 맞게 설계되지 않는다.
- 서비스 경계를 벗어난 리팩터링은 어려울 수 있다.
- 특히 어플리케이션이 빠르게 발전하는 경우 서비스 종속성을 테스트 하기 어럽다.
- 통제 부족 : 마이크로 서비스 빌드에 대한 분산 접근 방법에는 장점이 있지만 문제가 발생할 수도 있다.
- 언어와 프레임워크가 너무 많아서 어플리케이션 유지 관리가 어려울 수 있다.
- 팀의 유연성을 지나치게 제한하지 않고 몇 가지 프로젝트 전체 표준을 적용하는 것이 유용할 수 있다.
- 네트워크 정체 및 대기 시간 : 다수의 작고 세분화된 서비스를 사용하면 서비스 간 통신이 증가할 수 있다.
- 또한 서비스 종속성 체인이 너무 길어질 경우(서비스 A가 B를 호출하고, B가 C를 호출하고 등등) 추가 대기 시간이 문제가 될 수 있다.
- 통신량이 과도한 API를 피하고, 직렬화 형식을 고려하고, 큐 기반 부하 평준화 같은 비동기 통신 패턴을 사용해야 할 수도 있다.
- 데이터 무결성 : 각 마이크로 서비스가 자체 데이터 지속성을 담당한다.
- 그 결과, 데이터 일관성이 과제가 될 수 있다.
- 가능한 경우 결과적 일관성을 수용한다.
위와 같은 MSA 형태의 개발을 하다 보면, 다음과 같은 상황이 펼쳐질 수 있다.
- 여러 프레임워크(Web, Android, iOS, Desktop 등)을 지원하게 되면서 각각 특정 데이터가 필요한 상황
- 원하는 데이터 형태에 도달하기 위해 여러 API 호출의 응답을 조작, 혼합, 일치시키는 상황
- 이런 상황들이 겹쳐 프론트엔드에서 복잡한 계산이나 비즈니스 로직을 작성하는 상황
코드 베이스가 커지고 복잡해짐에 따라 정리하기가 어려워지고, 복잡성은 증가한다. 그리고 프론트엔드에서 복잡한 계산을 수행하는 경우 렌더링 성능에도 영향을 줄 수 있다. UI 스레드에서 렌더링과 비즈니스 로직이 동시에 수행이 되면서 경합을 벌이기 때문이다.
BFF
이러한 문제를 해결하기 위해 나타난 아키텍처가 바로 Backend For Frontend (BFF)
이다. BFF는 프론트엔드 프레임워크(Web, Android, iOS, Desktop, 스마트 워치 등) 별로 필요에 맞게 각각 백엔드를 구성하는 아키텍처 방법론이다. BFF의 가장 큰 장점 중 하나는 플랫폼 별로 적절한 서버가 돌아가고 있기 때문에 seamless한 사용자 경험을 줄 수 있다는 점이다. 또한 각각의 플랫폼 별로 BFF를 잘 따라서 설계가 되어 있다면 어플리케이션을 실행하는 동안에 자원 사용량도 최적화를 할 수가 있다.
예를 들어, 은행 앱에서 내 계좌로 입금이 되었을 때 내가 가진 스마트 워치로 알림을 보내준다고 가정해보자. 스마트 워치에는 해당 입금 관련 정보(금액, 시간, 송금을 어디서 했는지 등)만 있으면 충분할 것이다. 하지만 같은 은행 서비스를 스마트폰 앱이나 데스크탑 PC 브라우저에서 사용한다면 필요로 하는 정보는 더 많을 것이다. 이럴 경우 모든 플랫폼에 쓸 수 있는 generic API를 사용할 경우 불필요한 데이터가 많이 쌓여서 오버헤드가 발생할 수 있다.
이렇게 BFF를 도입했을 때 장점은 다음과 같다.
- 여러 개의 프론트엔드 어플리케이션 인터페이스가 각각의 BFF 서버를 병렬적으로 호출하므로, 각각의 응답이 빨라진다.
- BFF 아키텍처를 따름으로서, 백엔드 시스템의 수정을 하거나 개선을 하는 과정에서 팀이 사용하는 시간이 줄어든다.
- 프론트엔드 어플리케이션으로 데이터를 전송하는 과정에서 민감하거나 불필요한 데이터는 숨길 수 있어서 시스템을 간결하게 할 수 있다.
반면에 BFF을 통해 마주하는 과제(=단점)은 다음과 같다.
- Fan Out : 하나의 서비스가 전체 BFF 시스템을 다운 시킬 수 있다. (안티패턴)
- Fuse : 각각의 서비스가 여러 BFF에게 호출되었을 때 발생한다.
- 많은 부분의 코드가 중복되거나 재작성될 수 있다. 이 과정에서 많은 커뮤니케이션 비용이 발생한다.
참고자료
카카오페이지는 BFF(Backend For Frontend)를 어떻게 적용했을까?
마이크로 서비스 아키텍처 스타일 - Azure Architecture Center
Why "Backend For Frontend" Application Architecture? - mobileLIVE
'Web Frontend Developer' 카테고리의 다른 글
React Context 올바르게 사용하기 (0) | 2022.07.06 |
---|---|
Apollo Client에서의 Caching에 대하여 (0) | 2022.06.14 |
[FeBase S3] SVG, Canvas, viewport와 viewbox (1) | 2022.04.17 |
[Troubleshooting] Next.js에서 dynamic routing 새로고침 에러 (0) | 2022.04.15 |
[패캠] The RED : 김민태의 React와 Redux로 구현하는 아키텍처와 리스크 관리 (0) | 2022.03.23 |