본문 바로가기
IT-개발트렌드

[IT/개발] 버그 없는 프로그램은 없다

by SB리치퍼슨 2010. 10. 7.

http://www.zdnet.co.kr/builder/system/etc/0,39031682,39147115,00.htm

 

 

버그 없는 프로그램은 없다

최진호 (한국 IBM 소프트웨어)   2006/05/04
때는 바야흐로 거미줄력 12년, 버너스 경이 웹과 브라우저를 만들고 웹의 지배 아래 세상이 마우스 클릭질로 시끄럽기 그지없던 시절이었다. 초기의 웹은 그저 집 없는 개인 사용자의 한풀이용으로 홈페이지 제작 기술을 위해 쓰이던 것이었지만 점차 그 허접하던 초기 기술적인 한계를 극복하고 수많은 천재들과 박사들의 컨설팅, 아키텍팅 그리고‘노가다’를 바탕으로 이제는 꽤나 위험할 듯 하고 시스템이 중지되어 버리면 범국가적 위기 상황으로 번질 만한 부분에도 웹이 야금야금 지배하기 시작했다. 바야흐로 전 세계가 거미줄에 대롱대롱 매달려서 살아가고 있는 것이다.

웹은 편하고 단순하고 빠르다. 게다가 돈도 별로 들지 않는다. 이렇게 너도 나도 다 웹 동네에서 살다보니‘가지 많은 나무 바람 잘 날 없다’고 웹 시민들을 끊임없이 괴롭히는 존재가 있었으니 바로 버그라는 놈이었다. 웹 버그는 웹 초기에는 단순히 소스코드 상에서만 숨어있어서 웹 개발자들이 쉽게 끄집어내어 처리하는 것이 가능했으나 점차 웹의 세계가 복잡해지면서 단순히 개발자가 처리할 수 있는 수준을 넘어서게 되었고 이 버그를 해결하는 데 수많은 인력이 투입되기 시작한다. 범기업적, 범국가적, 범세계적으로 문제를 일으킬만한 버그들이 하나 둘 씩 모습을 드러내면서 웹 시민들은 더 이상 이 웹을 좌시할 수 없게 되었으니 이것이 바로 버그 사냥꾼이라는 직업이 태어나게 된 계기가 되었다.

버그 사냥꾼이란?
그렇다면 버그 사냥꾼은 어떤 사람들이며 무슨 일을 하는가? 앞에서도 말을 했지만 웹이 주체할 수 없을 만큼 거대하고 복잡해져 버렸다. 우리가 웹 기반 하에서 서비스를 개발하면 과거에는 해당 서비스를 위해 필요한 다양한 아키텍처적인 요소들을 고려해서 해당 요소들을 거의 모두 개발해야만 했다. 왜냐? 기반이 없었으니까. 즉 보안이나 신뢰성, 성능, 데이터 정합성, 트랜잭션, 확장성 등 거의 모든 부분에서 개발자와 아키텍트들은 그들의 창조성과 능력을 발휘할 수 있었고 그들의 역량에 따라 프로젝트의 실패 유무가 잇따랐다.

사람들은 어떻게 하면 더 예술적이고 효율적으로 시스템을 개발할 수 있을지 고심했고 더 나은 시스템 아키텍처가 있으면 감탄했고 박수를 보냈다. 그러나 시간이 흘러가면서 사람들은 그것이 얼마나 위험천만한 일이고 고비용이 들어가는 일인지를 깨달았고 개발자와 아키텍트가 선별하고 고심해야 했던 아키텍처 요소들을 대신 처리해줄 수 있는 여러 컴포넌트와 미들웨어 제품들을 사용하기 시작했다. 이러한 선택은 웹 시스템 개발에 들어가는 인력과 시간을 줄여주는 듯해 보였고, 점차 순수한 소프트웨어 아키텍트는 손가락을 빨게 됐다. 이제 개발자가 하는 일이라고는 웹 화면의 단순한 인터페이스 노가다이거나 단순 로직에 대한 작업 등을 벗어나지 못했고 이러한 단순 노가다만으로도, 별다른 수고없이 보안이나 성능, 트랜잭션, 확장성 등이 어느 정도 이상 충족되어 가고 있었다. 결국 개발자가 작업한 내용은 전체 시스템에서 보자면 빙산의 일각이었고 눈에 보이는 소스코드 이면에는 그것들에 대한 아키텍처 요건들을 처리해주는 수많은 컴포넌트와 미들웨어 제품들이 얽혀있는 상황이 된 것이다.

문제는 여기에서 발생한다. 웹 시스템에 버그가 발생했을 때 이제는 개발자 한 두 사람이 분석해서 원인을 파악하는 것이 불가능해질 정도로 종합적인 문제 분석 능력이 필요해진 것이다. 때문에 웹 시스템에 버그가 발견되면 해당 사이트에 하드웨어 전문가와 네트워크 전문가, DB전문가, 미들웨어 전문가, 개별 컴포넌트 제품 전문가, 개발자, 운영자 등이 모여서 어디서 문제가 발생한 것인지를 종합적으로 분석해야 하는 상황이 발생하는 경우가 다반사가 되었다. 그래서 이 장애 전문 해결사로서 버그 사냥꾼이라는 직종이 탄생하게 되었다.

버그 사냥꾼 중에서도 특히 미들웨어 전문가의 역할이 매우 중요하게 되었는데, 거의 모든 문제가 발생하는 첫 번째 장소이자 시작 시점으로 거론되는 곳이 바로 이 미들웨어 쪽이기 때문이다. 즉 과거에는 개발로서 해결하던 여러 가지 요소들이 미들웨어 쪽에서 처리되면서 크리티컬한 부분에서의 버그 역시 미들웨어가 처리하게 되었다. 때문에 미들웨어 쪽 버그 사냥꾼의 지식 체계는 넓고 깊다. 왜냐하면 실제로는 하드웨어나 네트워크에 문제가 있어도 일단은 미들웨어에서 문제가 감지되고 소스코드 상에서 버그가 있어도 미들웨어에서 발견할 수 있다. 성능이 문제여도 미들웨어 쪽에서 전체적인 분석을 해야 하는 상황이다 보니 미들웨어 쪽 버그 사냥꾼은 만물박사가 되지 않을 수가 없다. 그들은 때때로 성능이나 개발에 대한 작은 컨설팅까지 해가며 웹 시민들의 안녕을 위해 고군분투하고 있다.

버그 사냥꾼 스파이크
그래서 이번 기사에서는 버그 사냥꾼 스파이크씨를 소개할까 한다. 그는 모 회사에서 판매하고 있는 웹 애플리케이션 서버 제품에 대한 기술지원을 담당하고 있는 경력 5년의 버그 사냥꾼이다. 그가 주로 하는 일은 회사가 판매하고 있는 제품을 구매해서 쓰고 있는 고객들이 개발이나 운영 중에 제품에 문제가 발생했을 때 문제를 해결해주는 것이다. 그러나 웹 애플리케이션 서버라는 것이 위로는 사용자의 요청을 받아서 일차적으로 처리하는 웹 애플리케이션과 맞닿아 있고 아래로는 DB나 네트워크, 하드웨어, Legacy 등의 리소스와 연결되어 있다보니 일단 고객이 뭔가 서비스가 되지 않으면 무조건 스파이크씨를 부른다. 그러면 스파이크씨는 전체 시스템을 모니터링하면서 문제의 원인을 분석하고 고객에게 해결책을 알려주는 것이다. 이런 그에게 최근 웹 시스템에서 발생하는 버그의 유형에 대해 의견을 물어보았다.

버그요? 말도 마세요. 버그 같은 버그, 정말 웹 애플리케이션 서버에 문제가 있어서 생기는 버그면 말도 안하죠. 미들웨어라는 게 눈에 보이지는 않으면서 하는 일은 무진장 많으니까 걸핏하면 저를 호출하는데요, 사실 일어나는 문제 중의 상당수는 개발 쪽이나 DB 그리고 서버에서 생기는 문제예요. 사이징을 제대로 하지 못해서 생기는 경우도 많죠. 그래도 일단 에러 로그는 웹 애플리케이션 서버 쪽에서 나오니까 일단 고객은 저를 부르는 거에요. 그런데 사실 요새에는 개발 쪽에서 생기는 버그도 많질 않아요. 워낙에 개발자들의 능력도 좋아졌지만 개발자들이 웹 개발에서 해볼만한 게 없거든요. 대부분의 중요한 로직들은 웹 애플리케이션이 해결해주니까 단순한 버그는 많지 않은거죠. 다들 버그, 버그 하지만 요새처럼 버그 잡기 어려운 시절이 어디 있겠어요? 버그 잡는 거 쉬운 노릇이 아니거든요. 하드웨어부터 개발까지 IT 지식 전반적인 것들을 다 알아야만 버그를 잡을 수가 있는거죠. 아무나 버그 사냥꾼 하는거 아니거든요.

횡설수설하는 스파이크씨의 인터뷰를 통해서 그가 얼마나 쌓여있는 할 말이 많은지 알 수가 있다. 버그 사냥꾼의 입장에서 과연 최근의 웹 기반 시스템에서 발생하는 버그의 유형은 어떠한 것들이 있는지 살펴보자.

버그의 종류
스파게티 코드와 리소스에 대한 정확한 사용
세상이 많이 변하고 변했지만 아직까지도 이런 허접한 코드를 보면 왕짜증이죠. 개인 홈페이지 만드는 것도 아니고 명색이 대기업 홈페이지라고 해서 들어가 보았더니 JSP 코드에 DB 호출하려고 JNDI 룩업해서 직접 DB랑 쿵작쿵작하는 걸 박아놓고 있더라구요. 정말 한숨부터 나옵니다. 그래도 좀 안다 하는 운영자분들은 미안해하기라도 하지요. 요즘 웹 개발에서 그나마 전체 시스템을 망가뜨릴 수 있는 이슈는 리소스 관리에요. 예를 들어 개발자가 코딩하면서 DB 리소스만 공손하게 사용해준다면 웹 애플리케이션에서 생기는 버그의 반 이상은 방지할수 있을 거예요. 그런데 JSP 코드에 로직과 뷰가 분리되기는커녕 오묘한 조화로 손잡고 있으면 정말 버그 잡기도 힘들 뿐더러 리소스에 대한 반환이 제대로 되는지 파악조차 사실 잘 안 되거든요. 확장성에도 문제가 있고. 아무튼 이런 구석기 시대코드는저질버그를양산하는창고같은역할을하는거죠.

스파이크씨도 과거에는 웹 개발자였다. 특히 그는 php 전문 개발자였는데 초짜시절에 그 역시 php로 무수한 스파게티 코드를 작성한 경험이 있다. 자유로운 php라는 언어의 특성상 개발 속도가 빨랐고 단시일 내에 원하는 사이트를 개발하는 것은 어렵지 않았지만, 초짜시절 그는 지인을 통해 아르바이트로 자그마한 컴퓨터 회사의 홈페이지를 php로 개발하게 되었다. 하루가 지나니 게시판이 생기고 또 하루 지나니 견적 페이지가 만들어졌다. 그렇게 후다닥 만들어진 홈페이지는 고객과 홈페이지 주인의 원망을 듣는 버그 투성이 사이트로 전락해버렸다. 객체지향이고 뭐고 없이 생각나는 대로 만들어진 스파게티 코드는 나중에 다시 고쳐보려 해도 어찌할 수 없을 만큼 복잡해진 말썽꾸러기가 되어버리고 만 것이다. 그러나 이런 사례는 사실 요 근래에는 많이 찾아볼 수 없거나 혹은 이러한 로직과 뷰의 분리가 완전히 되어 있지는 않더라도 중요한 비즈니스 로직 정도는 컴포넌트화 시켜놓는 것이 요 근래의 추세이다. 이것은 그동안 웹 기반 개발자들이 양적으로 뿐만 아니라 질적으로도 많은 향상을 보여왔음을 뜻하는 것이다.

스파게티 코드와 함께 웹 기반 시스템에서 웹 개발자가 실수하는 것들 중의 하나가 리소스에 대한 해제를 제대로 해주지 않아서 전체 시스템에 무리가 가게 만든다는 것이다. 또한 서블릿 사용시 쓰레드 기반 프로그래밍에 익숙하지 않은 개발자가 리소스 변수에 대한 잘못된 사용으로 인해 부하를 일으키는 경우도 종종 있는 일이다. 사실 이러한 현상은 무조건 개발자의 탓으로만 돌릴 것이 아니라 문제가 될 만한 소지가 있는 부분들을 미연에 방지할 수 있도록 별도의 공통 컴포넌트로 끄집어내서 통합관리를 하는 등의 개발 환경을 구축해 놓아야만 해결될 수 있을 것이다.

몇 달 전 스파이크씨가 고객의 요청으로 들어간 사이트에서 있었던 일이다. 평소에는 이상 없이 잘 돌아가던 시스템이 부하가 어느 정도 쌓이면 갑자기 행(hang) 현상이 발생하면서 웹 애플리케이션 서버가 죽어버렸다. 늘 있어왔던 현상이고 이런 경우 대부분 애플리케이션에서 리소스 관리를 제대로 하지 못했기 때문에 발생하는 경우가 다반사였다. 역시나 문제는 애플리케이션 쪽이었다. 각각의 JSP 코드에서 직접 DB 리소스를 가져와서 함부로 썼던 것이다. 즉 그 수많은 JSP 코드에서 직접 DB를 연결하여 필요한 작업을 수행하고서는 때때로 연결을 닫지 않기도 하고 예외처리도 엉성하게 되어 있었다. 더구나 JSP 코드는 로직과 뷰가 전혀 분리되지 않은 상태이다보니 문제를 해결하는것도 어렵기 그지없었다. 천상 스파이크씨는 고객에게 애플리케이션에서 DB 리소스 해제를 제대로 해주지 않은 것이 문제여서 발생한 것임을 보고했고, 되도록이면 DB 제어에 대한 부분은 기업 공통 컴포넌트를 작성하여 그것을 전사적으로 사용할 것을 권했다. 또한 웹 개발자들에게 좀 더 좋은 교육의 기회를 제공하여 웹 프레임워크나 기타 기업 내의 프레임워크 등에 대한 가이드라인을 다시 한 번 제시할 것을 권고했다.

이러한 스파게티 코드와 정확치 않은 리소스 사용으로 인한 버그는 많이 발생하기도 하지만 문제의 원인이 분명한 만큼 스파이크씨가 짜증내는 일면 쉽게 해결할 수 있는 범위에 속한다는 측면에서 반가운 현상이기도 하다. 하지만 스파이크씨가 다음으로 언급하는 여러 상황들은 스파이크씨에게도 참으로 버거운 버그들, 고급 버그들이다.

시스템 및 프레임워크에 대한 이해 부족
생각있는 운영자들이 가장 꺼려하는 것 중의 하나가 무엇인지 아세요? 최신 기술입네 하고 무턱대고 개발자들이 인기있는 오픈소스 프레임워크를 도입해서 써버리는 경우에요. 문제는 그 프레임워크가 얼마나 신뢰할만 하냐는 거죠. 그 프레임워크를 썼는데 막상 운영하고 보니 치명적인 문제가 발생하면 대체 누구에게 하소연하겠습니까? 개발자는 그제서야 부랴부랴 오픈소스를 뜯어고치거나 이미 어디론가 회사를 옮겨버린 후란 말이죠. 게다가 무턱대고 프레임워크를 도입해버리면 그 프레임워크를 알고 있는 개발자는 어떻게든 문제를 해결한다하더라도 향후 업그레이드나 확장을 해야 할 시점이 왔을 때 생소한 프레임워크 때문에 개발에 드는 비용보다 프레임워크를 이해하는 데 드는 비용이 더 커져버린다 이겁니다. 저도 지원을 하다보면 이렇게 프레임워크에서 문제가 발생한 경우에는 어떻게 손을 쓸 수가 없어요. 그 프레임워크를 들어내라고 할수도 없고 말이죠. 게다가 프레임워크의 철학을 제대로 이해하지도 못하고 써버리면 문제는 아주 골치아파지는 거죠.

자바 엔터프라이즈 기술 중 EJB는 상당히 성공한 컴포넌트 기반의 기술이다. 수많은 서적에서 EJB를 다루었고 마치 JEE의 수준 높은 개발을 이루려면 EJB를 써야 하는 것처럼 보이기도 한다. EJB는 결국 웹 기반 서비스에서 트랜잭션과 분산처리가 꼭 필요한 요소가 있을 때 그러한 위험을 대신 처리해주기 위해 탄생했다. 물론 비즈니스 로직에 대하여 EJB로 만들어두고 추후 두고두고 쓰겠다고 마음먹겠다면, 그리고 EJB라는 좋은 프레임워크 안에서 개발을 하겠다는데 말릴 사람은 아무도 없을 것이다.

그러나 EJB를 통해서 얻을 수 있는 것이 있다면 반대로 잃는 것이 있게 마련이다. 우선 속도의 문제를 들을 수 있다. RMI Call을 통한 분산 컴포넌트 기술이다보니 아무래도 직접 메쏘드 호출에 드는 비용보다 많을 수밖에 없다. 또한 EJB 기술을 충분하게 숙지하지 않은 개발자일 경우 잘못된 설계와 사용으로 인하여 오히려 사용 안하느니만 못한 결과를 종종 가져올 수 있다. 왜냐하면 EJB는 성숙한 JEE 기반의 설계 지식을 바탕으로 개발되었을 때 그 기능을 십분 발휘할 수 있는 것이지, 비즈니스 로직과 도메인 로직에 대한 분리 개념 없이 접근했다가는 큰코 다칠 기술이기 때문인 것이다. 이런 이유로 가뜩이나 무거운 JEE 환경에서 EJB 호출이 너무나 빈번히 발생하여 전체 시스템에 오버헤드가 일어나는 경우 그 결과는 느려진 서비스와 고비용으로 귀결될 뿐이다.

재차 강조하자면 앞에서도 언급했듯이 웹 기반 시스템에서의 버그가 점점 개별적인 소스코드에서 프레임워크나 전체 시스템단으로 옮겨오는 추세이다. 때문에 전체 시스템과 도입된 프레임워크에 대한 충분한 이해 없이 개발된 시스템은 결국 버그를 양산해낸다. 그 중에서도 프레임워크에 따른 폐해는 정말 심각하다. 문제는 해당 프레임워크가 검증되지 않았다는 것과 프로젝트에 참여하는 개발자 전원이 프레임워크에 대한 이해가 충분하느냐에 있다. 소프트웨어는 단지 바이너리 데이터 덩어리만을 의미하지는 않는다. 소프트웨어에는 고객이 있고 개발 프로세스가 있고 문서가 있으며 유지보수에 따른 절차가 포함된다. 이러한 소프트웨어의 필요충분조건을 무시하고 신뢰성에 대한 검증과 유지보수에 대한 확실한 책임 소지를 분명히 하지 않을 경우 어줍잖은 프레임워크 도입은 오히려 더 큰 버그를 양산하는 요소가 된다.

충분한 테스트 없이 운영
요새 프로젝트를 보면 개발에 걸리는 시간보다는 테스트에 걸리는 시간이 훨씬 많이 소요되고 그 중요성이 증대되고 있는것 같아요. 그만큼 운영 환경에서의 검증작업을 확실하게 한다는 얘긴데요. 그럼에도 불구하고 평상시에는 잘 돌아가던 것들이 운영 때만 되면 꼭 문제가 일어나요. 테스트할 때 제대로 운영 환경에 맞추어 시나리오를 구성하지 못했다는 것이고 운영 환경을 제대로 예측하지 못한 결과이기도 하죠.

지금도 여전히 스파이크씨는 운영 하루 만에 시스템이 정지된 고객의 현장에 출동하느라 여념이 없다. 그만큼 운영과 테스트는 다르다는 것을 입증하는 것이리라. 또한 이것은 단순히 운영과 테스트가 다르기 때문에 일어나는 당연한 현상이라고 넘겨버리기에는 아쉬운 무언가가 있다. 즉, 고객이 테스트의 중요성을 제대로 인식하지 못한 경우에 발생한다는 것이다.

며칠 전 스파이크씨는 고객의 신규 오픈 사이트 통합 테스트 현장에 출동했다. 테스트 중 웹 애플리케이션 서버에서 문제가 발생했을 때를 대비하여 같이 모니터링을 요청한 것이다. 테스트 현장에는 몇 명의 애플리케이션 개발자와 운영자 그리고 부하테스트 전문가들이 모여 있었다. 늦은 밤 시간이었고 개발자들은 하나같이 초췌함 일색이었다. 저녁 9시에 성능 테스트가 시작됐다. 그런데 테스트는 단 30분도 더 진행시킬 수가 없었다.왜냐하면 애플리케이션에서 버그가 발생했기 때문이었다!

스파이크씨는 황당했다. 분명 그 통합 테스트는 성능 테스트였다. 그렇다면 적어도 한번쯤은 애플리케이션에 대한 단위 테스트 정도는 해보았을 것이 아닌가? 스파이크씨가 개발자에게 물어보니 단 한번도 애플리케이션에 대한 통합 테스트를 이전까지 진행해본 적이 없다고 한다. 결국 그 날의 테스트 현장은 파장되었고 개발자는 성능 테스트에서 발생하여 접수된 버그를 해결하기 위해 밤을 샜다.

통합 테스트는 운영 테스트와 성능 테스트로 분류할 수 있고 이러한 통합 테스트 이전에 각각의 애플리케이션들에 대한 충분한 단위 테스트와 애플리케이션 별 통합 테스트가 선행되어야만 한다. 그런데 이러한 순차적인 과정을 무시하고 오픈이 얼마 남지도 않은 시점에서 개별 애플리케이션들에 대한 기본적인 버그조차 해결되지 않은 상황에서 성능 테스트한답시고 밤을 새워가며 애플리케이션 성능이 나오지 않음을 탓하는 경우를 스파이크씨는 가끔 목격하곤 한다. 테스트는 아무리 강조해도 지나치지 않으며 테스트 기간 산정은 시스템의 신뢰성을 가름하는 가장 중요한 잣대가 될 수도 있다.

제품에 문제가 있는 경우
버그 중에 저 같은 버그 사냥꾼들이 가장 무서워하는 것이 제품 버그죠. 새 버전의 웹 애플리케이션 서버가 출시되면 일단 처음에 겁부터 나요. 이번엔 어떤 버그가 있을까? 하구요. 제가 담당하고 있는 제품이 그래도 이 바닥에서는 유명하고 검증받은 제품인데도 가끔씩 황당한 버그를 발견하곤 하거든요. 세상에 버그없는 소프트웨어가 어디 있겠어요? 하지만 특히 웹 애플리케이션 서버 버그는 찾기도 어렵고 치명적인 경우가 많아서 신경이 많이 쓰이죠. 보통 문제가 발생한 사이트에 나가면 문제의 원인이 어디에 있는지 추적해 들어가는데, 전체 IT 인프라부터 개별 애플리케이션까지 다 추적해보거든요. 그런데 결국 추적의 방향이 웹 애플리케이션 서버 자체의 결함으로 결론지어지면 고객에게 할 말이 곤궁해져요. 금방 고칠 수 있는 거면 고치지만 제가 개발한 것도 아니다보니 시간이 길어질 수밖에 없어요. 아무튼 이런 경우 입이 바짝 바짝 마릅니다.

보통 고객에게 제품을 판매하기 전에 정말 이 제품이 제 성능을 발휘하는 지를 보여주기 위해 때때로 벤치마크 테스트를 고객이 보는 앞에서 시연하는 경우가 있다. 스파이크씨는 몇 달 전 고객에게 웹 애플리케이션 서버의 성능을 보여주기 위해 벤치마크 테스트에 참여했다. 테스트는 클러스터링된 환경에서 여러가지 패일오버(Failover)와 세션 클러스터링 그리고 고객의 샘플 애플리케이션에 대한 성능 테스트였다. 웹 애플리케이션 서버에서 클러스터링 기능은 가장 기본이 되는 기능이기 때문에 비록 새 버전의 제품이기는 하지만 결국 같은 제품 라인이므로 스파이크씨는 큰 무리없이 테스트가 진행되리라 생각했다.

그러나 이후 엄청 황당한 경험을 해야 했다. 클러스터링으로 묶여있는 서버군 중 하나의 서버를 임의로 중지시키고 다시 가동시켰더니 나머지 다른 하나의 서버가 죽어버리는 현상이 발생한 것이다. 아마도 세션 정보를 서로 공유하다가 무언가가 꼬여버린 것 같은데 전날 테스트할 때에는 아무런 문제가 없다가 특정 상황에서 그것도 하필 고객이 바로 옆에 있는 그 상황, 너무나 중요한 그 상황에서 제품은‘엿 먹으라는 듯’버그를 발생시키고 만 것이다. 스파이크 씨를 비롯한 회사의 모든 사람들의 얼굴은 흙빛이 되었고 그 날 테스트는 그것으로 끝이 났다. 그 이후로 스파이크씨는 밤새도록 제품 개발자와 문제를 재현하여 해결하는데 많은 시간을 들였고 결국 단순히 하나의 클래스를 교체함으로써 더 이상 해당 버그는 발생하지 않았다.

앞서 언급한 것처럼 웹 시스템 개발자가 담당하는 역할 상 리소스에 대한 제대로 된 사용만 철저히 한다면 전체 시스템에 걸쳐 영향을 미칠 수 있을만한 여지가 적은 반면에 미들웨어에서 상대적으로 처리해주는 기능이 많아지다 보니 만약에 이러한 미들웨어가 부실한 신뢰성을 가진다면 그 파급 효과는 상당한 것이다. 때문에 미들웨어를 선택할 때에는 신뢰할만한지 지원은 얼마나 철저한지를 제대로 점검해보지 않으면 두고두고 전체 IT 인프라를 좀먹을 수 있는‘악의 근원’이 될 소지가 있다.

나무를 보지 말고 숲을 보자
가장 황당한 버그는, 사실 이건 버그도 아닌데요. 사람들은 문제가 발생하면 아무래도 시야가 좁아지죠. 개발자는 소스에 이상이 없는지만 살피게 되고 운영자는 운영 환경만 살펴보게 되죠. 그런데 문제는 정말 엉뚱하게도 너무나 당연하게 생각했던 부분에서 해결되는 경우가 많아요. 이를테면 네트워크 선이 뽑아져 있었다든지, DB 서버가 잠시 죽어있었다든지 우리가 평소에 당연히 되리라고 믿어 의심치 않는 요소들이 문제여서문제 상황이 지체되는 경우가 심심치 않게 일어나죠. 그래서 가끔 지원나갔다가 랜선 뽑아져 있던거 연결해주거나 시스템만 한 번 껐다 켜주고 돌아오는 경우가 의외로 많지요. 이런 상황이 있으니 저처럼 미들웨어 쪽 기술 지원하는 사람이 만능박사가 될 수밖에 없는 거죠. 일도 많지만 그만큼 전체 시스템을 보게 되는 힘을 기를 수 있어서 즐겁습니다.

어느 중요한 고객으로부터 스파이크씨에게 연락이 왔다. 엄청나게 성능 좋은 서버를 도입해서 프로젝트를 진행하고 오픈이 얼마 남지 않았는데 성능이 제대로 나오질 않아서 난리가 났다고 한다. 허접한 오픈소스 제품으로 돌릴 때만도 못한 성능이 나오니 이것은 분명 스파이크씨가 담당한 제품의 문제이고 이것을 해결하지 못하면 앞으로 장사 못할 줄 알아라고 말한다. 다급한 스파이크씨 곧장 고객에게 달려간다.

실제로 문제 상황을 보니 같은 웹 애플리케이션을 실행하는데 유독 스파이크씨가 담당한 제품에서만 느린 것을 확인했다. 스파이크씨는 당연히 제품만의 문제로 규정하고 제품의 버그를 찾기 시작했다. 애플리케이션의 알고리즘을 바꿔보기도 하고 버그 리스트를 찾아보기도 했으며 다른 서버 환경에서의 차이점도 분석해보았다. 그러기를 며칠, 결론은 제품의 문제인 것 같기는 하지만 다른 서버에서는 전혀 발생하지 않는 문제라는 것이다. 결국 문제는 고객이 최신 기종이랍시고 들여온 서버에 문제가 있음을 검증하는 단계에 이르렀고 스파이크씨가 며칠 동안을 애써가며 웹 애플리케이션 서버안의 문제를 파헤쳤던 수고는 공염불이 돼버렸다. 즉, 애초에 스파이크씨가 문제의 원인을 좀 더 다각도로 바라보았다면 일찍 서버에 문제가 있었음을 간파할 수있었을 것이며 상황은 훨씬 빨리 종결될 수 있었을 것임에도 불구하고 고정관념에 사로잡혀 하나의 포인트만을 바라보다 보면 숲을 보지 못하는 결과가 생길 수 있음을, 즉 문제는 의외로 다양한 곳에서 복합적으로 일어날 수 있음을 간과한 결과라고 할 수 있겠다.

이렇게 숲을 보지 못해서 쉽게 해결할 수도 있는 문제가 오래동안 여러 사람의 밤잠을 설치게 하는 경우는 스파이크씨에게 비일비재하다. 밤늦게 전화가 온다. 급하게 어느 사이트에서 장애가 발생했는데 웹 애플리케이션 서버 쪽 문제인 것 같다. 그러니 빨리 와 달라. 그래서 찾아간 고객의 사이트에서 스파이크씨가 한 일이라고는 고작 랜 선 꽂아주고 라우터 한 번 껐다 켜준 일 밖에 없을 때 고객과 스파이크씨는 서로 얼마나 X씹은 얼굴일지 상상해보라. 그러니 문제가 발생했을 때에는 일단은 먼저 숲을 바라봐야 한다. 숲을 바라본 다음에 우리가 가진, 문제의 원인일 것이라고 생각하는 고정관념을 배제한 상태에서 문제의 원인을 추적해 들어가는 것. 그것이 웹 기반 시스템에서 문제를 접하는, 스파이크씨가 권하는 방법론이다.

웹 기반 시스템 버그 해결 프로세스
앞서 버그 사냥꾼 스파이크씨의 경험을 토대로 웹 기반 하의 시스템에서 어떠한 버그들이 있는지 사례별로 살펴보았다. 스파이크씨의 말처럼 웹 기반에서의 시스템이 일으키는 버그는 여타 다른 아키텍처에 비하여 상당히 복합적이고 다층적인 관점에서 문제 해결 능력을 필요로 한다는 것을 여실히 느낄 수 있을 것으로 생각한다.

<그림 1> 웹 기반 시스템 버그 해결 프로세스

여기서 짚고 넘어가야 할 것은 어느 문제 상황에서나 스파이크씨처럼 다양한 문제 해결 경험을 가진 이가 여러분 곁에 있을수는 없다는 것이다. 버그는 사람을 가리지 않고, 오히려 상황이 다급하고 주위에 전문가가 없을 때 더 잘 나타난다. 그게 버그의 습성이다. 따라서 필자는 스파이크씨에게 과연 웹 기반 시스템에서 버그를 해결하기 위한 방법론은 없겠는가 물어보았다. 스파이크씨는 비록 웹 기반 시스템이 복합적인 성격을 가지고 다양한 지식과 경험을 가진 이의 분석을 필요로 하는 것은 맞지만 그럼에도 불구하고 어느 정도의 수준을 가진 개발자 내지 운영자가 문제를 해결하는 데 있어 쉽게 접근해 볼 만한 방법론을 제시했다.

어디서 시작할까?
문제가 발생하고 버그가 예상되었을 때 디버깅을 하기 이전에 먼저 전체 웹 시스템이 어떻게 운영되는지를 점검해볼 필요가 있다. 만약 시스템 아키텍처에 대한 간략한 구성도가 있다면 그것을 보면서 점검해보면 좋을 것이다. 과연 아키텍처 각각의 구성원들이 서로 어떻게 연결되어 있는지를 살펴보자. 웹을 구성하고 있는 아키텍처 상에는 생각보다 상당히 많은 구성원들과 리소스 그리고 메시지 프로토콜로 이루어져 있는 것을 알아챌 수 있으며 이와 관련하여 당신이 운영자가 아니라면 운영자와 대화를 통해 각 구성상의 취약점은 없었는지 그리고 최근에 벌어졌던 다른 문제 상황과 변경된 사항들을 먼저 수집해 나가야 한다.

던져야 할 질문들
넓고 넓은 시스템 아키텍처 중에서 가장 먼저 살펴봐야 할 그 곳은 어디일까? 그 곳을 찾는 것이 문제 분석의 첫걸음이다. 이 결정을 위해 몇 가지 간단한 질문을 스스로에게 던져보아야 한다. 첫 번째로 이 문제의 증상은 무엇인가? 만약 에러 메시지가 클라이언트 브라우저에서 발생한 것이라면 아무래도 클라이언트와 맞물려 있는 여러 구성요소들을 의심해 볼 만할 것이다. 아니면 특정 프로세스가 죽거나 행 현상이 발생했다면 이것 역시 가장 먼저 살펴 볼 그 곳을 결정하는 데 중요한 단서가 된다. 물론 해당 프로세스가 죽거나 행 현상이 발생했다면 다음 절차는 해당 프로세스에 대한 행동을 기록하고 있던 로그 파일을 보는 행위가 될 것이 명백하다.

두 번째로 가져야 할 질문은‘언제 해당 증상이 발생하는가?’이다. 발생하는 시간과 발생하는 주기 등이 문제의 본질에 대해 이해하는 데 매우 중요한 단서가 된다. 예를 들어 사용자가‘계정 정보’페이지를 클릭할 때면 무조건 에러 메시지가 출력된다면 너무나 당연하게도‘계정 정보’와 관련된 소스코드를 먼저 볼것이다. 반면에 사용자 트래픽이 매우 높을 때에만 발생하는 현상이라면 무언가 시스템 리소스와 관련이 있는 문제라는 것을 직감할 수 있을 것이다. 반면에 아무런 시기적인 유사성이 없는 상황에서 발생하는 문제라면 이 문제에 제3의 구성원의 개입이 있을 수 있거나 좀 더 시간과 상황에 따른 유사성을 발견해내야할 것이다. 하지만 이렇게 간헐적으로 발생하는 문제가 가장 해결하기 어려운 문제임은 확실하므로 단단히 긴장해야 한다.

세 번째로 가져야 할 질문은‘최근에 시스템 변경사항은 무엇이었는가?’이다. 최근에 애플리케이션 혹은 시스템에 변경 사항은 없었는가? 무언가가 변경이 되었다면 그것이 원인이 되어 발생한 문제 혹은 버그임을 우선 의심할 수 있을 것이다.

버그를 고립시키기
쥐를 잡아본 적이 있는가? 쥐를 잡으려면 일단 쥐가 어디에 숨어있는지를 알아야 하고 위치를 알았다면 적절한 도구로 쥐를 야금야금 몰아가야 한다. 자 이제 어디에 버그가 숨어있는지를 눈치 챘다면 적절한 도구로 버그 사냥에 들어간다.

디버깅 툴
웹 기반 시스템에서 발생한 버그라는 것이 대부분 런타임 환경에서 발생하는 경우가 많기 때문에 디버깅하기가 상당히 까다롭기는 해도 요즘 출시되고 있는 각종 개발 툴에서는 런타임에서의 디버깅 환경이 꽤 유용할 만큼의 환경을 제공해준다. 그럼에도 불구하고 디버깅 툴에는 어느 정도 한계가 있다. 그 첫 번째가 운영환경에서의 버그일 경우 디버깅 툴로서는 잡아내는 게 여의치 않다는 것이다. 이를테면 사용자 접속이 얼마 이상일 때 발생하는 버그일 경우 주로 객체와 메시지 자체에 대한 정보만을 바라볼 수 있는 디버깅 툴만으로는 현상 파악에 무리가 있는 것이다. 따라서 자세한 정보를 위해서라면 한 손에는 디버깅 툴을 그리고 다른 손에는 또 다른 유용한 툴을 지니고 있어야 한다.

로그 파일
거의 대부분의 프레임워크와 미들웨어 및 리소스 관리 툴에서는 로그 파일을 남긴다. 때때로 특정 제품의 경우 성능 등의 이유로 최소한의 로그만을 남기는 경우가 있는데 대부분 로깅 수준을 조절하여 더 세밀한 정보를 볼 수가 있다. 로그 파일에는 단순히 각각의 서버가 제공하여 주는 것들 이외에도 JVM이나 네트워크스위치 등이 제공해줄 수 있는 파일(쓰레드 덤프와 힙 덤프 등)들도 있다. 이 뿐만 아니라 문제가 발생하고 있는 부분에 대한 자세한 추적을 위한 로그를 별도로 추가함으로써 문제의 원인을 좀 더 막다른 골목으로 좁혀볼 수 있을 것이다. 따라서 전체 시스템 아키텍처 구성도를 바탕으로 해서 하나라도 빠짐없이 로그파일을 챙기는 것이 문제 원인을 해결할 수 있는 지름길이다.

모니터링 툴
요즘 출시되고 있는 DB 서버나 웹 애플리케이션 서버, 웹 서버,메시징 엔진 제품 등은 더 편리한 관리 환경을 위해 비주얼한 형태의 모니터링 툴을 제공하여 자원의 상태 등을 파악하고 런타임 환경이 제대로 운영 중인지 파악하는 데 많은 도움을 주고 있다. 또한 이러한 적절한 툴이 없다 할지라도 간단한 스크립트를 이용하여 서버 상황을 이해하는 데 기본이 되는 여러 가지 정보를 추출하는 것이 가능하다. 이를테면 네트워크 연결 수나 DB 연결수 그리고 CPU와 메모리 활용 상태 등은 간단한 스크립트로도 추출하는 것이 가능하다. 이러한 툴을 쓰는데 인색하지 말라.

숙련된 버그 사냥꾼이 필요하다
이제까지 버그 사냥꾼 스파이크씨의 경험을 토대로 웹 환경에서의 버그의 유형과 이러한 버그를 잡아내는 대략적인 방법론에 대한 이야기를 들어보았다. 우리는 흔히 버그 없는 소프트웨어는 없다고 하고 단 백 줄도 안되는 소스코드에서도 얼마든지 버그는 존재한다고 한다. 그만큼 개발자에게 있어 버그는 여름철의 모기처럼 평생을 따라다니는 숙명과도 같은 존재다. 그럼에도 불구하고 웹 기반 시스템은 날이 갈수록 그 복잡도를 더해가서 하나의 웹 사이트 안에 포함되어 있는 프레임워크나 미들웨어 제품 그리고 각종 부가적인 서버들의 종류가 점점 더 다양해져가고 있다.

이는 곧 웹 기반 시스템이 점점 더 단순한 개발자로서의 능력보다는 전체 시스템에 대한 안목과 다양한 경험을 아우르는 능력을 가진 인력을 더 필요로 함을 반증하는 것이기도 하다는 생각이다. 때문에 이렇게 복잡해져가는 시스템에 대한 문제 해결 능력을 기르는 것은 개발 본연의 경험과 함께 매우 중요한 능력이라 생각하며 본 기사를 통해 더 깊은 웹 기반 시스템 문제 분석가의 길에 매력을 느끼는 독자들이 많아지면 바랄 것이 없겠다.

* 이 기사는 ZDNet Korea의 제휴매체인 마이크로소프트웨어에 게재된 내용입니다.
반응형

댓글