A Tale That Wasn't Left

양철웅의, 특별히 주제를 정해두지 않은 이야기들

RSS

Regarding Network Software Robustness
Posted on Tuesday, November 2, 2010.

1st draft: 2 November 2010
양 철 웅  (cwyang)
cwyang.tistory.com

이 글에서는 네트워크 소프트웨어의 안정성을 강화하기 위한 방안을 기술한다.

네트워크 상의 소프트웨어에게 있어서 안정적이라는 의미는 크게 두 가지로 나눌 수 있다. 그 하나는 제품이 안정적이라는 의미(product robustness)이며 다른 하나는 운영이 안정적으로 이루어질 수 있음(operational robustness)을 의미한다.

제품이 안정적이라는 것은 쉽게 말하여 소프트웨어에 버그가 없음을 의미한다. 소프트웨어가 크래시가 발생하지 않으며, 제작 의도대로 올바른 동작을 한다는 것이다. 개인 사용자를 대상으로 하는 소프트웨어의 경우는 제품 (사용)의 안정성이 가장 중요하다. 운영이 안정적이라는 것은 네트워크 소프트에 있어서 결국 사용 품질을 결정할 수 있는 종단 사용자에게 불편을 끼치지 않는다는 것을 의미한다.

제품은 오류가 없이 안정적이지만 운영이 불안할 수도 있다. 라우터의 경우를 예로 들면 한계 처리 용량보다 많은 용량의 트래픽이 들어올 경우 패킷 로스가 발생하여 서비스 품질이 떨어진다. 이러한 경우 그 이유를 제품이 명확히 제시할 수 없다면 이 제품은 오류는 없으나 운영 면에 있어서 약점이 있는 것이다. 반대로 오류가 많아도 운영이 안정적일 수도 있다. 제품 설계 자체가 액티브-스탠바이 이중 구조로 되어 있어 장애가 발생할 경우 자체 감지하여 백업 처리가 이루어진다면 실 운영 상에는 아무 문제가 없다. 실질적으로 모든 부분을 장애에 강하게 설계하기 힘들기 때문에 많은 경우 제품의 오류는 운영의 불안정을 초래한다. 하지만 확실한 것은 제품의 안정성 및 운영의 안정성 두 가지 모두가 네트워크 소프트웨어의 경우 중요하다는 것이다.

안정적인 제품은 테스트를 통해 만들어진다. 제품은 모니터링(계측)을 통하여 안정적인 운영이 이루어진다.

먼저 테스트에 대하여.

테스트를 통해서 제품을 안정화 할 수가 있기 때문에 개발 방법론으로서 테스트 주도 개발(test-driven development)이 주목을 받고 있다. 또한 대안 언어로서 주목 받고 있는 프로그래밍 언어 중에는 ML, Haskell, Erlang등이 있는데, 이들의 공통점은 함수형 언어라는 것이다. 함수형 언어는 입력 값에 대응하여 결과를 출력하는 메카니즘에 집중하며, 사이드 이펙트를 악의 축으로 삼는다. 테스트 기반 개발은 유닛 테스트를 반드시 만들도록 하고, 개발 중의 중간 단계에서부터 유닛 테스트를 통과해야만 되도록 하여 테스트를 강제화 한다. 함수형 언어는 프로그램의 기본 단위가 사이드 이펙트가 없는 함수이다 보니 유닛 테스트를 쉽게 만들 수 있다는 장점을 가진다. 이 두 가지 개발 메카니즘은 제품의 품질 측면에서 상당한 효과를 가져온다고 알려져 있다.

그러면, 이 두 가지 개발 메카니즘을 적용하지 않았던 소프트웨어에 대해서는 어떻게 하여야 하는가? 유닛 테스트도 코드 베이스를 많이 커버하지 못하고, 복잡한 로직과 사이드 이펙트들로 인해 굉장히 난감한 상황을 만들어내는 소프트웨어라고 한다면… 코드 베이스를 모두 버리고 무에서 다시 시작해야 하는가? 그것도 나쁜 선택은 아니라고 생각하지만… 그것이 선택지가 되지 않는 경우는 대개 “테스트를 최대한 많이 한다” 라는 접근 방법을 택한다. 그러나 테스트를 최대한 많이 하는 것 보다 더 중요한 것이 있는데, 그것은 테스트를 하기에 앞서서 제품 자체를 테스트가 가능하도록 보완하여야 한다는 것이다.

다음은 모두 같은 이야기다.

기획 단계에서부터 테스트를 염두에 둔 기획이 들어가지 않으면 나중에 돌아오는 것은 개발자로부터의 “이 제품은 네트워크 소프트웨어라는 특성 상 테스트가 힘듭니다"라는 말이다.
최근의 개발방법론에서 QC팀이 있는 경우 기획단계에서부터 참여를 권하는 것은 이러한 이유이다.

두 번째, 모니터링에 대하여.

네트워크 소프트웨어가 잘 운영되고 있는 지를 알기 위해서는 운영 상태를 계측(measure)해야 한다. 즉, 계측을 통해 다음 사항을 알 수 있어야 한다.

계측 대상은 여러가지가 있겠지만, 계측 방법은 외부에서 계측하는 방법과 자기 자신이 계측하는 두 가지로 나뉘어진다. 외부에서 계측하는 것에 의한 장점은 네트워크 소프트웨어의 특성 상 피어(peer)를 효과적으로 시뮬레이션 할 수 있다는 것이다. 계측 주체가 분리되어 있으므로 계측 대상의 오류에 자유롭다는 장점 또한 존재한다. 자기 자신이 계측하는 방법은 외부 계측에 비해 소프트웨어의 모든 상태를 알 수 있다는 점에서 장점이 존재한다.

어떤 파라메터를 어떤 방법으로 계측하여 위에 언급된 소프트웨어 운영에 필수적인 안정성을 답보할 것인가. 이것 역시 기획 단계에서부터 미리 고려되어야 한다.

즉, 중요한 것은 소프트웨어를 “Testable”하며 “Measurable”하게 기획, 개발해야 한다는 것이다. 만약 그렇게 되어 있지 않다면, 그렇게 되도록 소프트웨어를 개선하는 것이 제일 먼저 해야 할 일이라는 것이다.

Testable Software

소프트웨어를 테스트 가능하게 만든다는 것은 (1) 소프트웨어의 구성 요소인 함수가 테스트 가능하며 (2) 소프트웨어가 구현한 기능이 테스트가 가능하다는 것이다. 또한 테스트가 가능하다는 것은 (Input, Environment) 쌍이 결정되면 반드시 유일한 Output이 존재한다는 것이다. 이 때에 Environment는 소프트웨어의 상태(state)일 수도 있고, 외부의 환경일 수도 있다. 많은 경우에 있어서 Input/Output보다 Environement는 복잡한 상태를 가지게 되므로 Environment가 Test에 영향을 미치지 않을 경우 테스트는 보다 용이해지며 궁극적으로 사람의 개입 없이 자동화가 가능하다. 함수형 언어가 각광 받는 것은 각 함수에 대한 테스트 - 유닛 테스트 - 에 있어서 복잡한 상태인 Environment를 고려하지 않아도 되기 때문에 쉽게 테스트를 할 수 있고, 프로그램의 로직도 단순해지기 때문이다. 이와 마찬가지로 기능을 테스트 함에 있어서, 각 기능이 Environment에 의존하지 않거나 의존성이 매우 적으며, Input에 대한 Output의 검사가 용이하다면 기능 테스트 역시 쉽고 자동화될 수 있으며 소프트웨어의 안정성이 향상된다.

테스트를 감안 하지 않고 기획, 설계된 소프트웨어의 취약성은 위에 언급된 주로 Input에 대한 Output의 검사에 대한 메카니즘의 부재에 기인한다.

전형적인 네트워크 소프트웨어는 다음의 구성 요소를 가진다.

각 요소는 모두 중요하다. 일단 설정이 완료된 상태에서는 네트워크 처리 부만이 운용에 관여하므로 상대적으로 그것이 가장 중요하나, 사용자의 UX측면에서는 다른 두 부분도 중요하다. 고객들 (그리고 경영진, 심지어는 개발자까지)은 대개 네트워크 처리 부에 비하여 UI, 설정 처리부가 중요하지 않으며 개발 및 설계 난이도도 낮다고 생각하는 경향이 있는데, 이는 물론 사실과는 다르지만 이것이 의미하는 것은 난이도가 높은 부분에서 오류가 발생하면 일정 부분 수긍하지만 난이도가 낮(다고 생각하는)은 부분에서 오류가 발생하면 제품 자체의 신뢰성을 의심 받게 된다는 것이다.  최근의 아이폰 등의 성공은 어플리케이션 로직보다는 완벽한 UX를 제공하고 있다는 것에 기인한다. 네트워크 소프트웨어의 사용자라면 껍질을 보기보다는 열매를 볼 것이라고 기대하는 것은 경험상 섣부른 판단이다.

따라서 UI, 설정 처리부, 네트워크 처리부는 모두 테스트가 가능하여야 한다. 여기서부터는 제품의 특성에 따라 테스트의 방식이 달라지지만, 공통적으로 고려해야 할 사항들을 기술한다.

UI

설정 처리부

네트워크 처리부 - I

네트워크 처리부 - II

소프트웨어가 이들 요건을 만족하였다면 다음과 같은 장점을 기대할 수 있다. (1) 테스트 수트test suite를 용이하게 만들 수 있다. (2) 만들어진 테스트 수트는 개발 단계에서 개발을 보조하기 위하여 사용된다. (3) 또한 회귀테스트regression test로 사용된다. (4) 제품이 프로덕션production 사이트에 배치되었을 때에 발생한 최악의 상황을 풀어나갈 수 있다.

Measurable Software

테스트 가능testable하도록 소프트웨어를 만들고, 충분히 테스트를 거듭한다면 훌륭한 품질의 소프트웨어가 탄생한다. 그러나 프로덕션 사이트에서는 (아무리 기획과 설계가 완벽했다 할 지라도) 항상 예기치 못했던 상황이 발생하여 문제가 나타난다. 기획이나 설계에서 세운 가정에 들어맞지 않는 상황을 맞이한다던가, 각 기능들이 복잡하게 서로 연관되는 가운데 오류가 나타난다던가, 많은 연결 혹은 과도한 양의 트래픽을 처리함에 있어서 성능 상의 문제를 겪게 된다던가 하는 것은 드문 일이 아니다. 일단 이러한 이상 상황이 발생하는 것을 알 수 있다면 개발자는 적절한 조사 및 조치를 통해 상황을 해결 할 수 있다. 특히 테스트 가능한 소프트웨어라면 큰 난관을 겪지 않을 수도 있다. 그러나 이상 상황이 발생한 것을 쉽게 알 수 없다면 해결도 할 수 없다. 이것은 큰 문제가 아닐까?

이상 상황이 발생했는데 어떻게 모를 수가 있는가 하고 반문할 수 있으나, 이상 상황이 발생했는데 꼭 알 수 있다는 보장은 없다. (1) 이상 상황인지 아닌지 모르는 경우: 설계에 의하면 100km/h를 내야 하는 자동차가 실제로 70km/h밖에 나오지 않을 때. 운전자가 설계자가 아닌 다음에야, 아 이 자동차는 70km/h밖에 안 나오는구나… 라고 생각하기 마련이다. (2) 이상 상황이 불규칙하게 발생하는 경우: 키를 돌렸을때 가끔씩 시동이 안걸리는 경우. 운전자가 차에 대한 기대치가 높지 않으면 원래 세상의 이치는 그럴 수도 있다.. 라고 생각 할 수 있다. 물론 브레이크를 밟을 때 가끔 제동이 안 되는 경우는 예외지만. (3) 이상 상황이 제품 탓인지 주위 환경 탓인지 알 수 없는 경우: 키를 돌려도 시동이 안 걸리는데 창문을 열고 보니 다른 사람들도 다 시동을 못 걸고 있다. “어떻게 된 일이죠?” “이 근처는 가끔 전자 펄스 충격파EMP shockwave가 터지는 데라서 그런가 봐요.” 자동차는 정상일까? (4) 이상 상황이 발생해도 이용에 지장이 없는 경우: 가솔린 엔진이 운행중 정지해도, 하이브리드 자동차는 배터리의 힘으로 운행을 계속한다. 계기판을 특별히 주의 깊게 보지 않는 운전자는 가솔린 엔진이 정지한 것을 전혀 모른다.

중요한 것은 이상 상황을 파악하는 것, 대처는 그 다음 문제이다. 네트워크 소프트웨어의 운용에 있어 검토하여야 할 사항을 다음과 같이 제시한다.

운영 환경

시스템 부하

컴퍼넌트 상태

세션 처리 시간

제약 조건 확인

위에 기술한 다섯 가지 종류의 정보를 파악할 수 있어야 만이 안정적인 운영이 가능하다. 각 정보는 운영자가 요청하는 즉시 파악될 수 있어야 하며,  과거의 값이 로그나 MRTG 형태로 저장되어 어떠한 시점에 운영 상황의 변화가 있었는지 알 수 있어야 한다. 이렇게 과거의 정보들이 저장되는 경우 베이스라인에 기반한 이상 변화를 감지하여 알려주는 방법 또한 적용을 검토할 수 있다.

위의 다섯 가지에 다음의 추가도 검토해 볼 수 있다.

기능 확인

안정적인 소프트웨어의 운영을 위해서는 위에 기술된 여러가지 정보를 소프트웨어가 제공할 수 있어야 한다. (1) 즉, 기획/설계 단계에서 어떠한 운영 정보를 제공할 것인가를 결정하여야 한다. (2)그 다음에는 결정된 정보를 과거 이력을 용이하게 검토할 수 있는 형태, 즉 RRDTOOL이나 MRTG형태로 제공 해야 한다. (3) 만약 이미 구축되어 있는 시스템에서  해당 정보가 부족하다면 해당 정보를 신규로 제공하도록 하거나, 기존에 기록하고 있는 로그를 주기적으로 처리하여 분석이 용이한 형태로 이차 가공하여 사용할 수도 있다. (4) 일단 분석이 가능한 형태로 데이타가 수집된다면, 그를 운영자에게 제공하여야 한다. 제공하는 방법은 여러가지가 있을 수 있겠으나 중요한 것은 한 화면, 테이블, 혹은 리포트 형태로 _일목요연_하게 제공하여야 한다는 것이다. 알람, 베이스라인 분석등 형태 자체는 부차적인 결정 사항일 뿐이다. 운영자가 항상 띄워 놓는 웹 페이지 하나에서 시스템의 정상/비 정상만 알 수 있다면 충분한 것이다.


Tags: blog, software development, measurement, monitoring, quality, robustness, software, test