본 게시글은 https://www.udemy.com/course/microservices-with-node-js-and-react/ 강의를 듣고 정리한 내용입니다.
아직 마이크로 서비스에 대해 잘 모른다면 보통은 모놀리식 방식으로 서버를 개발할 것입니다. 모놀리식 서버는 하나의 코드 베이스안에 필요한 모든 코드를 가지고 있는 서버를 말합니다. 위에처럼 인증미들웨어를 지나 라우터를 건너 요청한 기능에 맞는 코드를 수행하게 될 것입니다.
마이크로서비스
는 하나의 기능만을 구현하도록 설계되어있습니다. 그 기능을 수행하기 위해 필요한 모든 코드를 가지고 있죠. 즉, 각 서비스는 혼자 존재해도 쓸 수 있다는 소리가 됩니다. 따라서 다른 한개 서비스가 오류가 나서 중단되어도 다른 기능은 문제 없이 동작하게 될 것입니다. 또한, 한 가지 기능에 사용자가 몰리면 그 기능만 추가적으로 여러개를 생성해 분산 처리하면 될 것입니다.
마이크로서비스를 시작할때 직면하는 몇가지 큰 장벽이 있습니다.
먼저, 서비스들이 데이터를 어떻게 저장하는지와 접근하는지를 알아야 합니다.
그림을 보면 알겠지만 마이크로서비스는 각 서비스에 대해 별도의 데이터베이스를 만들고 이용하고 있다는 점입니다.
마이크로서비스는 한 서비스에서 다른 서비스로 데이터베이스에 접근하여 데이터를 액세스 하지 않을 것입니다.
일단 왜 데이터베이스를 분리해서 사용하는지 알아보겠습니다.
첫번째 이유는 우리가 만든 모든 서비스가 독립적으로 실행
되기를 원하기 때문입니다.
먼저 위 그림처럼 동일한 공통 데이터베이스를 사용하는 모든 서비스를 상상해 보겠습니다. 가장 큰 문제점은 이 데이터베이스에 나쁜 일이 일어난다면 우리의 모든 서비스에 문제가 발생할 것입니다. 또한 다른 큰 문제로는 데이터베이스 확장입니다. 차라리 하나의 DB를 한 서비스만 사용한다면 추가 용량이나 처리량이 필요한 DB를 확장하는 것이 좀 더 효과적일 것입니다.
두번재 이유로는 데이터베이스의 스키마나 구조가 예기치 않게 변경
될 수 있기 때문입니다. 예를 들어, 서비스 A가 서비스 B 전용 DB에서 User 정보를 호출하고 name이란 값으로 반환받아서 사용중이라고 해보겠습니다. 그러다가 서비스 B가 자기 전용인 DB에서 name 속성이름을 firstName이라고 수정했습니다. 그렇다면 동시에 서비스 A도 영향을 받을 것입니다.
간단한 예시로 위와 같은 앱이 있고 이를 모놀리식 서버로 구성했을때 이미지입니다.
그리고 이런 기능들은 한개의 DB를 가지고 여러 테이블로 나눠서 처리할 것입니다. 만약 여기서 특정유저가 주문한 상품을 보여주고 싶다면 어떻게 해야 할까요? 먼저 유저 테이블과 주문 테이블과 제품 테이블을 모두 조인해서 처리해야 할지도 모르겠습니다.
그렇다면 마이크로 서비스는 이 문제를 어떻게 해결해야 할까요?
Sync Communication(동기 통신) : 한 서비스가 요청을 통해 다른 서비스와 직접 통신할 수 있도록 하는 방식입니다. 그래서 우리는 서비스 패턴에 따라 데이터베이스와 관련된 어떠한 큰 규칙도 위반하지 않았습니다.
다만 문제가 있습니다. 서비스 D와 다른 서비스간의 의존성관계입니다. 서비스 A에서 오류가 발생하면 서비스 D까지 번지게 되는 셈이죠. 또한 속도 측면에서도 느릴겁니다.
이 이벤트 버스의 목적은 서로 다른 이벤트로부터 방출되는 알림이나 이벤트를 처리하는 것입니다. 각 서비스는 이벤트를 내보내거나 이벤트 버스로부터 이벤트를 수신할 수 있습니다.
예를 들어 서비스 D가 이벤트버스로 요청합니다. 여기서는 type: UserQuery와 data: {id: 1} 을 Event로 보냈습니다. 그러면 서비스 A가 자신에 대한 이벤트 요청인것을 알고 처리해서 결과를 이벤트 버스로 넘겨줍니다. 그러면 서비스 D가 그 결과를 받습니다.
하지만 여전히 모든 단점이 해결되지 않았습니다. 서비스 의존도 해결되지 않았고요.
서비스 D가 하려는 일이 뭔지 정확히 정의를 내리면 유저의 ID가 주어졌을때 그들이 주문한 모든 상품의 이름과 이미지를 출력하는 것입니다.
음.. 만약 서비스 B에서 상품을 추가해본다고 합시다. 그럼 자신과 연결된 서비스 B 데이터베이스에다가 상품을 추가할 것입니다. 그런다음 Event Bus에 상품이 추가되었고 이런이런상품이야 라는 정보를 올립니다. 서비스 D는 이 이벤트를 전달받아서 자신의 Database에 기록합니다.
다른 서비스도 마찬가지로 동작합니다. 유저정보가 추가되었다면 서비스 D에다가도 저장해주고, 주문목록이 추가되었다면 마찮가지로 업데이트시켜줍니다.
이렇게 해서 어쨌든 서비스 D는 단일적으로 동작할 수 있습니다. 하지만 Data가 중복적으로 저장되는군요. 근데 달리 방법이 없으니 선택의 여지가 없습니다. (??) 음... 어... 사실 이 부분이 잘 이해되지는 않습니다.