대규모 마이크로 서비스의 대응 패턴 

장애는 어디서든 발생할 수 있다는 가정을 명심하는 거은 문제 해결 방법을 다르게 생각하도록 만든다.

얼마나 많은 장애를 감내할 수 있는지와 얼마나 빠른 시스템이 되야 하는지 아는 것은 시스템 사용자에 의해 좌우 된다.

부하와 장애를 더 잘 처리하기 위해 다음과 같은 시스템 확장을 고려할 수 있다.

- 응답시간/지연시간 ex) 웹사이트가 초당 200개의 동시 접속수를 처리할 때 응답시간의 90%가 2초 미만을 유지할 것으로 예상된다

- 가용성, 데이터의 내구성 

기능분해의 중요성 

회복력 있는 시스템 구축을 위해서는 안전하게 기능을 분해할 수 있는것이 중요하다. 다수의 마이크로서비스를 사용하는 모든 고객을 향한 인터페이스나 다수의 하위 협업자 서비스에 의존하는 마이크로서비스가 다운되면 어떤 일이 벌어질지 자문하고 무엇을 해야 할지 알아야 한다. 교차 기능 요구 사항의 고나점에서 개별 기능의 심각도를 생각함으로써 우리가 무엇을 할 수 있는지 훨씬 더 잘 알게 될 것이다. 

안티프래질 조직 : 실패와 무질서로부터 얻을 수 있는 혜택

실제로 장애를 조작하여 궁극의 장애 테스트를 할 수도 있다. 분산된 아키텍처에서 발생할 수 있는 이런 장애를 대응하기 위한 준비

- 타임아웃 : 모든 프로세스 경계 외부의 호출에 타임아웃을 넣고 항상 기본 타임아웃 시간을 설정해야 하는데 발생 시간을 로깅하고 어떤 일이 발생했는지 살펴보며 타임아웃 시간을 적절히 변경해 주어야 한다.

- 회로 차단기 : 호출 타임아웃 또는 오류가 발생하기 시작했을떄 임계치를 초과하면 커텍션을 중단키셔 요청이 실속히 실패하도록 한다. 그다움 서브 시스템이 복수 여부를 간헐적으로 확인하고 정상 임계치에 도달하면 커텍션을 리켓한다. 

- 격벽 : 각각의 하위 커넥션 마다 각각의 다른 커텍션 풀을 사용

- 격리 : 하위 서버를 오프라인 상태로 만들 수 있는 통합 기술을 사용하여 하나의 서비스가 다른 서비스에 의존하지 않도록 한다.

확장

- 더 크게 만들기 : 더 큰 머신에 더 빠른 CPU와 더 좋은 I/O를 탑재 한다고 해서 모든 문제가 해결되는 것은 아니지만 이는 빠르고 좋은 해결 방안이다. 

- 작업부하 나누기 : 중요성의 크기에 따라 서비스를 잘 분리한다. 

- 부하 분산 : 부하분산기는 유입된 호출을 주어진 알고리즘에 따라 하나 이상의 인스턴스에 분배하고 인스턴스가 정상 동작하지 않거나 복구되었을 때 제거하거나 추가한다. 일부 부하분산기는 SSL termination 기능을 제공한다. 분산기로 유입되는 HTTPS 커넥션을 HTTP커넥션으로 변환해서 인스턴스에 전달한다. 보안강화를 위해 VLAN안에 모든 마이크로 인스턴스를 둔다. VLAN은 가상의 지역 네트워크로 외부와 격리되어 있어 외부 요청은 라우터로만 유입되는데 이 경우에는 라우터가 SSL을 종단하는 부하분산기가 된다. VLAN외부의 통신은 HTTPS지만 내부에서는 모두 HTTP를 사용한다. AWS는 HTTPS terminal 기능이 있는 부하분산기를 elastic load balancer ELB 형태로 형태로 제공하고 VLAN을 구현하기 위해 AWS보안 그룹이나 가상 사설 클라우드 를 사용한다. 아니면 모드 프록시와 같은 소프트웨어가 소프트웨어 부하 분산기의 역할을 할 수 있다. 

데이터베이스 확장

- 서비스의 가용성과 데이터의 내구성 : 둘의 개념은 분리하여 다른 해결책을 찾아야 한다. 대기 모델도 주 DB를 백업으로 바꾸거나 할 수 없다면 가용성을 얻을 수 없다. 

- 읽기용 확장 : 읽기만을 위한 복제도 있다.  

- 쓰기용 확장 : 샤딩 - 노드 

- 공유 데이터베이스 인프라스트럭처, CQRS

캐싱

성능 최적화의 방법으로 연산의 이전 결과를 저장하여 연속된 요청일 경우 재연산을 위한 시간과 자원 소비 없이 저장되 있는 값을 사용할 수 있게한다. 

- 클라이언트 측, 프록시, 그리고 서버측 캐싱 : 클라이언트 측 캐싱은 클라이언트가 캐싱된 결과를 저장하는 것으로 클라이언트가 새로운 복사본을 가져올 싲머과 여부를 결정한다. 이상적으로는 하위 서비스가 힌트를 제공하며 클라이언트는 그 응답을 통해 해야 할 것을 이해하고 새로운 요청의 시점과 여부를 알 수 있다. 프록시 캐싱은 클라이언트와 서비 사이에 프록시를 배치하는 것이다. 가장 좋은 예는 리버스 프록시나 콘텐츠 전송 네트워크를 사용할 경우다. 서버 측 캐싱은 서버가 캐싱의 책임을 지고 레디스나 멤캐시드 또는 단순한 인메모리 캐시 같은 시스템을 활용한다. 어떤걸 쓸지는 최적화 하려는 대상에 좌우된다. 1번은 네트워크 호출을 대폭 줄이고 서버의 하위 서비스에 대한 부하를 줄일 수 있는 가장 빠른 방법이며 2번은 클라이언트와 서버에 독립적이다. 프록시가 일반적인 트래픽을 캐시하도록 설계되었다면 하나 이상의 서비스도 캐싱할 수 있다. 흔한 예는 스퀴드나 바니시 처럼 모든 HTTP 트래픽을 캐시하는 리버스 프록시다. 3번은 클라이언트에 독립적이다. 서비스 경계 내부 또는 근처에 캐시를 배치하면 데이터의 무효화 또는 캐시 적중률 추적과 최적화 같은 것을 추적하기 쉽다. 

동적 서비스 레지스트리

- 칸슬 : 환경 구성 관리 + 서비스 발견. 서비스 발견을 위한 HTTP 인터페이스 제공. 실제 DNS 서버 기능 제공.

- 주키퍼, 유레카, 직접만들기 

문서화 서비스

- 스웨거 : API 문서 웹으로 

- HAL과 HAL브라우저, 자기 기술 시스템



+ Recent posts