The Drawbacks of Microservices (Microservice의 단점)

약 30년 전, Fred Brooks가 쓴 것처럼, 획기적인 방법은 없다. 다른 모든 기술들처럼 Microservice Architecture도 단점이 있다. 한가지 단점은 이름 그 자체에 있다. Microservice라는 용어는 서비스의 크기를 과도하게 강조한다. 사실, 극도로 잘게 나누어진, 10~100줄의 코드로 이루어진 서비스 개발을 지지하는 개발자들도 있다. 작은 서비스들이 더 좋지만, 그것은 목적을 위한 수단이고, 주된 목적은 아니라는 것을 기억하는 것이 중요하다. Microservice의 목적은 어플리케이션을 빠르게 개발하고 배포 가능하도록 하기 위하여 어플리케이션을 충분히 분해하는 것이다.

Microservice의 또다른 주요 단점은 microservice 어플리케이션들이 분산환경에 있다는 사실에서 발생하는 복잡성에 있다. 개발자들은 메시지나 RPC중 하나에 기반한 inter-process communication 메커니즘을 선택하고 구현할 필요가 있다. 더욱이, 요청의 목적지가 느려지거나 이용불가능할 경우가 있기 때문에 부분적인 오류를 다루는 코드를 반드시 작성해야만 한다. 고도의 지능이 요구되는 일은 아니지만, 모듈간 language-level method/procedure 호출을 통해 서로 통신하는 monolithic application에서 훨씬 더 복잡하다.
(Inter-process communication : 프로세스들 사이에 서로 데이터를 주고 받는 통신 방법 혹은 경로)

Microservice의 또다른 도전은 분할된 데이터베이스 구조(partitioned database architecture)이다. 일반적으로 Business Transaction은 여러 개의 business entity들을 업데이트한다. 이러한 종류의 transaction들을 monolithic application에서 구현하는 것은 사소한 일이다. 왜냐하면, 하나의 데이터베이스만 있기 때문이다. 그러나 Microservice 기반 application 에서는 다른 서비스들이 소유한 여러 개의 데이터베이스를 업데이트할 필요가 있다. 분산 transaction을 사용하는 것은 CAP theorem 때문에 유일한 해결책은 아니다. 오늘날 매우 확장 가능한 많은 NoSQL 데이터베이스나 messaging broker에서 분산 transaction을 지원하지 않는다. 결국 개발자들에게 더 도전적인, 궁극적인 일관성에 기반한 접근법을 사용해야만 하는 상황에 직면하게 된다.

Microservice 어플리케이션을 테스트하는 것 또한 훨씬 더 복잡하다. 예를 들면, Spring Boot과 같은 최근의 framework으로 monolithic 웹 어플리케이션을 구동하는 테스트 클래스를 작성하고, REST API를 통해서 테스트 하는 것은 사소한 일이다. 반대로, 서비스에 대한 유사한 테스트 클래스는 테스트 대상 서비스와 의존 관계에 있는 다른 서비스들을 실행할 필요가 있다.(최소한 그러한 서비스들에 대한 stub 환경 설정이라도 해야 한다.) 한번 더 말하면, 이것이 고도의 지능을 요구하는 일은 아니지만, 테스트 수행에 대한 복잡도를 너무 적게 잡지 않는 것이 중요하다. (테스트 수행이 monolithic application 보다 복잡하다는 뜻.)

Microservice Architecture Pattern의 또 다른 주요 도전은 여러 서비스에 퍼져 있는 변경 사항들을 구현하는 것이다. 예를 들어, 서비스 A, B, C의 변경을 요구하는 스토리를 구현하는 것을 상상해 보자.서비스 A는 서비스 B에 의존하고, 서비스 B는 서비스 C에 의존한다. Monolithic application 에서는 해당 모듈들을 간단하게 변경하고, 변경 사항들을 취합하여 한번에 배포할 수 있다. 반대로, Microservice Architecture Pattern 에서는 주의하여 계획을 세우고, 뽑아낸 변경사항들에 대해 각 서비스들을 조정, 반영해야 한다. 예를 들어, 서비스 C를 업데이트할 필요가 있을 경우, 서비스 B도 따라서 업데이트 하고, 마지막으로 서비스 A도 업데이트 해야 한다. 다행스럽게도 대부분의 변경사항들은 보통 하나의 서비스에만 영향을 주고 조정이 필요한 여러 서비스를 변경하는 경우는 거의 드물다.

Microservice 기반 어플리케이션을 배포하는 것은 훨씬 더 복잡하다. Monolithic 어플리케이션은 전통적인 load balancer 뒤에 있는 동일한 서버에 간단하게 배포된다. 각각의 application instance에는 데이터베이스와 messaging broker와 같은 infrastructure service의 위치(host and ports)가 설정되어 있다. 반대로, microservice application은 일반적으로 수많은 서비스들로 이루어져 있다. 예를 들어, Hailo는 160개의 다른 서비스들로 이루어져 있고, Netflix는 Adrian Cockcroft에 따르면 600개가 넘는다. 각 서비스는 여러 개의 runtime instance를 가지고 있을 것이다. 여기에는 설정하고, 배포하고, 확장하고, 모니터링 대상이 되는 많은 이동하는 부품들이 있다. 게다가, 하나의 서비스에서 통신할 필요가 있는 다른 서비스들의 위치(host and ports)를 찾기 위한 service discovery mechanism(나중에 다른 post에서 논의할 것이다.)을 구현할 필요가 있다. 전통적인 trouble ticket 기반과 operation에 대한 수작업 접근법은 복잡도의 레벨을 변경할 수 없다. 따라서, microservice application 을 성공적으로 배포하는 것은 개발자들이 배포 방법을 더 많이 제어하고, high level 자동화가 필요하다.

자동화에 대한 한가지 접근 방법은 Cloud Foundry와 같은 기성 PaaS를 이용하는 것이다. PaaS는 개발자들이 microservice를 배포하고 관리하는 데 쉬운 방법을 제공한다. PaaS는 IT 리소스를 어렵게 구하고 설정하는 것에 대한 우려를 불식시킨다. 동시에, PaaS를 설정하는 시스템과 네트워크 전문가들은 best practice와 회사 정책에 따른 법규 준수를 보장할 수 있다. Microservice 배포를 자동화하는 또다른 방법은 근본적으로 여러분 자신의 PaaS를 개발하는 것이다. 한가지 전형적인 시작 포인트는 Docker와 같은 기술과 함께 Kubernetes와 같은 클러스터링 솔루션을 이용하는 것이다. 이 시리즈의 뒤쪽에서, Microservice level에서 caching, access control, API metering, monitoring을 쉽게 다루는 NGINX와 같은 software 기반 어플리케이션 배포 방법들이 이 문제를 해결하는데 어떤 도움을 줄 수 있는지를 보여줄 것이다.

받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/750

The Benefits of Microservices (Microservice가 주는 혜택)

Microservice Architecture Pattern은 많은 중요한 혜택을 준다.

첫번째로, 복잡성의 문제를 다룬다. Microservice Architecture Pattern은 괴물같은 monolithic application을 반대로 service들의 집합으로 분해한다. 전체 기능성을 변경하지 않는 범위내에서 관리가능한 덩어리나 서비스로 application을 쪼갠다. 각 서비스는 RPC-나 메시지 기반 API 형태로 잘 정의되어 있는 경계를 가진다. Microservice Architecture Pattern은 실제 monolithic code에서는 극도로 달성하기 어려운 모듈화(modularity) 수준을 강화한다. 따라서, 개별 서비스를 훨씬 더 빨리 개발하고, 더 이해하기 쉽고, 유지하기도 쉽다.

두번째로, 이 아키텍처는 한 팀에서 각각의 서비스에 초점을 맞춰 독립적으로 개발할 수 있게 한다. 개발자들은 API를 붙여서 명예로운 서비스를 제공하는데 어떤 기술이 적합한지 선택하는데 자유롭다. 물론, 대부분의 조직에서는 완전한 무정부 상태를 피하고 기술 선택을 제한하고 싶을 것이다. 그러나 이러한 자유는 개발자들이 신규 프로젝트를 시작할 때 존재했던 한물간 기술을 더이상 의무적으로 사용하지 않아도 된다는 것을 의미한다. 새로운 서비스를 만들 때, 현재 기술을 사용할 선택권을 갖는다. 더 나아가, 서비스들이 상대적으로 작기 때문에 현재의 기술을 사용하여 예전 서비스들을 재작성하는 것이 가능하다.

세번째는, Microservice Architecture Pattern에서는 각 microservice별로 독립배포가 가능하다. 개발자들은 로컬환경에서 서비스로 변경 사항들을 배포할 때, 조정할 필요가 없다. 변경 사항들은 테스트가 완료되는 대로 즉시 배포할 수 있다. 예를 들어, UI 팀은 A/B 테스트를 수행하고, UI를 변경하는 작업을 빠르게 반복할 수 있다. Microservice Architecture Pattern은 지속적인 배포가 가능하다.
(A/B testing : 전체 디자인에서 한가지 요소에 대한 두가지 이상의 버전을 시험하여 더 나은 것을 판별하는 테스트 기법)

끝으로, Microservice Architecture Pattern은 각 서비스별로 독립적인 확장이 가능하다. 각 서비스별로 용량과 가용성 제약사항들을 만족시키는 범위 내에서 수많은 인스턴스에 배포할 수 있다. 게다가, 서비스의 리소스 요구사항에 가장 적합한 하드웨어를 사용할 수 있다. 예를 들어, EC2 Compute Optimized instance에 CPU-집중적인 이미지 프로세싱을 배포할 수 있다. 그리고 EC2 Memory Optimized instance에 인메모리 데이터베이스 서비스를 배포할 수 있다.
받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/749

서버의 주요한 기능은 이미지나 HTML 파일과 같은 파일들을 제공하는 것이다. 여러분은 서로 다른 디렉토리(HTML 파일들이 있는 /data/www 디렉토리와 이미지를 포함하고 있는 /data/images 디렉토리) 있는 파일들을 서로 다른 요청에 의해서 제공하는 예제를 구현할 있다. 그렇게 하기 위해서는 configuration 파일을 수정하여 http block내에 있는 server block 2개의 location block 설정하면 된다.


먼저, /data/www 디렉토리를 생성하고 임의의 텍스트를 가진 index.html 파일을 저장하자. 그리고 /data/images 디렉토리를 생성하고, 임의의 이미지 파일을 위치시킨다.

다음으로 nginx configuration file open하면 이미 기본적으로 server block 여러 예제들이 포함되어 있다. (대부분 코멘트로 막혀 있다.) 이제 모두 코멘트로 막고, 새로운 server block 추가해 보자.


http {

server {

}

}


일반적으로, configuration file 요청을 받을 서로 다른 port server name으로 구분된 여러 server block 가질 있다. Nginx에서 request 처리할 server 결정하고, server block내에 정의된 location 지시어(directive) 파라미터와는 반대로 Request header 특화된 URI를 테스트한다.


Server block내에 다음 location block 추가한다.


location / {

root /data/www;

}


location block prefix "/" 시작하는 request URI 특화되어 있다. URI root directive 특화된 path 추가될 것이다. 따라서, 로컬 파일 시스템상의 요청된 파일은 /data/www 있다. 만약 여러 개의 매칭되는 location block 있다면, nginx 가장 prefix 선택한다. 위에서 제공된 location block 가장 짧은 prefix이다. 따라서, 모든 request에는 location block 사용된다.


다음으로, 두번째 location block 추가해 보자.


location /images/ {

root /data;

}


이것은 /images/ 시작하는 request 매칭될 것이다. (location / 역시 매칭되기는 하지만, 짧은 prefix이다.)

결과적으로 server block configuration 다음과 같다.


http {

server {

location / {

root /data/www;

}


location /images/ {

root /data;

}


}

}



이것은 이미 표준 포트 80으로 요청을 받는 동작하고 있는 server 설정이다. 따라서, localhost 접속할 있다. /images/ 시작하는 URI 요청에 대한 응답에서 server는 /data/images 디렉토리에 있는 이미지 파일을 보낼 것이다. 예를 들어, http://localhost/images/example.png 요청하면 nginx /data/images/example.png 파일을 리턴할 것이다. 만약 그런 파일이 없다면, nginx 404 error 리턴할 것이다. /images/ 시작하지 않는 request URI 대해서는 /data/www directory 맵핑된다. 예를 들어, http://localhost/some/example.html 요청에 대해서 nginx /data/www/some/example.html 파일을 리턴할 것이다.


새로운 configuration 적용하기 위해서는 아직 nginx 시작되지 않았으면 nginx start하고, 이미 nginx 시작했다면, master process reload signal 보낸다. 실행 command 다음과 같다.


nginx -s reload


기대한 대로 동작을 하지 않는 경우에는 access.log error.log에서 이유를 찾아볼 있다. 로그 파일들은 /usr/local/nginx/logs /var/log/nginx에서 찾아볼 있다.

받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/684

<설정 파일 구조>

Nginx 설정 파일 내의 directive(지시어)들에 의해 제어되는 모듈들로 이루어져 있다. Directive simple directive(단순 지시어) block directive(블록 지시어) 나누어져 있다. Simple directive space 구분되는 name, parameter 구성되어 있고, semicolon(;)으로 끝난다. Block directive simple directive 동일한 구조를 갖지만, semicolon으로 끝나는 대신에 괄호로 묶인다. (중괄호 사용 : '{' '}') Block directive 괄호 안에 다른 directive들을 가질 있다. 이것을 context라고 부른다. (ex. Events, http, server, location)


설정 파일에서 Context 밖에 위치하는 directive들은 main context 있는 directive 간주한다. Events, http main context 위치하고, http 안에 server 있고, server 안에 location 있다.


#표시 뒤에 오는 라인은 comment이다.

TAG
받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/665

<Starting, Stopping, and Reloading Configuration>

Nginx 실행파일을 실행하여 시작한다. Nginx 실행된 이후에는 -s 파라미터를 가지고 다른 작업을 수행하도록 있다. 다음과 같은 문법을 갖는다.


nginx -s signal


Signal 다음 값을 가질 있다.

Stop : fast shutdown

Quit : graceful shutdown

Reload : 설정 파일 reload

Reopen : 로그 파일 reopen


예를 들어 현재 처리 중인 request 모두 처리하고 nginx 종료하고자 한다면 다음 command 실행하면 된다.


nginx -s quit


  • command nginx 실행할 때와 동일한 user 실행해야 한다.

설정 파일의 변경은 변경된 설정 파일을 reload command 통해서 nginx 전달해야 적용된다. 설정 파일을 reload하는 command 다음과 같다.


nginx -s reload


Master Process 설정 파일 reload signal 받으면 새로운 설정 파일에 대한 syntax validation 체크하고, 적용한다. 적용이 끝나면 master process 새로운 worker process 실행하고, 기존의 worker process에는 shutdown 요청을 보낸다. 과정 중간에 오류가 발생하면 master process 변경 사항을 roll back하고 계속해서 old worker process 작업을 수행한다. Old worker process shutdown 메시지를 받으면 새로운 connection 받는 것을 중지하고 현재 처리 중인 request 완료될 때까지 계속해서 서비스를 제공한다. 모든 처리 중인 request 완료되었을 , old worker process 종료된다.


Signal kill utility 같은 Unix tool 도움을 받아서 nginx 전달될 수도 있다. 경우 signal 주어진 process ID 통해서 직접적으로 nginx process에 전달된다. Process ID로는 nginx master process ID 사용한다. 기본적으로 nginx.pid /usr/local/nginx/log 폴더나 /var/run 폴더에 저장된다. 예를 들어서, master process ID 1628이라면, nginx graceful shutdown 위한 Quit signal 다음과 같이 보낼 있다.


kill -s QUIT 1628


모든 기동중인 nginx process 대한 리스트를 얻으려면 다음과 같이 ps utility 사용할 있다.


ps -ax | grep nginx


Nginx 보내는 signal 대한 자세한 정보는 Controlling nginx (http://nginx.org/en/docs/control.html) 통해서 얻을 있다.

TAG
받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/664