Akashic Records

안정성 패턴 본문

오래된글/Articles

안정성 패턴

Andrew's Akashic Records 2018. 4. 19. 15:01
728x90

안정성 패턴

1. 제한시간을 활용하라.

제한 시간은 응답이 오지 않을 거라고 생각될 때 기다리는 것을 멈추게 하는 간단한 메커니즘이다.

잘 배치된 제한시간은 오류를 차단한다. 그래서 다른 시스템, 서브시스템 또는 다른 장치의 문제가 여러분의 문제가 될 필요가 없다. 불행히도 하드웨어의 지저분한 세상을 멀리 떠나 고수준의 추상화로 다가갈수록, 제한시간을 잘 배치하는 일이 점점 드물어진다. 정말 많은 고수준 API에서 분명한 제한시간 설정이 드물거나 아예 없다. 벤더가 제공한 클라이언트 라이브러리는 제한시간이 없는 것으로 악명 높다.

클라이언트의 관점에서, 오래 기다리게 하는것은 매우 나쁘다. 제한시간 때문에 작업을 마치지 못한다면, 결과를 돌려주는 것이 낫다. 그 결과는 실패일 수도, 성공일 수도, 또는 추후 작업을 위해 작업을 큐에 올려놨다는 통지일 수도 있다.

  • 통합 지점이나, 블록된 스레드, 느린 응답에 적용하라. - 제한시간 패턴은 통합 지점으로의 호출이 블록된 스레드가 되는 것을 방지한다. 그리하여 연속적인 고장을 막는다.

  • 예측하지 못한 고장에서 회복시키고자 할 때 적용하라. - 작업이 너무 오래 걸리 때, 때로 그 이유에는 관심이 없다면, 그냥 포기하고 다음 작업으로 넘어가야한다.

  • 천천히 재시도 하는 것을 고려하라. - 제한시간을 초과하는 것에 대한 대부분의 설명은, 네트워크나 당장 해결될지 않는 원격 시스템의문제를 포함한다. 즉시 재시도하면 동일한 문제가 생기고 또 다른 제한 시간을 일으킬 가능성이 높다.


2. 차단기

차단기는 전체 시스템이 파괴되지 않고 하나의 서브시스템이 고장 나게 하기 위해 존재한다. 더 나아가, 위험이 사라진 후 차단기는 시스템 전체 기능이 회복되게 복구될 수 있다.

차단기는 작업을 다시 실행하기보다는 막기 위해 존재한다는 점에서 재시도와는 다르다.

차단기가 열렸을 때, 모든 호출은 즉시 실패한다. 이 상황은 어떤 형태의 예외로 표시될어야 할 것이다. 사용자에게 적절한 피드백을 주기 위해 차단기가 열릴 때마다 다른 형태의 예외를 던지면 유용하다. 이렇게 하면 호출하는 코드가 이런 예외 형태를 별도로 취급할 수 있다.

  • 문제를 일으킨다면 호출하지 마라. - 차단기는 모든 방식의 통합 지점 문제로부터 시스템을 보호하는 기본적인 패턴이다.

  • 제한시간과 같이 사용하라. - 차단기는 통합 지점에 문제가 있을 때 호출하지 않게 한다. 제한시간 패턴은 통합 지점에 문제가 있음을 지적해 준다.

  • 상태 변화를 노출시키고, 추적하고, 보고하라. - 차단기의 상태가 변한다는 것은 항상 심각한 문제가 있음을 나타낸다. 보고되고, 기록되고, 경향과 연관성이 파악되어야 한다.


3. 칸마기

시스템을 나눔으로써 시스템의 한 부분에서의 고장이 모든 것을 파괴하는 것을 막을 수 있다. 물리적 이중화가 칸막이의 가장 일반적인 형태이다.

  • 배의 일부분을 구하라. - 칸막이 패턴은 안 좋은 일이 생길 때 부분적인 기능을 보존하기 위해 용량을 분할한다.

  • 효율이 떨어지는 리소스의 사용을 받아들일지 결정하라. - 시스템이 위기에 빠지지 않았을 때, 서버를 분할하는 것은 각 분할이 비축 용량을 더 많이 필요로 한다는 것을 의미한다. 모든 서버가 하나로 묶이면, 전체 비축 용략이 떨어진다.

  • 적절한 세분화를 선택하라. - 어플리케이션에서 스레드 풀을, 서버에서 CPU를, 클러스터에서 서버를 분할 할수 있다.

  • 공유된 서비스 모델에서는 매우 중요하다. - 서비스 지향 아키텍처에서는 어플리케이션에 의존한 엔터프라이즈 시스템이 많이 있을 수 있다. 연쇄 반응 때문에 어플리케이션이 죽어 전체 회사 시스템이 정지한다면 칸막이를 두는 게 낫다.


4. 정상 상태

  • 만지작거림을 피하라. - 인가느이 개입으 ㄴ문제를 야기한다. 시스템이 수종 디스크 비우기나 매일 방 다시 시작하는 일 없이 최소한 전형적인 개발 사이클 동안 실행되어야 한다.

  • 어플리케이션 로직으로 데이터를 비워라. - DBA는 데이터를 비우기 위해 스크립트를 만들 수 있지만. 데이터가 제거되었을 때 어플리케이션이 어떻게 행동해야 할지 항상 아는 것은 아닌다. 논리적 무결성을 유지하려면 어플리케이션이 자신의 데이터를 비워야 한다.

  • 캐싱을 제한하라. - 메모리 내 캐싱은 어플리케이션의 속도를 올리자만 나중에는 속도를 떨어뜨린다. 캐시가 소비할 수 있는 메모리 량을 제한하라.

  • 로그를 옮겨라. - 로그 파일을 무한정 보관하지 마라. 크기에 따라 로그 파일을 순환하도록 설정 하라. 추후 대응을 위해 보존해야 한다면 실전 서버가 아닌 데다가 보존하라.


5. 빠른 고장

응답이 전혀 없는 것보다 느린 응답이 나쁘다면, 가장 나쁜 것은 느리 실패한 응답이다. 시스템이 동작하다 실패할지 미리 결정할 수 있다면, 늘 빨리 실패하는 편이 낫다. 이런 식으로 하면, 호출자는 기다리면서 자신의 용량을 허비하지 않아도 된다. 시스템은 다른 일을 할 수 있다.

웹 어플리케이션에서 빨리 실패하는 다른 방법은 EJB나 도메인 객체를 불러오기 전에 요청을 받는 서블릿이나 컨트롤러에서 기본적인 매개변수 확인을 실행하는 것이다. 그러나 도메인 객체의 캡슐화를 위반하지 않도록 주의해야 한다.

빨리 실패할 때도, 시스템 실패를 어플리케이션 실패와 다르게 보고하라.

  • 느린 응답을 피하고 빨리 실패하라. - 에러 메시지를 기다리게 만들지 말고, 더욱이 제한시간에 걸릴 때까지 기다리게 하지 말라.

  • 리소스를 예약하고 통합 지점을 미리 확인하라. - 시작 전에 트랜잭션을 완료할 수 있는지를 확인하라. 핵심적인 리소스를 사용할 수 없다면, 그 지점으로 가서 일을 낭비하지 마라.

  • 입력 확인을 사용하라. - 리소스 예약 전에도 기본적인 입력을 확인하라.


6. 핸드셰이킹

핸드셰이킹은 통신을 조절하는 장치들 사이에서의 신호법을 말한다. 직렬 RS-232 프로토콜은 데이터를 받을 준비가 되었다는 것을 알리기 위해 수진자에 의존한다.

HTTP는 핸드셰이킹을 잘 사용하지 않는다. HTTP에 기반한 XML-RPC나 WS-I Basic 같은 프로토콜은 핸드셰이킹에 사용할 수 있는 선택사항이 거의 없다.

핸드셰이킹은 서버가 자신의 작업부하를 조절함으로써 자신을 보호하는 모든 것이다. 주어진 요구의 희생자가 되는 대신, 서버는 들어오는 작업을 거절할 방법이 있어야 한다.

전반적으로 핸드셰이킹은 흔히 사용되지는 않지만 애플리케이션 계층 프로토콜에 적용했을 때 큰 장점을 얻을 수 있는 기법이다. 연속적인 고장의 경우와 같이 다른 곳에 크랙을 퍼트리는 계층에서 크랙을 멈추는 효과적인 방법이다.

  • 협력적인 요구 제어를 만들어라. - 클라이언트와 서버 간의 핸드셰이킹은 서비스가 가능한 수준으로 요구를 조절하게 허용한다. 클라이언트와 서버 모두 핸드셰이킹을 수행하도록 만들어져야 한다.

  • 상태 확인을 고려하라. - 상태 확인 요청은 프로토콜에 핸드셰이킹이 없는 경우 어플리케이션 수준의 대안이다. 호출해서 실패하는 비용보다 추가 호출의 비용이 현저히 낮다면 상태 확인 요청을 고려하라.

  • 자신의 프로토콜에 핸드셰이킹을 만들어라. - 자신의 소켓 기반 프로토콜을 만든다면, 그 안에 핸드셰이킹을 만들어서 종단점마다 다른 종단점으로 작업을 수용할 준비가 되었을 때 알리게 하라.


7. 테스트 하니스

소프트웨어 컴포넌트의 테스트를 가능하게 하거나 프로그램의 입력을 받아들이거나 빠진 컴포넌트의 기능을 대신하거나 실행 결과와 예상 결과를 비교하기 위하여 동원된 소프트웨어 도구 또는 부분적인 테스트를 위하여 코드에 삽입하는 프로그램을 테스트 하니스(Test Harness)라고 한다.

  • 사양 외 고장을 본떠라. - 실제 어플리케이션을 호출하면 그 어플리케이션이 고의로 만든 어레만을 테스트 할 수 있다. 좋은 테스트 하니스는 뒤섞이고 실질적인 온갖 종류의 고장 유형을 시뮬레이션하게 한다.

  • 호출자에 스트레스를 가하라. - 테스트 하니스는 느린 응답, 무응답, 쓰레기 응답을 만들 수 있다. 그런 후 , 어플리케이션의 반응을 볼 수 있다.

  • 공유된 테스트 하니스는 공통 고장에 대해 지렛대 효과를 가져온다. - 통합 지점마다 테스트 하니스를 구분할 필요는 없다. '킬러' 서버는 여러 포트에서 대기하면서 어떤 포트에 연결되었느냐에 따라 서로 다른 고장 유형을 만들 수 있다.

  • 다른 테스트 방식으로 대체하는 대신 보충하라. - 테스트 하니스 패턴은 다른 테스트 방식을 증가시킨다. 단위테스트, 인수 테스트, FIT 테스트 등을 대체할 수 없다. 이런 기법 각각은 기능적 작동방식을 확인하는데 도움을 준다. 테스트 하니스는 원격 시스템으로부터 격리시킨채, 비기능적 작동방식을 확인하는데 도움을 준다.


728x90

'오래된글 > Articles' 카테고리의 다른 글

Android Inter-App Communication  (0) 2018.04.19
Getting all EJB home interface object from a HashMap  (0) 2018.04.19
Android Thread 내에서 UI 핸들링  (0) 2018.04.19
Java VM Core Dump 분석  (0) 2018.04.19
Java Memory Model  (0) 2018.04.19
Comments