2000년대 초반, 큰 규모의 Application을 구축할 때 SOA라는 패턴이 유행했다.
다른 플랫폼들과 다른 언어로 작성된 서비스들을 Enterprise Service Bus( Common Communication Mechanism )으로 하나로 묶어줬다.
SOA의 특징은 아래와 같았다.
Monolithic 구조란
아래의 그림처럼 모든 모듈들이 하나의 서비스 내부에 종속되어 있으며, 다른 역할을 하는 모듈들이 하나로 모여서 하나의 프로젝트를 이루는 것.
장점 | 단점 |
---|---|
- 단순한 구조 | - 규모가 커질수록 복잡도 증가 |
- 배포가 간편 | - 코드 전체를 이해하기가 힘듦 |
- End to End 테스트가 용이 | - CI/CD가 많이 힘듦(어떠한 영향을 주는지 파악하기 힘들어서) |
- 통일성을 가짐 | - 새로운 기능이나 기술을 적용하기 위해서는 새로 만들어야 함 (관리를 제대로 하지 않았다면) |
MicroService란
위의 단점을 보완하기 위해 나왔으며, 각 서비스는 작고 독립적이며 느슨하게 결합되어 있다.
장점 | 단점 |
---|---|
- 전체를 다시 배포하지 않고도 업데이트 가능 | - 서비스간 통신방법이 필요하고 복잡함 |
- 독립적인 개발이 가능 | - 서비스끼리 전체 테스트가 어려움 |
- 서비스 하나의 문제가 전체에 영향을 끼치지 않음 | - 독립된 구조로 통합적인 관리가 힘들어 질 수 있음 |
위에서는 SOA와 MSA가 완전히 다른 개념인것 같지만 자세히 살펴보면 본질은 같다.
MSA는 SOA에서 세분화된 버전이며, SOA의 단점인 Monolithic 구조를 극복하고자 만들어진 것이다. ( 더 좋아서가 아님!! )
( 둘 다 각각의 서비스들이 존재하며, SOA는 ESB를 통해서 하나로 운영하려 하지만 MSA는 하나의 통신창구를 놔둔 것이 아니라 각각 통신하게 한다는 차이만 있다. )
MSA가 최근 각광받는 이유는 2가지가 있다.
처음에는 하드웨어 즉 물리적인 서버를 사용했다. 예전에는 application을 build할 때 host OS의 리소스를 가져다 썼다. 즉 scale up을 위해서라면 다른 물리적은 서버를 하나 더 구매해서 사용해야만 했다.
이를 극복한 것이 가상화이다. 단일 서버를 여러 사용자가 공유할 수 있도록 물리서버 자원을 추상화하고, 공간을 분리해서 독립적인 가상환경 서버를 사용할 수 있게 되었다. 즉 여러개의 application들을 물리적인 서버를 늘려서 구동할 필요가 없어진 것이다.
가상화의 종류에는 'Hypervisor' 기반과 'Container' 기반이 있다.
'Hypervisor'는 Host OS에서 다수의 guest OS를 구동할 수 있게 해주는 것이다. Hypervisor와 guest OS가 필요하기에 무거운 것이 단점이다.
'Container'는 'Hypervisor'와 달리 실행에 필요한 모든 구성을 함께 배포한다. 즉 어디에서 실행해도 일관성 있는 실행이 가능해진다. 그렇기에 모든 서비스가 분리되어 있는 MSA에서 각광받는다.
이를 쉽게 관리하게 도와주는 것이 뒤에서 다룰 Docker이다.
Monolithic 구조는 각 모듈들이 합쳐져서 하나의 큰 덩어리이기 때문에, 사용성이 적은 모듈을 삭제한다고해도 전체 시스템은 거대하기 때문에 스펙이 크게 변화하지 않습니다.
하지만 MSA는 서비스단위로 기능을 분리해서 구축하기 때문에 사용하지 않는 기능을 축소화해서 효율적인 관리가 가능합니다.
도커는 Container 기반의 오픈소스 가상화 플랫폼이다.
즉, 위에서 이야기한 Container들을 기반으로 한 플랫폼이다. Container 기술을 바탕으로 사용자의 코드를 어디서든 빠르고 가볍게 실행시킬 수 있게 도와준다.
Docker Container란 개별 소프트웨어 실행에 필요한 환경을 독립적으로 보장해주는 즉 격리된 공간이다. Container 안에는 뒤에서 알아볼 Docker image가 담겨있으며 이를 실행시켜주는 공간이다. (뒤에서 좀 더 자세하게 설명한다.)
이것이 왜 이점인지 알아보자.
눈송이 서버(Snowflake Servers)를 방지할 수 있다.
같은 일을 하는 서버 A, B가 있다고 가정하자. A서버는 한 달전에 구성했고, B 서버는 이제 막 구성했다면, 운영체제부터 컴파일러, 패키지 등 완벽하게 같게 하기가 쉽지가 않다. 이렇게되면 A 서버는 잘 되는데 B 서버는 동작하지 않는 문제도 발생한다. 하지만 도커를 사용한다면 동일한 환경에서 구동되기 때문에 이러한 문제를 방지할 수 있다.
서버 운용기록의 코드화가 가능하다.
도커는 Docker file을 사용해서 서버 운영 기록을 코드화 할 수 있다. 즉 이 방식으로 눈송이 서버를 방지한다. Docker file을 바탕으로 Docker image를 만들 수 있다. file이 기록이라면 image는 실행시점이라고 볼 수 있다.
Docker file = 서버 운용 기록 코드
Docker image = Docker file + 실행시점
Docker image는 정확히 Container 실행에 필요한 파일과 설정값들을 모두 담은 것이며 변하지 않는 성질이 있다. 같은 image에서 Container를 여러개 생성할 수도 있고, Container가 삭제되더라도 image는 남아있다.
이 image를 싱행시키면 서버를 항상 같은 시점을 기준으로 운영할 수 있다.
앞에서 이야기한 Docker Container를 다시 이야기 해보면 서버에는 바뀌어야 할 부분도 있다. 그래서 변하지 않는 image를 감싼 Container에 실행되는 시점에서 수정되어야 할 정보들을 더한다.
Docker file = 서버 운용 기록 코드
Docker image = Docker file + 실행시점
Docker Container = Docker image + 환경 변수