디아블로2 렐름 다운 정책 정리

서버의 부하를 줄일 수 있는 부하 조절 정책으로, 블리자드의 디아블로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 배틀넷 초기에는 이렇지 않았음. 초기의 길고 잦았던 렐름다운을 겪고나서 취한 방법이 이 방식이라 생각됨.)

서버 최적화 핵심 요약

  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을 좀 더 용이하게 이뤄낼 수 있다. 

단점 고치기

이직 한지 대략 한달쯤 됐군요.

입사하고 나서 느낀 가장 아이러니 한 것은, 오픈이 얼마 남지 않은 프로젝트인데도, 검증이나 테스트가 의외로 안되어 있더라는 점이죠.

유닛 테스트 자체는 적지 않지만 그 커버리지가 높다고 하기 어려운 상황이고요.

전반적인 자동화를 통한 커버리지를 올리는 작업을 주로 하고 있습니다. 계측/측정에 대한 업무 위주랄까요.

트러블 슈터로써 문제가 발생할 여지를 검토하고, 또 테스트를 통해 검증하는 작업을 맡게 됐다고 보시면 될거 같네요. (물론 조만간 컨텐츠 작업도 하게 되지 않을까…싶네요. 자동화를 통한 커버리지를 올리는 목표를 달성하고 나면 말이죠)

하다보면…이 일도 나름 재밌습니다. 안정적인 서비스를 해냈다는게 서버 개발자로써 뿌듯하게 생각해야 될 목표지점 중 하나니까요. (디아3 반성하라!!)

원래 성격 자체가 덜렁대는 데다가, 성격도 급하다보니 사고뭉치였던 저로썬 제가 트러블 슈터적인 성향의 개발자가 될꺼라곤 사실 상상하기 어려웠습니다.

저 역시도 다른 많은 분들처럼 열혈 게이머였으며, 아마추어 게임 개발자 출신으로써 그저 재미난 게임을 만들고 싶었던 사람일뿐이었습니다.

뭐 아마추어 게임 개발자이긴 했다보니 비정규직 개발 작업 (툴 외주 및 소규모 게임) 에 여럿 참여하다보니 아예 경험이 없는 개발자는 아니였죠.

뭐…어찌어찌 하다보니 휴학 없이 졸업을 하게 됐고, 군대 가기전 돈좀 모아놓고 가려고 1년정도 일할 곳을 찾던중 감사하게도 병역특례를 주신다는 회사에 입사하게 됐습니다.

그 조건은 서버로 전직…!!! 전직후 버라이어티한 사고들을 잔뜩 치고나니…. 아 내가 이런 실력으론 회사에도 민폐, 내 자신에게도 부끄럽고, 유저분들에게도 민폐겠구나 싶었습니다.

그래서 어떻게하면 사고를 많이 안치는 개발자가 될 수 있을까에 대한 고민이 많아졌고, 만약 실수를 하게 되도 빨리 해결하려는 노력이 생활화됐죠.

제가 가장 집중한 부분은, “나처럼 덜렁대는 사람이라도 사고치지 않기 위한 방법이 무엇이 있을까?” 였습니다.

그 과정에서 얻은 결론에 대한 즉흥적인 정리입니다.

  1. 커버리지를 높이는 것만이 살길이다.

당연히 자동화! 유닛 테스트는 커버리지의 일부일뿐.

유닛 테스트를 이용하면 그 기능의 개별 동작에 대한 검증은 이뤄지는데. 하지만 그 기능들이 맞물려 돌아가며 상호작용에 대한 부분을 검증하는 것은 어렵죠. 유닛 테스트는 당연히 필요하지만, 런타임 테스트도 반드시 필요합니다!

보통 서버의 경우는 이를 위한 테스트 클라이언트 구현이 이루어지는 경우가 많고, 테스트 클라이언트를 통해 자동화된 스트레스 테스트, 기능 테스트를 하면 됩니다.

  1. 적어도 알고 있는 부분에서 실수한건 잘 핸들링하자 꽤나 많은 실수…이 로직에서 실패하면 밑에 로직들은 엉망이 될걸 알면서 왜 핸들링 안하나요?? 리턴 값 없는 함수라면 throw를 통해서라도 1차 감염에서 바로 코드 흐름을 멈춰야합니다… 만약 아직도 예외처리 안하고 있다면 그거부터 하고!

예외처리가 잘되어있다면 throw랑 RaiseException의 적절한 활용은 코드 흐름을 catch한 상위 지점까지 코드 흐름을 옮길 수 있습니다. 

proactor등으로 비동기 작업을 던져놓은 경우에도, 적정위치를 try-catch로 감싸두면 코드 흐름 제어에 장점이 많아요.

  1. 자신을 믿지마라 도대체 얼마나 잘하길래 자기 코드에 테스트도 한줄 없고, 검사 로직도 한줄 없을까? 자신이 실력이 좋다해도 다른 사람이 쉽게 망가뜨리기 쉬운 코드 짜지말아야 합니다. 코드만으로 의도를 전달하는 건 굉장히 뛰어난 실력입니다.

const랑 접근 지정자만 잘써도 의도 파악이 쉬워집니다.

주석 달려있는 코드 고칠때는 주석도 고치고! (은근히 많은 코드가 변경시 코드만 고쳐져있고,주석이 수정안되서 두 내용이 다르면 크게 혼동이 오고, 코드를 훨씬 오래봐야되요. 주석 고치기 귀찮으면 지우기라도 합시다)

  1. 많이 짜봐라 누가 그러더군요… 3년차 넘어가면 코드 짜는거보다 설계가 많아진다고. 

하지만 제 생각엔 많이 짜고, 많이 지워버리는게 더 많이 늘고 더 좋은 결과물이 나온다고 생각합니다. 

생각한 대로 많이 돌려보고 마음에 들지 않으면 버리면 되는거에요. (은근히 한번 작성한 코드 아까워하는 사람 많은데 그러지 맙시다. 프로토타이핑은 어디까지나 프로토타이핑!).

run and fix를 통해 배우는게 많습니다. 코드를 읽기만할때랑 작성해보면 그 격차가 꽤나 큽니다.

TDD도 run and fix에 기반한거고 봐도 되요. 코드를 작성하는 과정에 수정이 함께 하니까요.

많이 짜고 지우고 유닛 테스트와 함께 코드의 커버리지를 높인다면 충분히 검증된 코드를 많이 짜고, 버려야 될 코드를 깨닳을 수 있습니다. (유닛테스트로 각이 안나오는 코드가 작성되는 경우가 종종있는데 이런 코드는 미련없이 버립시다)

  1. 책임감 갖고 일하자… 전 항상 예전에 제가 작성했던 코드와, 그 습관… 아마추어 시절과 클라이언트 프로그래머 시절의 마인드를 한심하다 생각합니다.

제가 짠 코드가 정상적인 상황에만 잘돌아가는 나약한 코드였던게 말이죠.

헌데 예전의 저처럼, 많은 개발자들이 자기 코드를 다방면으로 보지 못하더군요.

그런 방어적인 코딩 하는 사람들에겐 아무리 말해도 못알아듣겠지만… 남의 코드를 보는것 만큼, 자기 코드를 자주 들여다 보는 것도 꽤나 좋습니다.

어제 짠 코드 오늘보면 허접하다면, 오늘 다시 맘에 들게 고치면 됩니다.

refactoring 능력도 하는 만큼 늘더군요.

책임감 갖고 작성한 코드만큼 자기 실력을 늘려주는게 없다고 생각합니다.

당장 서비스에 들어갈 코드 아니라고 대충 짜지 맙시다.

특히 굳이 사용하지 않는 코드 언젠가 쓸꺼라 예상하고 만들어놓고, 유닛테스트도 안붙이고 그러지 맙시다. 

기능이 작성되어있으면 잘 동작할거라 믿고 쓰게 되는게 일반적이라구요.

이정도로 하겠습니다. 

저도 아직 갈길이 먼 개발자지만… 라이브 경험이 부족한 분들의 코드에선 느껴지는게 많습니다. 

뭐랄까… 유지보수하기 쉬운 코드란걸 원한다고 말은 하면서, 막상 다른 사람 코드나 자신이 짰던 코드를 들여다보며 느낀 불편함이 개선되지 않고, 습관대로 작성하시는 느낌?

팀작업이잖아요. 안좋은 습관은 함께 고쳐나갑시다.

새 회사를 한달쯤 다녔지만 아직 사람들도 낯설고 어색해서…아직 뭐 딱히 재밌게 다니고 있진 않습니다.

워낙에 바쁜시기인 것도 있을테고, 전에 다녔던 회사들에서 동료들과 친밀한 사이였던게 그리워서… ㅠ_ㅠ 

재입사 하는 사람들 마음이 이해가 간다는…

그래도 조금씩 친해져서 나름 재밌게 다니려 노력중이에요~

솔직히 이 곳을 얼마나 오래 다니게 될지 확신은 못하겠습니다만… 좋은회사인건 확실하다고 생각해요.

최소한 목표한바가 명확하고 그에 대한 의지는 있으십니다. (안되어 있는 것들은 여러가지 여건 등으로 인해 못해오셨던거란 느낌?)

저도 그에 힘을 보태고 싶고, 좋은 결과 이루고 싶네요.

사고뭉치를 위한 디버깅 방법 03

이번 시간에는 예고한 대로 버그 재발 방지에 대해서 알아보겠습니다.

저를 포함한 대부분의 개발자들은 버그를 만듭니다. 인재들이 모였다는 MS의 IE 베타버전이 얼마나 엉망인지 아시죠? QA와 오류 보고 시스템 등을 통한 검수가 정식 버전을 안정성있게 만드는 것이지 MS가 만든 제품도 버그가 많습니다. 그 들이 극찬하는 IOS나 OSX요? 네 그렇게 신중한 애플도 버그를 만듭니다. 특히나 많은 버그가 개발 과정에서 더더욱 많이 튀어나오는데, 이들 대부분이 개발자의 습관에서 비롯됩니다.

흔 히 많이 하는 실수가 초기화 오류(변수값의 초기화 값이 없다거나, 변수가 초기화 되는 시점이 잘못된 경우)라던가, 경계값 오류(임계치에 가까운 값을 잘못 설정한 오류), 연속 시도시 잘못된 결과가 도출되는 오류 (예를들면 결제 버튼 여러번 누르면 돈은 여러번 감소하고 아이템은 지급안된다던가하는 오류), 버그 수정시 다른 버그를 만들어 내는 문제 등이 있습니다.

생각보다 같은 종류의 실수를 자주 하는 사람이 많은데, 모 QA팀에서는 버그 스타일에 따라 담당자를 배정하는 사례도 있었다고 할 정도죠. 물론 어쩌다가 한번 나오는 버그는 개발자의 실수로 모두가 좋게 넘어가지만 같은 종류의 버그가 여러번 나오고, 제대로 된 수정이 이루어지지 않는다면 여러가지 측면에서 문제가 생깁니다.

QA팀에 없는 경우에는 개발팀 테스트 후 바로 서비스가 될 테니 더 말 할것 없고, QA팀이 있는 경우라해도 개발 과정의 버그도 줄여야 합니다. 반드시 그렇게 해야 하는 근거는 다음과 같습니다.

  1. QA팀에 신뢰를 심어주기 위해
    • 물론 QA팀은 몇번 같은 종류의 버그가 생겼다면 꼼꼼히 챙겨봐주신다. 하지만, 버그가 급격히 줄어든 걸 보면 뿌듯하고 개발팀에 신뢰도가 향상하게 되어있다.
  2. 우리의 버그를 검증해주는 QA팀 마저도 놓칠 수 있기에
    • 특히나 대규모 패치일 경우 더더욱 그런데, 체크 리스트 목록을 많이 작성하다보면 평소보다 테스트하는 디테일이 떨어질 수 있다.
  3. 안좋은 습관은 긴급한 코드 작성시 극도로 심해지기 때문에
    • 이건 주로 내가 그런데, 급하게 코드를 작성하다보면 안좋은 습관 (여러가지 측면을 다 고려해야 하는데, 현재 증상만 보고 버그를 수정한다거나 하는 경우)이 나온다.
  4. 멍청하단 소리를 듣지 않기 위해서
    • 같은 실수 여러번하면 멍청하다는 소리를 듣게 되있다. 듣기 싫다면 고쳐라.

이런 문제는 정상적인 개발자라면 대부분 2~3년차 때는 고치게 되는 편입니다. (안타깝게 비정상적인 개발자가 꽤 많죠…ㅠ_ㅠ 누구라고는 얘기 안하겠습니다.)

여하튼 개인의 습관에서 나오는 문제를 고쳐야 되는 이유에 대해 이야기 해봤습니다.

자 이제, 팀 차원에서의 버그 재발을 막기 위한 노력에 대해서 예를 들어 이야기 해보겠습니다.

개발자가 어느정도 숙련자 위주로 이루어져있는 팀이 있습니다. S프로젝트라고 지칭해보죠.

S프로젝트는 3년의 개발을 거쳐 OBT 직전에 와있는 사내에서도 주목받는 팀입니다. 그런데 이 팀에 인원이 부족하네요.
자 우리 회사는 어느정도 건실하고, 주목받는 팀에서 본보기가 되기 위해 신입도 뽑아보자고 마음을 먹었습니다.
10여명 면접을 보고 그 중 가장 성실하고 센스 있어 보이는 C를 뽑았습니다.

OBT가 시작됐습니다. 예상보다 반응이 좋습니다. 너무 반응이 좋다보니 유저가 폭발적이네요. 로그인이 잘 안된다고 합니다.
하지만 우리가 누군가요? 베타랑들 답게 능숙하게 트러블을 10분만에 빠르게 해결하고 정상화 시켰습니다.
게시판에서도 호평 일색입니다. 안정적인 서비스, 재미, 그래픽 모두가 만족스럽다고 합니다.
딱히 문제도 없다보니 OBT중이지만 이 행복한 팀은 OBT기간임에도 칼퇴근도 합니다.

반응이 좋지만 조금씩 불안해집니다. 미리 만들어놓은 컨텐츠가 1달치뿐이니까요. 슬슬 컨텐츠를 더 만들어야 할 때 입니다.
베테랑 개발자 A가 이 시기에 집안일로 어쩔 수 없이 자리를 비우게 됩니다.
해야 될 일은 많은데 한사람이 비어 어쩔 수 없이 C에게 컨텐츠 개발을 시켜봅니다.

그런데 똘똘해보이고, 센스 있어보이던 C가 실수 연발입니다.
개발과정이 A보다 몇배 오래 걸림은 물론이고, QA에서 발생한 버그를 한번에 수정하지 못하고 계속 여러번 오가게 만들어 QA도 늦게 끝나 야근하는 날이 늘어납니다.
다른 개발자들은 이 신입에게 불만을 토로합니다. 좀 모자란거 아니냐, 잘못 뽑은거 같다, 나 신입땐 안그랬다 등등...
팀 분위기는 조금씩 안좋아지고, 야근이 잦아지다보니 서비스 퀄리티는 조금씩 떨어집니다.
아 뭔가 잘못 되어가는거 같습니다. 우울해집니다.

노파심에서 말씀드리자면 이 이야기는 절대 신입을 뽑지 말자는 의미가 아닙니다. 상황이 이렇게 된데에는 잘 흘러가는 것처럼 보이던 S프로젝트 팀에 잠재적 문제가 있었습니다.

과연 이 팀의 문제가 무엇이었을까요?

  1. 개개인의 차이에 맞지 않는 일정 수립
    • 베테랑 개발자 A와 신입 개발자 C의 개발 속도 차이를 고려하지 않고 일정이 수립.
    • 여기에 + @로 신입 개발자 C는 코드 분석 시간과 업무 방식에 대한 적응 기간도 필요한데 이마저 고려되지 않았음.
  2. 개발 검수 과정이 없었음.
    • 너무나 숙련된 개발자들로 이루어진 팀이었다보니, 개발 과정에 대해 누구도 관심을 갖지 않음. 각자의 할일에만 포커스가 맞추어져 있었음.
    • 개발 검수가 없었다는 것은 코드 검수도 이루어 지지 않았다는 것이고, 신입 개발자 C가 작성한 코드가 지금껏 암묵적으로 지켜져오던 룰을 깼을 가능성도 있음.
    • 분명 개발 검수 과정이 제대로 이루어졌다라고 한다면 적절한 로그를 남기도록 작업했을 터인데, 이마저도 이루어지지 않음.
  3. 디버깅이란 경험이 많은 역할을 하는데, 이에 대한 리딩이 없었음.
    • 디버깅은 정상 동작과 비정상 동작의 차이와 증상을 힌트로 원인을 찾아내는 과정이다.
    • 신입 개발자인 C가 디버깅에 익숙할리가 없는데 이에 대한 방치로 인해 업무가 지연되었고, 이는 C가 아닌 개발팀이 만든 문제다.

실제로 이 팀에 내재된 문제는 더 있을 겁니다. 이런 상황을 만들었다는 것 자체가, 개발자 개개인의 역량에 지나치게 의존한다는 증거라고 볼 수 있기 때문입니다.

게다가 업무에 대한 교류와 검토가 이루어지지 않다보니, 베테랑 개발자 A라 할지라도 순간 정줄을 놓는 순간 버그를 양산할 여지가 다분합니다. 문제는 버그가 양산된다해도 우리의 희망 QA팀에서 대부분 잡아주시겠지만 개발 규약이라던지, 로그가 적절하게 취합되고 있는지, 예외 상황은 얼마나 잘 처리되었는지 등에 대한 검토마저 개개인의 역량에 맡기고 있다는 사실입니다.

요 새 PC가 워낙에 빠르다지만 클라이언트는 유저에게 배포되기 때문에, 서버는 많은 유저를 수용하고 그들의 요청을 처리해야 되기 때문에 속도도 중요한데, 검수가 없다는 것은 이 코드가 정상 상황에서 잘 돌아가기만 하면 된다고 여기고 있다는 얘기가 되는 겁니다.

이렇듯 꽤나많은 문제를 갖고 있는 이 팀이 문제들을 해결하기 위해선 몇가지 노력이 필요합니다.

  1. 오류 보고 시스템
    • M2 프로젝트에서 개발과정 도입되었다고 알려져 있는 이 시스템은, 나는 5명이상의 프로그래머가 함께 일하는 모든 개발팀에서 도입되어야 한다고 생각한다. 오류 보고 시스템을 적극 사용하는 과정중에 코드 검수가 이루어지며, 런타임 오류가 발생한 위치와 작성자, 원인 등을 명확히 파악하기에 유용하기 때문이다.
  2. 개발 규약
    • 암묵적이 아닌 개발 규약은 어느정도 존재할 필요가 있다. 뭐 띄어쓰기는 어떻게 하고, 네이밍은 어떻게하고 이런거보다는, 예외 처리는 어떻게 해야 하는지, 로그 기록에 대한 기준, 외부 라이브러리 도입 기준, 코드 관리 규약 (만들어져 있는 기능들에 대한 명세 및 관리) 등에 대한 이야기를 정리해놓고 손쉽게 관리하도록 노력하는 것이좋다.
  3. 코드 리뷰
    • 코드 리뷰를 어렵게 생각하지 마라. 개발 전에 작업 방향에 대해 이야기를 나눈 이후, 개발 테스트 이전이나 개발 테스트중 코드 검수를 요청하면 된다. 작업 방향에 대한 이야기가 선행되어 있기 때문에 전면적 리팩토링을 하게 될일은 없을 터이고, 개발 테스트 도중 발견됐을 버그나, 부분적인 코드 완성도를 끌어올리고 개발 규약에 맞는지, 유저에게 오류 발생시 어떻게 보여지고 어떻게 처리될지에 대한 고려를 중점적으로 보면 된다.
    • 다만 지나치게 잦은 코드 리뷰와, 코드의 큰 방향성을 뒤흔드는 코드리뷰는 옳지 않다. 이는 개발 미팅 후 개발자들 간의 조율 과정에서 끝나야 한다.
  4. 자동화 된 테스트
    • 유닛테스트 + 모듈 테스트로 분리되어 얘기되기도 하는데, 분리 가능한 코드 조각을 테스트 하는 것이 유닛 테스트, 외부 프로그램 내지는 포함된 코드가 실제 동작중인 프로그램을 대상으로 반복된 테스트를 통해 새로 작성된 코드가 이미 작성된 기능을 망가뜨리진 않았는지, 또 새로 작성된 코드에 대한 테스트를 작성함으로써 해당 기능에 대한 이해도를 높이는 순작용도 가지고 있다. *  또한 자동화된 테스트를 통해 크래시가 얼마나 자주, 또 매번인지 때때로 발생하는 지 등도 알아 낼 수 있다.
  5. 자동화된 측정 시스템
    • 자동화된 테스트에 함께 붙이면 되는 경우가 많으며, 성능 측정과 잔존물 측정이 함께 이루어져야 한다. 성능 측정은 perfmon과 같은 외부 프로그램을 통한 측정과, 코드 수행속도 측정, 부가 데이터 측정 (로그나 DB 데이터 등…)등으로 분류된다. 측정 대상은 상황마다 다르지만, 보통 퇴근시간에 측정 시스템과 테스트 시스템을 켜놓은 후 다음날 결과를 바탕으로 회의와 업무를 진행하는 식으로 이루어지는 것이 좋다.

이렇게 갖춰놓는다면 아무리 사고뭉치라해도 개발 과정에서 대다수를 캐치 할 수 있습니다.

자 이렇게 좋은 개발팀이 버그를 많이 만들지 않도록 구축해야 할 것들에 대해 이야기해보았습니다. 어느정도 디버깅에 대한 이야기를 마무리 한거 같네요. 아쉬운 부분이 좀 있지만, 디버깅에 대해 좀 더 진지하게 다시 할 얘기가 생겼을 때 연재하도록 하겠습니다.

다음 시간에는 디버깅 주제가 아닌 게임 개발 이야기로 찾아올게요~ 감사합니다.