본문 바로가기
Thoughts

당신의 커리어가 서쪽으로 간다면 (3)

by 이병준 2019. 10. 13.

그렇다면 개발자의 일상에서 불확실성은 어떤 형태로 등장하는가?

 

불확실성은 내가 잘 모르는 것, 그리고 내가 통제할 수 없는 어떤 것에서부터 등장한다. 내가 통제할 수 없는 것으로는 여러가지가 있지만, 주로 소프트웨어 납기에 관련된 것만 살펴보면 주로 다음과 같다.

 

  • 내가 이용하는 소프트웨어/서비스의 업데이트 주기 또는 릴리즈 사이클
  • 내가 속한 팀과 다른 서비스 소유자 또는 팀과의 협업 형태
  • 사용자로부터의 요구사항 
  • 시니어 리더십으로부터의 우선순위 변경 요청
  • 여러 프로젝트 사이의 컨텍스트 스위칭 오버헤드 
  • 내가 이용하는 소프트웨어/서비스의 가용성 

 

전부 시간을 들여 따져볼 가치가 있는 사항들이지만, 우선 제일 마지막 항목, 그러니까 내가 이용하는 소프트웨어/서비스의 가용성이 어떻게 내가 통제 불가능한 형태의 불확실성이 되기도 하는지 살펴보자.

 

보통 소프트웨어의 특정 기능('피처'라고 부르기도 하는)을 개발하고 납품하는 과정에 문제가 없으려면, 이용하는 소프트웨어/서비스의 가용성에도 문제가 없어야한다. 현대 소프트웨어는 복잡한 의존성(dependency)을 갖는다. 하나의 소프트웨어가 온전히 자족적으로 존재하는 경우는 이제 찾아보기 어려우며, 보통 하나의 제품은 다른 여러 소프트웨어/서비스에 의존한다. 여러분이 AWS/GCP 등에 의존하고 있다면, 여러분의 소프트웨어는 해당 클라우드 플랫폼이 제공하는 서비스들에 의존성을 갖는다. 여러분이 회사 내부적으로 공개된 다양한 서비스를 이용하여 소프트웨어를 개발하고 있다면, 여러분의 소프트웨어는 해당 서비스에 의존성을 갖는 것이다. 이 의존성은 프로젝트 개발 과정의 다양한 부분에 영향을 미치지만, 가장 결정적인 부분은 테스트이다.

 

여러분이 어떤 서비스를 만든다고 하자. 해당 서비스에 대한 변경사항을 배포하기 위해서는 다양한 테스트가 필요하다. 해당 변경사항을 머지한 이후에 서비스가 정상적으로 실행되는지는 가장 기본적으로 테스트해야 할 사항이다. 해당 변경사항을 머지한 이후에 해당 서비스의 응답 속도에 큰 변화가 없는지, 처리량에 큰 변화가 없는지를 검사하는 것은 조금 더 복잡하지만, 역시 필수적으로 요구되는 사항이다. 한편 사용자 경험 상에 어떤 부정적 변화가 없는지를 테스트하는 것은 훨씬 어렵다. 이런 부분까지 테스트하는 자동화된 툴을 도입할 수 있다면 좋겠지만, 그렇지 못한 경우도 있기 때문에 릴리즈 마지막 단계에서는 QA 엔지니어들의 도움을 받아 서비스를 수동 테스트하기도 한다. 

 

이 각각의 테스트는 단계적으로 이루어진다. 가령 서비스의 실행이 정상적으로 이루어지는지를 검사하는 것은 보통 알파 스테이지(alpha stage)에서 이루어지고, 서비스의 기본 기능에 부정적 변화(regression)이 없는지를 검사하는 것은 통상 베타 스테이지에서 이루어지며, 처리랑/응답속도/사용자 경험에 있어서 부정적인 변화가 없는지를 검사하는 것은 통상 감마 스테이지에서 이루어진다.

 

주목해야 할 것은 보통 알파/베타 스테이지에서 실행되는 서비스는 내부망을 바라보도록 설계되어 있어서, 해당 서비스가 의존하는 하위 서비스도 알파/베타 스테이지 버전을 이용하게 된다는 것이다. 한편 감마 스테이지에서 실행되는 서비스가 바라보는 타 서비스의 엔드포인트는 감마 엔드포인트, 그러니까 감마 스테이지에서 실행되는 서비스의 엔드포인트인경우도 있고, 실 서비스망에 위치한 서비스의 엔드포인트인 경우도 있다. 실 서비스에서 생성되는 데이터에 혼란을 야기하기 싫은 경우가 대부분이기 때문에, 보통은 감마 엔드포인트를 바라보도록 구성한다.

 

여기서 주의할 것은 내 알파/베타 스테이지 서비스가 이용하게 될 하위 의존성, 다시 말해 내가 이용해야 할 알파/베타 서비스들은 보통 굉장히 불안정하다는 것이다. 이름 자체가 알파/베타이므로 많은 팀들은 이들 스테이지를 그다지 적극적으로 관리하지 않는다. 이들 스테이지는 수시로 망가지고, 수시로 복구된다. 감마 스테이지 이후의 서비스가 정상적으로 동작하고 있다면, 많은 팀들은 알파/베타 스테이지에서 벌어지는 문제를 긴급하게 처리하려 하지 않는다. 실 서비스 망에서 지금 당장 벌어지고 있는 문제가 아니기 때문이다. 

 

그러나 망가진 알파/베타 스테이지 서비스는 해당 서비스에 의존하는 다른 팀들의 서비스 테스트를 곤란하게 만든다. 방금 머지된 서비스 변경 사항이 정상 동작하지 않는 것이 해당 변경사항에 끼어든 버그 때문인지 아니면 하위 서비스의 장애 때문인지 확인하기 어렵기 때문이다. 이 때문에, 많은 경우 시스템 변경을 A/B 테스트로 감싼 후 감마 스테이지까지 푸시한 뒤에 감마 스테이지에서 하위 서비스의 안정 버전을 이용해 테스트하는 고육책을 쓰기도 하는데, 보통 알파->베타->감마로 내 변경사항을 옮기는 데는 시간이 소요되기 때문에 (테스트되지 않은 변경사항을 코드리뷰하는 데는 갑절의 시간이 든다) 전반적인 개발 속도가 지연되는 결과를 낳고 만다. 

 

이런 형태의 불확실성은 프로젝트 계획 단계에서 추정하기가 어렵다. 그렇기 때문에 많은 개발자는 이런 문제가 생길 것으로 예상되는 태스크에 좀 더 큰 버퍼를 방어적으로 할당하기도 한다. 이런 버퍼는 프로젝트의 규모에 대한 추정치를 보수적으로 만들기 때문에, 전체 부서의 생산성에 큰 문제가 있는 것처럼 보이도록 만들기도 한다. 

 

이런 문제를 방지하는 좋은 방법이 무엇이냐에 대해서는 이견이 있을 수 있으나, 많은 개발자는 보다 공격적이고 선제적인 테스트 전략이 없이는 이런 형태로 드러나는 불확실성이 양을 줄일 수 없다는 데 동의할 것이다. 개발자가 변경사항을 마스터 브랜치에 머지하기 전에 e2e로 변경사항을 테스트할 수 있도록 허락하는 어떤 물리적 수단의 도입 없이는, 여러 팀이 지연 없이 협업하는 것 또한 물리적으로 어렵다.