버그는 프로그래머의 숙명이다.

 

섬세하게 만들려한 IOS, OS X에도 버그는 종종 있으며, 사실 많은 사람이 M$ 부르지만 나의 경우는 매우 감사하고 있는 MS 경우에도 버그는 많다. 구글도 예외는 아니고. (구글 apps 초창기 패치할 마다  언어 관련, IME 관련 문제를 겪게 했던 일은 나름 유명한 일화다.)

 

이러한 회사는 분명히 업계의 엘리트가 모여있을 텐데 어째서 이렇게 버그가 나오는걸까?

 

어찌보면, 버그는 당연한 숙명이다.

 

하나의 어플리케이션을 작성하기 위해, 작성된 위지윅 툴을 사용하더라도, 버그가 없다고 단정 지을 없다.

하물며, 코드가 들어가고, 각종 코드를 재사용하고, 다른 코드를 얹는 과정에서는 복잡도와 결합도는 증가하고, 당연히 버그가 생길 여지도 많아진다.

 

그렇다면 버그를 없애려는 노력과 기반은 당연히 마련해야 할테고… (나의 디버깅 관련 글들은 대부분 주제에 대한 글로 이루어져 있다) 그렇게 했는데도 발생한 버그들에 대해선 어떻게 대처해야 것인가?

 

나는 대안으로 기록. 버그 노트를 작성해야 한다고 생각한다.

 

꽤나 많은 프로그래머들이 버그를 부끄러워한다.

숨기려고도 하고, 괴로워 하기도 하고.

 

하지만 나의 경우는 꽤나 많은 버그가 환경에 영향을 준다고 생각한다. , 기존에 작성된 코드가 버그의 수나 버그의 수위를 조절한다고 생각하고.

 

, 그렇다면 버그는 부끄러워 대상이 아니고 개선해야 대상이다.

 

그럼 하나 질문.

 

개선을 위한 습관으로  어떤 노력을 해보셨나요?

 

흔히들 하는 핑계가 경력이 쌓이면 저절로 고쳐져요같은 경험론이다.

주변 지인들과 수많은 얘기와 경험 해보고 내린 결론은 절대 버그는 경험과 비례하지 않는다. (물론 절대적 경험치나 기본기가 부족한 경우는 버그를 양산하기도 한다. 혹은 절대적으로 촉박한 일정도 그런 문제를 만들기도 하고)

 

오히려 위에 언급한 시스템이 버그를 줄여든다.

 

추가적으로 개인적인 노력도 반드시 필요하다고 생각한다.

나의 경우는 그런 의미로 버그 노트를 작성해왔다. 대략 9년여 되가는 습관은, 나의 버그 수를 줄이진 않았어도 같은 종류의 버그 재발은 급격히 줄여줬는데, 자체적인 회고를 주기적으로 거치는 것도 병행하는 덕택일거다.

 

반드시 자신의 버그를 돌아봐야 한다고 생각한다.

그러기 위해 버그 노트를 작성하고, 과정에서 기록되어야 것은 다음과 같다.

 

  • 현상
  • 추정
  • 과정
  • 원인
  • 해결책

 

항목을 채우다보면, 잘못된 해결책이나, 미흡한 원인 파악, 잘못된 추정등이 밝혀진다. (종종 잘못된 현상 보고도 있긴 하고)

 

그런 과정을 반복하다보면, 자신의 잘못된 습관이 보인다. 습관을 고쳐나갈 수록, 퀄리티 높은 프로그래머가 된다고 생각한다.

 

물론 이런 노력없이도, 좋은 퀄리티의 프로덕트를 만들어 내는 분들이라면 괜찮지만, 아니라면 버그를 줄이기 위해 버그 노트를 써보면 어떨까?


Posted by 엘키 엘키

댓글을 달아 주세요

꽤나 많은 상황에서 우리는 기존 코드를 분석해야 한다.

 

빌드업이라 불리는 프로젝트에 필요한 기능들을 만져나가는 과정에서도 우리는 라이브러리나, 오픈소스 코드등을 통해서 기존 코드를 분석해나가야 한다.

 

물론 과정은 섬세하게 만져나갈 여지가 있고, 그간의 결합도를 조절해나갈 여지가 있으므로 상대적으로 코드 분석의 여지가 적다.

 

심지어 사용하는 라이브러리들이 익숙하거나, generic하게 구현되어있다면 더더욱이 쉽고.

 

 

 

사실 가장 곤욕스러운 과정은 프로젝트 dependency 코드를 분석하게 때이다.

 

과정에서, 코드간의 결합도를 낮출려고 노력해온 흔적이 있는 경우는 그래도 상대적으로 쉬운 편에 속한다.

예를 들어 패킷으로만 다른 티어와 통신을하고, 패킷 핸들링 코드가 명확하다면 기존 코드가 난해하다해도 결합도를 풀어가는데에 상대적으로 수월하다.

 

하지만 진입점의 종류가 곳이고, 기능별로 핸들링 코드가 분리되어있음에도 객체간의 관계가 명확하지 않고, 쓸데 없이 복잡하게 보이는 일은 비일비재하다.

 

 

이럴때 당신은 어떻게 분석하는가?

, 인수인계를 위해 어떻게 준비해야 하는가?

 

많은 코드 분석과정을 해본결과, 지켜본 결과 많은 사람들이 두가지 방법정도로 코드를 분석하더라.

 

상향식 코드분석과, 하향식 코드 분석이다.

 

그림. , 전체적인 구조 설계의 전제 파악, entry point 분석, 스레드 디자인 분석과 같은 프로젝트의 룰을 파악하는데에 주력하는 것을 하향식 코드 분석이라 부른다.

 

반대로 컨텐츠별로 하나씩 기능들을 분석하며, 실제 컨텐츠별 사용중인 클래스들을 분석해나가는 것을 상향식 코코드 분석으로 부른다.

 

 

두가지 모두 적절히 이루어지면 좋겠지만, 사실 대부분의 경우 입사나 부서이동 직후 업무를 바로 진행해야되는 경우가 수두룩 하다.

 

이럴 경우 어떤 방법을 먼저 채택할 것인가?

 

나의 경우는 항상 하향식 코드 분석을 선호해왔다.

 

프로젝트의 , 전제를 모르고선 다른 코드들의 디테일을 봤을 , 코드가 과연 작성된 코드인지, 혹은 자연스레 녹아든 코드인지 판단도 안된다고 여겨서이다.

 

그렇다고 상향식 코드 분석이 나쁘다고 없다.

 

일관된 규칙으로 코드가 관리되어왔고, 간결하면 간결할 수록, 상향식 코드 분석이 빛을 발하기 때문이다.

 

하지만 그런 상황은 그다지 자주 벌어지지 않는다. 어찌보면 작성되어있는 코드 양이 많으면 많을수록 이상론적인 이야기이고, 꽤나 많은 경우에는 하향식 코드 분석을 선행하고, 이후 상향식 코드 분석으로 전환하는 과정이 옳다고 본다.

 

여기에 문서화에 대한 이야기를 빼놓을 없다.

 

그렇다면 인수인계 자신의 작업 기록을 위한 문서화는 어떻게 해야 하는가?

 

나는 작업 규칙과, 설계 기준을 명세하면 충분하다고 생각한다.

작업의 디테일은 고생한 과정을 기반으로 기록해 수록 좋다.

만약 두사람 이상이 같은 작업 과정에서 고생했다면, 작업 자체가 집중을 요하는 작업이거나, 혹은 실수의 여지가 많은 빈틈있는 기반 작업이 되었다는 것을 (혹은 그러한 툴이나 라이브러리, 코드 등을 이용하거나) 의미하기 때문이다.

 

겪었던 문제들에 대한 기록만 취합되어 있더라도 상대적으로 많은 시간을 아낄 있다고 생각한다.

그래서 나는 버그 노트를 작성하기 시작했는데, 이에 대한 이야기는 다음 글에서 이어서 하려 한다.


Posted by 엘키 엘키

댓글을 달아 주세요

내가 코드를 작성할 때 신경쓰는 코딩 규약들을 정리해본다.

 

소유권

  • 객체의 소유 주체는 (생성과 소멸의 관리 주체는하나로 규정한다.
  • 객체의 생성,소멸 스레드도 하나로 규정한다.
  • 다른 클래스에서 호출되어야만 하는 메소드를 만들지 말라.
  • Has a 관계가 명확하다면 관계를 혼란 시킬  있는 메소드는 절대 만들지 마라.

 

진입점

  • 진입 점은 명확하게한곳으로 관리하자
  • 만약 다양한 진입 점이 있을  밖에 없다면다른 각각의 진입 점에서 왔음을   있게 하라.

 

중복

  • 중복을 허용하지 말라.

 

단일 규칙

  •  가지 이상의 규칙을 허용하지 말라새로운 규칙을 도입하고 싶다면기존 규칙대로 작성된 전부를 고쳐라.
  •  가지 이상의 규율이 존재하는 것은코드 작성/분석  모든 과정에서 해가 된다.

 

전치 검사, 후치 검사

  • 메소드는 정상적으로 실행되기 위한 선결 조건에 대한 검사를 해야 한다.
  • 메소드는 정상적으로 실행되었을 때의 기대 값을 충족 시키는지 검사해야 한다.

 

호출 주체

  • 누가 호출해도 문제가 없는 메소드만 외부로 개방하라.
  • 만약 특정 클래스에서만 호출해야 정상 동작한다면, 잘못된 설계이고, 잘못된 사용법을 제공하는 것이다.

 

호출 순서

  • 호출 순서에 영향을 주는 코드는 지양하라.
  • 피치 못할 사정으로 함수의 호출 순서가 일정해야만 한다면, 정해진 호출순서대로 실행하는 상위 함수를 만들고, 내부를 숨겨라.


Posted by 엘키 엘키

댓글을 달아 주세요

지난해 10, 미국의 북동부 지역은 어딜 가나 아셀라(Acela) 광고 천지였다.아셀라란 암트랙(Amtrak) 워싱턴-보스턴간 노선에서 운행할 새로운 초고속열차의 이름. 끊임없이 쏟아지는 TV 광고와 전광판 광고, 도처에 나붙은 포스터들을 보면서, 누구라도  정도의 물량 공세라면  새로운 초고속열차 서비스에 대한 수요 창출에 상당히 기여했으리라 생각했을 것이다.


글쎄, 그랬는지도 모르지. 하지만, 정작 암트랙사는 이를 확인해  기회가 없었다. 아셀라 프로젝트가 계속 지연되는 바람에 상용서비스가 개시되지도 않은 상태에서 광고 캠페인만 진행되고 있었던 것이다. 어떤 회사의 신제품 시판을 한달 앞두고  제품이 우수한 평가 등급을 받자 마케팅 책임자가 했다는말이 떠오른다. “대단한 홍보 효과야! 이럴  시장에 물건만   있었으면얼마나 좋았을까!”


남성호르몬이 철철 넘치는 게임 업체들은 자사 웹사이트에 제품 개발이 완료되는 대로 새로운 게임이 출시될 것이라고 떠들어대기를 좋아한다. 스케줄?스케줄 같은  필요하지 않다. 그들은 나는 게임 개발자들이니까! 하지만,대부분의 평범한 소프트웨어 업체들에게는 스케줄이 필요하다. 로터스의 경우가  좋은 예로, 로터스사가 처음 123 버전 3.0 개발을 완료했을   소프트웨어는  당시만 해도 아직 보급 대수가많지 않던 80286 기종의 컴퓨터를 필요로 했다. 로터스는 제품 출시를 16개월이나 미뤘고  기간 동안 8086 기종의 메모리 한계인 640K 맞춰 제품의 용량을 줄였다. 수정된 제품이 완성되었을 때엔 이미 엑셀을 시판중인 마이크로소프트사가 시장에서 16개월 정도 앞서나가고 있었으며,  무슨 가혹한 운명의 장난인지, 8086 기종은 이미 시장에서 폐물 취급을 받고 있었다!


 글을 쓰고 있는 지금도 넷스케이프의 인터넷 브라우저 5.0 경쟁사에 비해 거의 2가까이뒤쳐져있다. 개발된 코드를 모두 폐기하고 처음부터 코딩을 다시 시작하는 치명적인 실수를 저질렀기 때문이다. 애시톤-테이트, 로터스, 애플사의 MacOS 등도 똑같은 실수를 저지르는 바람에 소프트웨어 역사의휴지통(Recycle-bin) 속으로 내던져지는 신세가 되고 말았다.  사이 넷스케이프사의  브라우저의 시장점유율은 80%대에서 20%대로 곤두박질쳤지만 회사는 아무것도   없었다. 주력 소프트웨어 제품이 산산조각으로 분해되어 있는 상태에서는 달리 손을   있는 방도가 없었기 때문이다.  한번의 잘못된 결정이 넷스케이프를 자폭시킨 핵폭탄이  셈이었다. ( 자세한내용은 Jamie Zawinski  world-famous tantrum 참조한다).


그래서, 스케줄관리가필요한것이다. 거의 모든 프로그래머들이 하기 싫어하는 일이 바로 스케줄 관리다. 필자의 경험에 따르면, 대다수의 프로그래머들은어떻게 해서든 스케줄 같은  아예 짜지 않고 버텨 보려고 든다. 스케줄을 짜는 극소수의 프로그래머들도 대부분 상사가 하라고 하니까 억지로 하고 있을,  스케줄대로 프로젝트가 진행되리라고 믿는 사람은  상사 밖에 없다. 상사는 스케줄을 믿는 한편으로, “기한 내에 완료되는 소프트웨어 프로젝트는 없다고도 믿으며 , UFO 존재도 믿는 사람이다.

그렇다면,  아무도 스케줄을 만들려 하지 않을까? 주된 이유는  가지다. 첫째는 스케줄을 짜고 관리하는 것이 매우 골치 아픈 일이기 때문이고,  번째이유는 아무도 그것이 그만한 수고의 가치가 있는 일이라고 믿지 않기 때문이다. 스케줄이 지켜지지도 않을 거라면 도대체  그런 수고를 해야 한단 말인가? 스케줄이란 애당초 지켜지는 법이 없고 시간이 지날수록 현실과의 괴리는점점  커지기만 하는데,  하러 그런 헛수고를 한단 말인가?


여기, 정확하게지켜지는스케줄을만드는간단하고손쉬운방법이있다.


1) 엑셀프로그램을사용하라. MS Project 같은 거창한 프로그램을 사용하려들지 말라. MS Project 사용자가 종속성의 문제를 해결하기 위해 많은 시간을 할애할 것이라는 가정하에 만들어진 프로그램이다. 종속성이란,  가지 작업을 진행해야 하는 상황에서 하나의 선행 작업이 먼저 완료된 후에만 다음 작업을 시작할  있는 경우를 말한다. 소프트웨어 프로젝트의 경우, 작업들간의종속성은 너무나 당연한 것이기 때문에 굳이 수고스럽게 종속성을 추적할 필요가 없다.

MS Project 사용하는 경우에 생길  있는  다른 문제는  프로그램을 사용하다 보면 자꾸 스케줄 균형 조정 기능을 실행하고 싶어진다는 것이다. 스케줄 균형 조정에는 불가피하게 모든 작업을 재조정하여 다른 사람에게 재할당하는 과정이 포함되는데, 소프트웨어 프로젝트의 경우 이런 재조정은 말이되지 않는다. 프로그래머들간의 호환이 불가능하기 때문이다. 가령, 리타가 작업한 코드의 버그를 존이 수정하려면 리타 자신이 수정할 때보다 시간이 일곱배는  걸린다. , UI 담당 프로그래머에게 WinSock 관련된 문제를 해결하라고 시키면, WinSock 프로그래밍에 익숙해지는 데에만 일주일은 걸릴 것이다. 결론은 MS Project 소프트웨어 개발 프로젝트보다는 건축 공사 프로젝트에 적합한 프로그램이라는 것이다.


2) 단순하게만들라. 필자가 이용하는 스케줄 포맷은 너무나 단순해서 한번만봐도 기억할  있을 정도다. (컬럼) 개수는 일곱 개면 된다.

개발자가 여러 명인 경우에는 개발자별로 시트를 각기 따로 만들 수도 있고,아니면  작업을 담당하는 개발자의 이름으로 컬럼을 만들 수도 있다.


3) 하나의기능은여러개의작업으로분해하라. 여기서, 기능이란 프로그램에추가되는 맞춤법 검사 기능 같은 것을 말한다. 실제로 맞춤법 검사 기능을 추가하려면, 프로그래머는 여러 단계의 작업을 수행하게 된다. 스케줄을  가장 중요한 부분은 바로 이와 같은 구체적인 작업들의 목록을 만드는 것이다.따라서 다음 규칙을 명심해야 한다.


4) 코딩을직접담당할프로그래머만이스케줄을만들있다. 관리자가 임의로만든 스케줄을 프로그래머에게 던져주고는 따르라고 말하는 프로젝트는 실패할  밖에 없다. 코딩을 직접 담당할 프로그래머만이  기능을 구현하기 위해 어떤 작업들이 필요한가를 구체적으로 예측할  있고  작업에 어느 정도의 시간이 소요될 것인가도 추정할  있다.


5) 작업단위를세분화하라. 실효성 있는 스케줄을 만들기 위해 반드시 유념해야  부분이다. 작업량은 날짜가 아니라 시간 단위로 계산해야 한다. ( ,또는   단위로 작업 기간이 계산되어 있는 스케줄은 처음부터 지킬 생각으로 만든 스케줄이 아니다). ‘작업 단위를  잘게 쪼개면  정밀한 스케줄이나오겠지 정도로 생각하는 독자가 있을지도 모른다. 천만의 말씀! 대략적인작업 개요를 바탕으로 스케줄을 세워보고, 다시 작업 단위를 보다 세분화하여스케줄을 세워보면, 단순히  정밀한 스케줄이 얻어지는 것이 아니라 전혀다른결과 나온다. 완전히 다른 수치가 나오는 것이다. 어째서 이런 일이 생기는 걸까?


작업 단위를 세분화하기 위해서는 실제 코딩 과정에서 구체적으로 어떤 일들을 수행하게  것인가를 생각해보지 않으면  된다. 서브루틴을 저작하고,이러저러한 대화상자들을 만들고, wawa 파일을 읽어내고 등등.  같은 각각의 단계에 소요되는 시간을 추정하는 것은 어렵지 않다. 프로그래머라면 서브루틴을 저작하고 대화상자를 만들고 wawa 파일을 읽어내는 작업들은 모두해봤을 것이기 때문이다.


만일 어떤 스케줄이 적당히 얼버무린  덩어리 작업들로만 (가령, “문법검사 기능 구현하기 ) 채워져 있다면, 이는 프로그래머가 구체적으로 어떤일들을 하게  것인가에 대해 제대로 생각해보지 않았다는 증거다. 그리고,어떤 일들을 하게  것인지 제대로 생각해보지 않았다면, 거기에 어느 정도의시간이 소요될 것인지도   없다.


개별 작업에는 어림잡아 2시간에서 많게는 16시간 정도까지가 소요된다. 스케줄에 40시간(1주일)짜리 작업이 포함되어 있다면, 작업 단위를 충분히 세분화하지 않았다는 이야기다.


스케줄을   작업 단위를 세분화해야 하는  다른 이유는 그런 과정을 통해 해당 기능을 머리 속으로 설계해보게 된다는 것이다. 만일 인터넷 통합이라는  떨리는 기능에 대한 스케줄을 수립하면서 무턱대고 3주일을 배정했다면  프로젝트는 실패할  밖에 없다. 구체적으로 어떤서브루틴들을만들어내야것인가 생각해내다 보면,  기능을 명확하게규정하게 된다.  같은단계에서 미리 계획을 세워봄으로써 소프트웨어 프로젝트와 관련된 불안정성을 크게 줄일  있다.

 

6) 최초추정시간과현재추정시간을지속적으로추적하라. 어떤 작업을 처음스케줄에 추가할 때는  작업에 어느 정도의 시간이 소요될 것인가를 추산한,  결과를 Orig Est (최초 추정시간) 컬럼과 Curr Est (현재 추정시간) 컬럼에 모두 입력한다. 


시간이 흐름에 따라, 작업 진도가 당초의 예정보다 지연 (혹은 단축)되면, 현재 추정시간 컬럼을 필요에 따라 업데이트할  있다.  같은방식으로 관리하다 보면, 특정 작업에 필요한 시간을 보다 정확하게 추정하는방법을 스스로 터득할  있다. 


대부분의 프로그래머들은 각각의 작업에 어느정도의 시간이 소요되는지  모른다. 그래도 걱정할 필요는 없다. 스케줄을지속적으로 관리하고 그에 따라 업데이트하는 , 결국 스케줄과 프로젝트 완료 시기는 일치하게 된다. (최종 납기를 맞추기 위해 일부 기능이나 항목을 잘라버려야만 하는 경우도 생길  있지만, 그와 같은 추려내기가 필요한 시점이언제인가를 일관되게 보여준다는 점에서 스케줄의 정확성은 여전히 유지될것이다). 필자의 경험으로  , 대부분의 프로그래머들은 일년 정도만 연습하면 스케줄 짜는  도사가 된다.


작업이 완료되면, 현재 추정시간 컬럼과 Elapsed (경과시간) 컬럼의 값이 똑같아지고 Remain (잔여시간) 컬럼의 값은 0 된다.


7) 경과시간을매일업데이트하라. 물론, 스톱워치를 들여다보며 코딩을 진행할 필요는 없다. 퇴근하기 직전에, 혹은 회사에서 밤을 새워가며 일하는 경우라면 책상 밑에 기어들어가 잠깐 눈을 붙이기 직전에, 하루에 한번만 경과시간을 업데이트하면 된다. 8시간 동안 근무했다고 가정하고 (하하!), 그날 진행한작업들에 대한 경과시간 필드에 8시간을 쪼개서 입력한다.


 잔여시간 컬럼의값은 엑셀이 자동으로 계산해  것이다.


그와 동시에, 현재 추정시간 컬럼도 업데이트하여 변화된 현실을 반영한다. 스케줄을매일업데이트하는걸리는시간은고작2정도밖에되지않는다. 그래서  방법을 손쉬운 스케줄 관리법이라고 부르는 것이다. 빠르고 간편하기 때문에.


8) 휴가기간과휴일등도항목에포함시켜라. 1 정도 진행되는 스케줄이라면, 사이에 프로그래머들의 휴가일수가 대개 10일에서 15 정도 포함될 것이다. 스케줄의 기능 컬럼에는 휴가, 휴일  기타 시간을 잡아먹는 모든 것들에대한 항목이 전부 포함되어야 한다. 잔여시간 컬럼의 값을 모두 더한  이를40(1주일)으로 나누면, 휴가  모든 요소를 포함하여 작업 기간이   주일이나 남아있는지를 산출할  있고 제품 출시 일자도 계산할  있다.


9) 디버깅시간도고려하라! 디버깅은 소요시간을 추정하기가 가장 어려운 항목이다. 가장 최근에 작업했던 프로젝트를 떠올려보라. 아마도 코딩 단계에서소요된 시간의 100% 내지 200% 해당하는 시간이 디버깅에 소요되었을 것이다. 스케줄의 기능 컬럼에는 반드시 디버깅 항목이 포함되어야 하며, 아마도가장 값이  항목이  것이다.


스케줄 업데이트 방법은 다음과 같다. 가령, 어떤 개발자가 wawa 파일을 코딩한다고 하자. 처음 스케줄을   예상했던 최초 추정시간은 16시간이었지만,현재까지 이미 20시간이 소요되었고 앞으로도 10시간 정도는  걸릴 것으로예상된다.  경우, 개발자는 현재 추정시간 컬럼에 30 입력하고 경과시간컬럼에 20 입력하면 된다.


주요 작업 단계가 완료된 , 모든 항목들의 값들을 더해보니 상당한 수치가나왔다. 이론상으로 제품 납기를 맞추자면 몇몇 기능을 잘라내 버려야 한다.이렇게 시간에 쫓길  프로그래머들이 가장 먼저 잘라낼  있는 기능이 바로디버깅 항목이다. 다행히도, 처음 스케줄을   디버깅 항목에 많은 시간을할당해 두었으니까.


원칙적으로, 개발자들은 코딩과 동시에 디버깅을 병행해야 한다. 절대로, 수정할  있는 버그를 뒤로 미뤄둔  새로운 코딩에 착수해서는  된다. 미해결버그의 수는 가능한  최소한으로 유지해야 한다.  이유는  가지다.


1) 버그는 코딩 직후에 곧바로 수정하는 것이 가장 수월하다.  달쯤 지난 후에 버그를 수정하려고 하면, 정확한 코딩 방식을 기억하지 못하기 때문에 버그수정도  어려워지고 시간도  많이 걸릴  있다.


2) 버그 수정은 과학적 연구와 비슷해서, 언제 새로운 과학적 사실을 발견할 있을지 정확히 예측하기 어려운 것처럼 언제 버그를 해결할  있을지 정확히 예측하는 것도 쉽지 않다. 수정해야  버그가  개나  개뿐이라면 제품출시 시기를 예측하는 것은 어렵지 않겠지만, 미해결 버그가 수백 개나 수천개쯤 되는 경우에는 이것들을 언제 전부 수정할  있을지 예측하기란 불가능하다.


그렇다면, 개발자가 코딩 과정에서 버그를 발견할 때마다 곧바로 버그를 수정하는데  디버깅 스케줄을 따로 만들어야 하는가? 프로그래머가 모든 버그를그때그때 수정한다 하더라도, 작업 단계가 완료되면 불가피하게 버그 수정 과정이 필요하다. 테스트 (내부 테스트  베타 테스트) 단계에서 정말로 어려운버그들이 발견되기 때문이다.


10) 통합시간도고려하라. 여러 명의 프로그래머가 함께 작업하는 경우, 프로그래머들 간에 서로 일치되지 않아 조정이 필요한 부분이 생기게 마련이다. 가령, 유사한 기능의 대화상자를  명의 프로그래머가 서로 다른 방식으로 구현할 수도 있다. , 여러 명의 프로그래머들이 각자 마음대로 추가한 메뉴 항목이나 키보드 단축키, 툴바 등을 누군가는 전체적으로 정리하고 통일시켜야만한다.  사람이 코드에 체크인하는 순간 컴파일러 에러가 발생할 수도 있다. 모든 것들을 수정할 시간이 필요하며, 이는 별도의 기능 항목으로 스케줄에포함시켜야 한다.


11) 여분의시간을포함시켜라. 시간은  모자라게 마련이다. 스케줄을  고려해야  여분의 시간(버퍼)  가지 종류가 있다. 첫째는 당초 추정했던것보다 시간이  많이 걸리는 작업을 고려한 버퍼이고, 둘째는 관리자가wawa 구현이 너무나도 중요해서 다음 버전으로 미룰  없다고 결정하는 경우 등과 같이, 계획에 없이 갑자기 추가된 작업을 고려한 버퍼다.


혹시라도 휴가, 휴일, 디버깅, 통합 시간  버퍼 항목 등을 모두 더한 값이 실제 작업 시간을 모두 더한 값보다  크다는 사실을 알고는 놀랄 수도 있다. 이런 사실에 놀라는 독자라면 아마 프로그래밍 경력이 아직 그리 길지 않은 개발자일 것이다. 책임질 자신이 있거든, 이런 항목들을 빼버려도 좋다.


12) 절대로관리자가프로그래머에게스케줄단축을요구해서는된다. 풋내기 소프트웨어 관리자 중에는 프로그래머들에게 빡빡한” (비현실적으로 짧은) 스케줄을 던져주는 방법으로 그들을 자극하여 작업을 보다 빨리 진행시킬  있다고 생각하는 사람들이 많다. 필자의 생각으로는 이런 식의 자극은멍청한 짓일 뿐이다. 필자의 경우, 스케줄에 뒤쳐지면 오히려 좌절감이 생기고의욕이 저하되며, 스케줄보다 진도가 빠를  활기도 생기고 생산성도 높아진다. 관리자는 스케줄을 심리전의 도구로 이용해서는  된다.


그럼에도 불구하고, 관리자가 스케줄 단축을 요구하는 경우에는 이렇게 대처하라. 릭의추정시간이라는 새로운 컬럼을 하나  추가한다 (물론, 프로그래머의 이름이 릭이라고 가정하고.) 프로그래머 자신이 예상하는 추정시간을 컬럼에 입력한다. 관리자가 원하는 새로운 스케줄은 현재추정시간 컬럼에 업데이트 한다. 관리자의 추정시간은 무시하고 작업을 진행하라. 프로젝트가 완료된 후에 누구의 스케줄이  현실적이었는지 비교해 보라. 필자의 경험에 따르면, “누구 스케줄이  맞는지 한번 볼까요?” 라고 관리자를 위협하는것만으로도 놀랄만한 효과가 있다. 자칫하면 프로그래머들과 얼마나 느릿느릿 일할 있는지 두고 보자는 식의 내기를 하는 꼴이 되고 만다는 사실을 관리자도깨닫게  테니까!


 풋내기 관리자들은 프로그래머의 스케줄을 단축하려고 노력하는가?


프로젝트가 처음 시작되면, 기술 관리자들은 비즈니스 담당자들과 회의를 하고는 그들이  3개월 정도 소요될 것으로 생각하는, 하지만 실제로는 9개월이 걸리는 제품 기능들이 적힌 목록을 만들어 온다. 어떤 작업들을 수행해야하는가를 구체적으로 생각해 보지 않고 스케줄을 짜는 경우, 항상 실제로는3n 시간 이상 걸릴 일이n 시간 정도 걸릴만한 일인 것처럼 보이게 된다. 현실적인 스케줄을 짜다 보면, 모든 작업 시간을 전부 더하게 되고  프로젝트가당초 생각했던 것보다 훨씬 시간이 많이 걸릴 것이라는 사실을 깨닫게 된다.현실은 가혹한 것이다.


풋내기 관리자들은  같은 문제를 해결하기 위해, 사람들이 보다 빨리 일하도록 만들  있는 방안을 찾아내려 애쓴다. 하지만, 이런 식의 접근은 그다지 현실적인 방법이 아니다. 작업 인원을  늘릴 수는 있겠지만, 그렇더라도 신입프로그래머들이 작업에 익숙해질 때까지 상당한 시간이 필요하기 때문에  정도는 작업 효율이 50% 정도 밖에 되지 않을 것이다 (게다가, 그들에게 일을 가르쳐야 하는 사람들의 작업 효율까지 떨어진다). 무엇보다, 소프트웨어업계에서 쓸만한 프로그래머를 새로 뽑자면 6개월 정도는 시간이 걸린다.


모든 에너지가 일년 안에 100% 소진될 만큼 팀원들을 쥐어짠다면 혹시 일시적으로 코드 산출량이 10% 정도 늘어날지도 모른다. 하지만, 별로 남는 장사는 아니다. 무엇보다, 이것은 배가 고프다고 종자용 옥수수까지 먹어치우는 것과 비슷한 꼴이다.


모든 사람들에게 아무리 피곤하더라도  참고 초인적으로 열심히 일해달라고 애원한다면 혹시 코드 산출량이 20% 정도 늘어날  있을지도 모른다. 하지만, 디버깅 시간은  배로 늘어날 것이다. 이야말로 숙명적으로 실패가 예정된 악수(惡手)   있다.


하지만, 아무리 해도 절대로 n 가지고 3n 이룰 수는 없다. 만일   있다고 믿는 회사가 있다면, 필자에게 이메일로  회사의 나스닥 상장기호를 일러주기 바란다. 필자가  상장기호를 반으로 줄여줄 테니까.


13) 스케줄은나무블록과같다. 집짓기 놀이용 나무 블록이  꾸러미 있는데이걸 주어진 상자에 전부 담을 수가 없다면, 방법은  가지다.    상자를구해오거나, 아니면 나무 블록 중에서  개는 포기하는 것이다. 6개월이면 제품을 완성할  있을 거라고 생각했었는데 작업을 진행하다 보니 12개월짜리스케줄이 됐다면, 제품 출시를 늦추든가 아니면 몇몇 기능을 포기해야 한다.나무 블록이 작아지게 만들 수는 없으니까. 만일 작아지게 만들  있는 것처럼 행동한다면, 이는 지금  앞에 보이는 것에 대해 스스로에게 거짓말을 함으로써 장래를 예측할  있는 기회마저 스스로 박탈하는 일이다.


이와 같은 스케줄 관리를 통해 얻을  있는  다른 부수적 효과는 많은 기능들 중에서 일부를 포기하게끔 만든다는 것이다. 포기하게끔 만드는 것이  좋으냐고? 여기  가지의 기능이 있다고 가정하자. 하나는 진짜로 쓸모 있고 장차 제품을 빛내줄 기능이고 (예를 들면, 넷스케이프 2.0 테이블 기능),  다른 하나는 코딩하기도 아주 쉽고 프로그래머가 만들어보고 싶어하지만 쓸모는 별로 없는 기능이다 (예를 들면, BLINK 태그).


스케줄 없이 프로젝트를 진행할 경우, 프로그래머들은 쉽고 재미있는 기능 먼저 코딩하기 시작할 것이다. 그러다가 나중에 시간이 부족하게 되면,   없이 유용하고 중요한 기능을 포기하게 된다.


프로젝트를 개시하기 전에 미리 스케줄을 수립하는 경우, 무언가를 포기해야만 하는 상황이 되면, 쉽고 재미있는 기능을 포기하고 유용하고 중요한 기능을작업하게  것이다. 스케줄을 관리하다 보면, 버려야  기능들을 프로그래머들이 스스로 추려내게 되기 때문에, 보다 나은 기능들로 구성된 강력하고 좋은제품을 만들  있게 된다.


필자가 엑셀 5.0 개발 프로젝트에 참여했을 때의 일이다.  당시 우리 팀이 계획했던 기능들이 워낙 방대한 양이었기 때문에 스케줄을 맞출 수가 없게 되었다. 팀원들은 고민했다. 이를 어쩌나! 전부  너무나도 중요한 기능들인데. 매크로 편집 마법사는 절대로 포기할  없어!


시간이 촉박해지자 별다른 도리가 없었다. 제품 출시 기한을 맞추기 위해 우리팀은 자식 같은 기능들을 잘라내야 했다. 포기하게  기능들에 대해 모두 마음 아파했다. 아픔을 달래기 위해 팀원들은 스스로에게 이야기했다.  기능들을 포기하는 것이 아니라 그저 조금  중요한 기능들을 위해 엑셀 6.0 버전으로 잠시미뤄두는 것뿐이라고.


엑셀 5 거의  완성되어갈 무렵, 필자는 동료인Eric Michelman 함께엑셀 6 버전에 대한 스펙을 만들기 시작했다. 

 사람은 머리를 맞대고 앉아엑셀 5.0 스케줄을 조정하면서 엑셀 6”용으로 미뤄둔 기능들을 다시 살펴보았다. 


우리는  기능들이라는 것이 너무나 조악한것들 일색이라는  놀라지 않을  없었다. 쓸만한기능이라고는 하나도 없었다. 물론,  기능들은  다음,  다음 버전에서도제품화되지 않았다.

 스케줄을 맞추기 위해 필요한 기능들만 추려낸 것이야말로 우리 팀이   중에서 가장 잘한 일이었다. 

그렇게 하지 않았다면, 엑셀5.0 개발 기간은  배쯤 길어졌을 것이고 아무짝에도 쓸모없는 쓰레기 같은 기능들로 50% 채워졌을 것이다. (넷스케이프 5.0이나 모질라(Mozilla)경우에도 분명히 이와 같은 상황이 벌어졌을 것이다. 스케줄도 없고, 확정된기능 목록도 없고, 쓸만한 기능만 추려내는  아무도 원치 않고, 그러다 보니제품을 출시할  없게  것이다. 그들은 결국 IRC 클라이언트처럼 시간을 들일만한 가치라고는 없는 기능들만 잔뜩 들어있는 제품을 내놓게  것이다.)


부록: 엑셀을이용할알아두어야것들

엑셀이 소프트웨어 스케줄 관리에 편리한 제품이라고 주장하는 이유 중의 하나는 대부분의 엑셀 프로그래머들이 오로지 엑셀 하나만 가지고 스케줄을 관리한다는 사실이다 (what-if 시나리오 같은 것을 분석하는 사람은 별로 없다...프로그래머들한테 그런  기대하면  되지!)


목록공유: 파일/목록 공유 명령을 이용하면 팀원 모두가 한꺼번에 파일을 열어두고 편집할  있다.  전체가 지속적으로 스케줄을 업데이트해야 하기 때문에,  기능은 아주 유용하다.


자동필터: 자동 필터 기능은 가령, 특정 프로그래머가 자신에게 할당된 작업만 전부 골라서 보고 싶을  스케줄을 필터링하는  편리하다. ‘자동 정렬 기능과 함께 사용하면, 자신에게 할당될 모든 작업을 우선순위에 따라 순서대로조회할  있다.  자체로 효과적인 작업 계획서 되는 것이다. 끝내주지?


피벗테이블: 피벗 테이블 기능은 요약정보나 크로스테이블을 보고 싶을 매우 편리하다. 가령, 각각의 우선순위에 대해,  개발자에게 필요한 잔여시간을 보여주는 도표를 만들  있다. 피벗 테이블은 결코 어렵지 않다. 반드시 기능을 사용하는  익숙해져야 한다. 엑셀을 백만 배쯤 편리하게 써먹을 있기 때문이다.


작업일기능: 엑셀의 분석 툴팩에 포함된 작업일(Workday) 기능을 활용하면 스케줄에 해당하는 실제 달력상의 날짜를 손쉽게 확인할  있다.


출처 : 조엘 온 소프트웨어 한국어 블로그 (http://korean.joelonsoftware.com/Articles/PainlessSoftwareSchedules.html)

Posted by 엘키 엘키

댓글을 달아 주세요

내 첫 IDE는 MS-DOS용 터보-C 2.0이다.


vi 정도는 아니었어도, 윈도우 기반 요즘 IDE와는 비교도 안될만큼 불편했다.


그런 환경에서 Visual Studio 5.0을 썼을때의 환경은 말그대로, 환호가 절로 나왔으며, MFC의 App Wizard는 신이 내린 하사품 같았다.


그렇다보니 GUI환경에 대한 동경은 갈수록 커져만갔을 뿐... 글씨만 줄창 보게되는 CUI (Console User Interface)에 대한 내 이미지는 "직관적이지 않고 어렵다" 였다.





알바 경험, 외주 경험을 다 제끼고 나면 나는 온라인 게임만으로 일해왔다.


내가 상업적인 프로젝트에 외주가 아닌, 직원으로 일한 것은 싸이미디어사의 믹스마스터였다.


당시 서버는 리눅스 서버였는데, 클라이언트 프로그래머였던 나로썬 점검시 심심하다고 나를 부르는 SE형 옆에서 서버 20대가량을 제어하는 터미널 창만 봐도 눈이 휘둥그레 졌었다.


여러개 떠 있는 세션에 같은 명령을 보내는 스크립트로 패치하시곤 했는데, 내 입장에서는 굉장히 신기한 작업이었다.


물론, 그저 신기했을 뿐 딱히 멋져보이진 않았다.




그러던 내가... 그 일로 얼마 지나지 않아 어쩌다보니 서버프로그래머가 됐다.


서버 프로그래머가 되고 서비스를 하다보니... 하... 먼놈의 관리해야 될 머신이 이렇게 많은겨....-_-


관리할 머신의 수는 팀마다 달랐고, 국가마다 달랐지만 최소 10대 가량은 관리해왔다고 볼 수 있다.



내 로컬에서 개발 머신까지의 적용은 그나마 괜찮다.


문제는 대부분 Local -> Develop -> QA -> Live 이런식으로 deploy 되는 과정에서, 실수가 유발됐다.


사실 점검은 국가마다 다르지만, 대게 새벽시간에 이루어지곤 한다.


유저가 가장 적은 시간대를 선택하다보니 그렇게 되기도 하고, 해당 국가의 시간에 맞추다보니 그렇게 되기도 하고.


그런 시간에 정신이 말짱해, 모든 프로세스를 실수 안하는 사람이 있나?


만약 있다해도 적어도 난 아니다.




작업은 가능한한 자동화 되어있어야했고, 그를 위한 서버 제어 시스템은 필수 였다.


내가 본 첫 서버 제어 시스템은 네X위즈사의 피X 서버 제어 시스템이었는데, 실질적으로 내가 사용한 것은 아니라 대략의 기능들과 어떠한 느낌인지만 알 수 있었다.



해당 서버 제어 시스템으로 관리되던 것은, 내가 클베때부터 합류했던 프로젝트인 네오액X의 포키포X인데, 


당시만해도 서버 프로그래머가 된지 얼마 되지 않았고, 업무량 자체가 절대적으로 많아 생각의 폭도 좁았지만, 그런 고민을 할 여유가 많지 않았다.


헌데 그렇게 바쁠 수록 실수는 나오기 마련.


패치할 서버를 FTP에 올려놓고, 패치 메일을 빼먹는 다거나, 업로드한 파일 경로를 잘못 메일에 기록한다거나...


특히 긴급 패치에 새로 나온 바이너리를 안올리고, 테스트하던 바이너리를 올린다거나 하는 등의 다급할때의 실수는 대부분 수작업으로 인한 파생 효과였다.




그래서 필요했던 것은 두가지였다.


1. 빌드 -> 배포까지의 자동화.


2. 배포 -> 실제 패치까지의 자동화




이렇게 되고나니 한결 편하게 패치를 진행할 수 있다.


서버가 몇대건 간에 말이다.



여기서 추가적으로 필요한 작업이 있다.


바로 서버 모니터링. 서버 제어 시스템의 핵심중 하나다.


서버가 죽었는지, 제대로 떴는지 등의 상태 체크를 모니터링 업체에만 맡길 순 없다. (실제로 모니터링 업체에 맡기는 경우도 드물고)



이런 기능을 개발하면서부터, 개발자의 시간을 아끼기 위해, 또 실수를 줄이기 위해 선 시간 투자에 대한 눈을 조금 떴다고 할까?


효율성이 떨어진 자동화나, 코드 생성기 작업도 없었던 것은 아니지만, 많은 작업들이 결과적으로 시간을 아꼈다.


애초에 덜렁대고 급한 성격인 나로썬, 급할 수록 돌아가지 못하다보니 잔실수를 자꾸 하게 됐었는데, 이를 자동화로써 해결하면서 큰 이득을 보게 됐다.


사실 과거에는 이런 솔루션 파는 회사 없나라는 고민을 좀 했었다. 범용 서버 제어 시스템...충분히 있을법하지 않은가?


요즘 보면 모바일 서버가 웹 기반으로 돌아섰고, AWS 등의 클라우드 기반 서버를 쓰다보니 자동화가 강제되는 면까지 있어, 이를 해낸 여러 사례가 들려오고 있다.


특히 cookbook같은 개념도 머릿속으로 그려봤던 개념이, 실제로 많이 실용화 된 것을 보자니 내가 해온 것보다 적은 공수로 실시간 서버 추가/제거를 해내는 모습을 보면 부럽기도 하면서, 뿌듯한 면도 있다. 당연히 앞으로 배울점도 많고.



다른 자동화에 대한 의지를 가진 분들의 생각은 다는 모르겠다만, 적어도 내 기본 전제는 "내가 편할려고", "똑같은 작업 여러번 하기 싫어서"다.


내가 당장 사무실에 없다해도, 혹은 누가 해도 되는 일로 만들기 위해서이기도 하고.


자동화도 하다보니 좀 늘더라. 특히 스크립트 언어를 적극 사용하니 좀 더 수월하기도 하고.



서비스 질이 갈수록 좋아지고 있다. 클라우드 서비스를 기반으로한 무인 원격 서버 증감도 이뤄지고 있더라.


요즘 트렌드를 보자면, 서버 제어 시스템을 앞으로 직접 구축하거나 보완하는 일은 많진 않을거라 예상은 되지만.... 서버 프로그래머로써 3번째 회사에서, 3번의 서버 제어 시스템을 담당 해본 입장에서, 이런 시스템을 구축하면 할 수록 업무 시간을 벌 수 있다.


node.js 등의 리눅스 기반 웹서버로써 구동하고자 하는 많은 회사들도 그렇게 하고 있다는 얘기도 들려오고 있고. 내가 한 많은 작업들이 AWS등에선 기본 지원하는 기능이기도하다.


조금 허탈하기도 하지만, 뭐 기술이란게 다 그런거 아닐까? 여하튼 좋은 모양새로 업계가 발전하고 있는것은 아주 맘에 든다. 



몇몇 분들을 보면 아쉬운 것이... 어째서 코드의 중복은 싫어하면서, 작업의 반복은 수긍하고 익숙해짐으로써 해소하려하는 걸까? 작업의 반복도 충분히 간소화하고 제거할 수 있다. 


개선할 수 있는 많은 것을 개선하고, 낭비되는 시간을 줄여야 진짜 즐거운 작업을 할 시간을 벌 수 있다. 우린 엔지니어다. 기술로 커버할 수 있는 것이 아주 많다. 조금씩만 더 효율적으로 일하도록 노력해보자.

Posted by 엘키 엘키

댓글을 달아 주세요

서버의 부하를 줄일 수 있는 부하 조절 정책으로, 블리자드의 디아블로2팀이 조치한 방법이 어떤 방법인지 알아보자.

1. 서버에 요청하는 액션이 일정 횟수 이상 반복되면 Trouble 유저로 판단.
* 방 입장/퇴장 반복
* 방 생성 후 일정 시간 이내에 빠른 퇴장
* 로그인/로그아웃 반복


2. Trouble 유저 (계정)로 판단시 해당 캐릭이 사용된 IP를 차단.
* Trouble 유저가 일정 시간내에 다른 IP에서 재사용된다면 그 IP도 차단.
* 한번 Trouble 유저로 인식되면 문제가 된 Trouble 사유가 아니더라도 (예: 방생성/퇴장 반복) 로그인만으로도 IP차단.


3. 빠른 방생성 입장/퇴장의 경우 ProcessID도 인식하는 것 같음. (정확하지 않음)
* 배틀넷 로그아웃후에 로그인을 통해 방 입장/퇴장 반복시에 간격이 짧으면 렐름 다운이 되는 경우가 발생.


4. 유저가 적은 새벽시간이나 낮시간에는 제약이 약한편
* 분명히 낮시간에는 잦은 반복과 더 빠른 반복도 유연하게 넘어갔었음.
* 유저가 훨씬 많은 시간 대에 같은 시간단위로 시도했음에도 Trouble 유저로 판정된다. (판단 규칙이 강화됨.)


5. 차단된 IP나 계정을 일정 시간 이내에 사용하면, 블럭 시간이 늘어남.
* 블럭되었다면 해당 계정을 묵혀두는 것이 좋다. 유동 IP의 경우는 IP를 재발급 받아서 시도 할 수 있었는데, 계정에 대한 제제가 들어가 있는 상태라, 바로 바뀐 IP도 블럭되었고, 블럭 시간은 계정단위로 지정이 되어있는 것 같다.
* 일반적으로 알려진 시간 (1시간)동안 사용하지 않았어야 했는데, 사용했더니 블럭 시간이 2배로 늘어났음. (정확치는 않음)
* 기본적으로 계정에 대한 블럭 개념 + IP에 대한 블럭 두가지 제약이 동시에 걸리는 구조로 예상됨.


6. 기타 사항
* 디아2의 경우 월간 사용료나 캐쉬템을 파는 게임이 아니기 때문에 강경한 정책을 사용할 수 있는편.
* 실제로 핵툴 유저 등 비정상 유저 계정 블럭은 CD-KEY단위로 이루어짐.
* 즉시 제제가 없다는 점은 좀 아쉽다.
* 서버 유지비를 줄일 수 있는 강경한 정책을 유지할 수 있는 장점이 있는 반면 사용자들이 불편한 점도 많이 갖고 있다. (디아2 배틀넷 초기에는 이렇지 않았음. 초기의 길고 잦았던 렐름다운을 겪고나서 취한 방법이 이 방식이라 생각됨.)

Posted by 엘키 엘키

댓글을 달아 주세요

1. 개체 단위 lock.

개체 수와 종류가 늘어날 수록 헬.

dead-lock 위험성도 매우 크다.

상위 개체 단위로 lock을 잠글 수도 있는데, 이마저도 상호 연관 이벤트가 늘어나면 헬이다.

사실 lock만으로 멀티스레드 로직을 구현한다는 것은 사실상 불가능에 가까운 복잡도를 만들어 낸다는 것을 이미 여러 프로젝트가 증명했다.


2. 데이터 사본 연산

그룹마다 (방 혹은 채널, 존) 스레드를 따로 생성하고 데이터 사본으로 연산 한 후 연산 결과를 이벤트로 다시 던져,  다음 턴 수행 전에 적용하는 방식이다.

기본적으로 턴(프레임이라 불리기도 하는) 단위를 잡고, 해당 단위마다 로직이 돈다는 것을 전제로 삼을 수 있어, 여러가지 계측의 기준점이 되기도 한다.


여러 그룹에서 동시 다발적인 변화가 발생해, 데이터 변경이 일어난다 해도 변경 사항들을 긁어와 턴 마다 적용하기에 문제가 생기지 않는다.

주로 응답을 message 개체로 변환해서 받기 때문에 message queue를 푸는 동작이 순서가 필요할 경우, 싱글 스레드로 풀어서 적용해도 된다.


주의 사항은 데이터가 클 경우 사본을 생성하는 과정이 무거울 수 있다는 점.

이런 과정도 delta를 잘 만들어 낼 수 있다면 가볍게 턴마다 수행 가능해, 정해진 영역 내에서는 비동기라는 생각 없이 프로그래밍이 가능하단 장점이 있다.


3. immediatly 연산

모든 오퍼레이션이 즉시 연산으로 이루어지게 설계 하는 방식이다. 현재 상황에서 즉시 알아낼 수 없는 정보는 취급하지 않거나, 티어를 옮기는 과정이 다른 요청에 영향이 없게 독립적으로 구성 되어 있어야 한다.

이 방식으로 구현하려면 middle-ware들도 non-blocking으로 응답 할 수 있는 구조로 지원되어야 한다. (혹은 그렇게 랩핑하거나)

즉시 연산을 위해선 connection (request) 대비 blocking 연산 비율이 1:1에 가까워야 한다.

가급적 cache 데이터 등에 접근해 blocking 도 줄이고, 계산 시간을 낮춰야 한다.

또한, 처리 티어를 옮겨 갔다 오게 되는 상황이 다른 요청에 영향을 끼치지 않으려면 stateless 해야 한다. (한번의 요청에 모든 필요데이터를 검증,취합,처리 해야 함을 의미)

대 다수의 web 서버가 이 구조라 할 수 있다.

Posted by 엘키 엘키

댓글을 달아 주세요

1. Through-put


초당 소화 가능 이벤트.

이는 DB나 연결된 기능들과의 교신/처리가 포함된 계측 이어야 한다.

분산 가능한 특정 이벤트들은 지정된 서버와의 교신 (P2P스러운 접근)만으로 처리함으로써, 비용을 분산 시킬 수 있다.

일반적으로 다음 두가지 측정이 이루어지면 된다.
- 프레임워크 (네트웍 엔진이라 불리우는) through-put.
- 로직 through-put.


2. Through Pipe-line

파이프라인이란 이벤트 처리를 위해 거치게 되는 과정을 표현한 것을 말한다.

구현 별로 다른 어떤 과정에서도 wait-free 방식으로 구현하는 것이 좋다.

어쩔 수 없는 상황이라면 해당 작업 전용 스레드를 할당 받는 것이 좋고.

Through Pipe-line은 스레드 디자인과 큰 연관이 있는데, blocking 동작이 있다면 퓨쳐 패턴으로 구현해 요청을 보낸 후, 다시 파이프라인으로 재 입력 받는 구조로 처리하는 것이 좋다.

핵심은 적절한 분산을 통해 병목 지점 제거, blocking 상황을 제거해 Through-put 향상을 노리는 것이다.


3. 순환 구조 체크

잘못된 순환이 이루어지면 이벤트 폭발이 일어날 수 있다.

상호 순환 구조가 안 생기도록 이벤트가 어떠한 순서로 파이프라인을 순회하는지 검사하고, 파이프라인을 오래 타거나 반복해서 타는 것이 불가능 하도록 제약을 걸 필요가 있다. (spin-count를 계산해 몇 번 이상이면 이벤트를 버리는 등의 처리가 필요하다)

4. base-line

base-line은 초당 로직이 몇회 동작할 것인지 (프레임), 그렇다면 한 프레임이 몇 ms까지 사용해도 되는지, 또 패킷은 몇초안에 수신된다는 것을 전제로 동작하는지 등이 명확히 규정지어져야 한다.

base-line을 넘어설 것이 의심되면 유저 수 제한, 특정 기능 제한 등을 통해 기존 접속한 유저/잘 동작하는 기능은 보호 받을 수 있도록 구현해야 한다.


5. run-time apply

run-time 접속제한, run-time 기능 제한, run-time 리소스 리로드 등이 그래서 필요하다.


6. 객체의 생성 소멸 관리

생성 시점과 소멸 시점은 같게 관리하는 것이 좋다.

만약 주체가 다른 tier나, 다른 프로세스 등이라 관리가 어렵다면, 이에 대한 보호 장치가 반드시 필요하다. 

어쩔 수 없는 상황이 아니라면 shared_ptr도 그다지 좋은 해결책이 아니다.

개체의 소유권은 가능한한 엄격히 관리되어야 한다.


7. 과한 보호 장치에 대한 억제

예외 상황을 검증하고 보호하기 위한 코드도 검사/검증 대상이다.

이런 코드가 문제를 일으킬 여지도 있으니 이러한 코드도 세워둔 전제를 위배하지 않는지 검사하고 검증하자.


8. 무거운 단일 이벤트 보다는 작은 이벤트로 처리하라.

가급적 모든 유저를 대상으로 하는 이벤트는 자제하고, 유저가 발생시키는 이벤트 단위로 동작 시켜라. (웹 서버 구조)

시간에 의존하는 이벤트 (heart-beat 체크, 아이템 유효 시간 체크, 날짜별 이벤트) 들도 비동기 처리 후, 적용 대상만 추려 작은 이벤트로 발생시켜라.

가능한 한 적용 대상 자체가 최대한 작게끔 유지 시키는 것이 좋다.

가능하다면 비동기 처리던 아니건 간에 목표 대상 자체를 줄이고, 기능이 정말 필요한 이벤트에 물려서 동작 시켜라. (코드 공유가 잘 되어 있다면, 클라이언트에 서버 연산 예상 결과를 적용 시키고, 서버는 해당 기능이 실제로 active 되는 시점에서 트리거를 동작시키는 방법도 있다.

가급적 polling보다는 event-driven을 선택하라


9. 확장성 (scalability)

결합도를 낮추면 자연스레 확장성을 높일 수 있다.

stateless를 의도하면서도 성능을 높일 수 있는지 검토하라.

서비스를 목적에 따라 작게 쪼개 관리할 수 있다면, (서비스 종류에 따라 관리 비용이 증가하지 않게 된다면)  확장성을 특히 runtime scale-in, scale-out을 좀 더 용이하게 이뤄낼 수 있다. 

'Software Engineering > Knowhow' 카테고리의 다른 글

디아블로2의 렐름 다운 정책에 대한 썰  (0) 2013.01.26
멀티스레드 로직 구현 방식  (0) 2013.01.26
서버 프로그래밍 핵심 정리  (0) 2013.01.26
문제 해결 노트  (0) 2009.02.03
나의 로그 기준  (0) 2008.02.23
서버 프로그래밍시 유의점  (0) 2008.01.14
Posted by 엘키 엘키

댓글을 달아 주세요

이전버튼 1 2 이전버튼

블로그 이미지
Software Engineer
엘키

공지사항

Yesterday31
Today27
Total1,605,481

달력

 « |  » 2020.8
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          

글 보관함