첫 프로젝트 in Tanzu Labs

9 분 소요


탄주 랩스(Tanzu Labs)에 합류하고 최근에 첫 프로젝트를 마쳤다. 1월에 시작해서 총 20주 동안 프로젝트를 진행했다. 프로젝트를 중간에 잠시 멈췄던 기간을 제외하더라도 반 년정도로 상당히 긴 시간이었다. 쓸 이야기는 많지만, 굵직한 몇 가지 주제를 가지고 이번 프로젝트에 대한 회고 글을 써내려가고자 한다.

첫 애자일(agile) 프로젝트

예전에 같이 일했던 분 중에 나를 불러놓고 현재 자신이 프로젝트를 위해 얼마나 수고스러운 일을 하고 있는지 설명해주신 분이 계셨다. 프로젝트 설계 문서들, 단위 테스트 결과서, 고객과의 미팅 후 남긴 회의록들을 보여주면서 자신의 고충을 토로하셨다. 약 30분정도 넘게 말씀하신 후 마지막에 이런 한마디를 하셨다.

준현아, 이런게 애자일이야.
처음부터 꼼꼼하게 설계하고, 문서로 남기고, 그대로 잘 개발해서 끝날 때 테스트 결과들을 남기는 이 과정이 말이야.

'제가 알고 있는 애자일이랑 다른데요?'라는 말이 목 끝까지 차올랐지만, 굳이 하지 않았다. 나에게 있어 보이기 위해 이야기하는건지 아니면 정말 워터폴(waterfall)스러운 그 방식을 애자일이라고 믿고 계신지 궁금했다. 물론 당시엔 나도 애자일을 글로만 배워서 누구를 가르칠 수준은 되지 않았기에 그러려니 넘어간 것도 있다.그런 일이 있은 후에 얼마 지나지 않아서 지금의 탄주 랩스로 오게 되었다. 예전 피보탈 랩스(pivotal labs)로 수 십년동안 세계 각지에서 애자일, XP(extreme programming)를 전파하는 일을 하고 있는 조직이다. 처음 이 곳에 온지 얼마 안 된 나는 프로젝트 기간동안 팀원들의 일하는 방식을 계속 관찰했다.

과연 무엇이 다른가?

일단 개개인이 각자의 역할(role)에서 일하는 방식은 크게 다르지 않았다. 다들 퍼포먼스로만 보면 잘하다 못해 뛰어날 정도인데, '이 곳에서 부족한 사람은 나 뿐인가?' 싶었다. 반면, 팀으로써 일하는 방식은 기존에 내가 일하는 방식과 많이 달랐다. 기획, 디자인 그리고 개발이 각자 다른 조직으로 존재하지 않았다. PM 한 페어(pair), 디자이너 한 페어 그리고 개발자 두 페어씩 총 8명이 한 팀으로 움직였다. 우리는 이를 밸런스 팀(balanced team)이라고 부른다.

밸런스 팀은 프로덕트(product)를 만들 수 있는 모든 구성원들이 한 팀에 모여 있는 것을 의미한다. 팀 스스로 자생력이 있고 모든 결정을 팀 안에서 할 수 있다. 내 옆엔 나의 짝 개발자와 다른 개발자 페어가 앉아 있었고 뒤에는 디자이너 페어, 대각선엔 PM 페어가 앉아서 한 공간에서 일했다. 컨텍스트(context)가 제대로 맞지 않는 부분들은 그 자리에서 피드백하고, 서로 이해하고 즉시 반영해줬다.

내가 왜 밸러스 팀을 색다르게 느꼈는지 이야기하기 전에 애자일을 다시 돌아보자. 나는 이번 프로젝트를 마무리하면서 애자일을 이야기할 때 가장 공감되는 문장이 하나 생겼다.

변화에 대응하는 능력

비즈니스 요건들은 계속 변하고 우리는 변화에 빠르게 대응해야 한다. 변화로 인해 발생하는 문제들을 해결하거나 또 다른 성공을 위해 무언가를 만들어야 한다. 그 것을 잘 만들었는지 검증하고 앞 선 행위들로부터 더 잘해낼 수 있는 무언가를 배워 나가야 한다. 변화에 신속하게 대응하기 위해선 팀이 스스로 결정하고 앞으로 나아갈 필요가 있다. 크지 않은 커뮤니케이션 비용으로 변화에 대응하기 위한 최선의 선택을 하고 결정을 즉시 실행으로 옮기기 위해선 밸런스 팀은 필수가 아닐까 싶다.

애자일하면 떠오르는 활동들은 당연히 했다. 많은 회사들이 자신들의 일하는 방식을 소개할 때 많이 봤었는데 다른 곳에서도 이런 활동들은 이미 잘하는 것 같다.

  • 일일 팀 스탠드 업(stand-up)
  • 스티키(sticky)를 붙혀가면서 아이디어 도출
  • 한 주 마무리 레트로(retro)
  • 한 주 단위로 이터레이션 미팅과 포인팅
  • 프로덕트 개발과 속도 측정

이번 프로젝트를 통해 내가 얻은 인사이트(insight)는 이 정도인 것 같다. 아는 만큼 보인다고 했던가. 지금 상황을 게임으로 비유하자면 마치 저렙이 고렙 사냥터에서 쩔 받는데 레벨 차이가 너무 커서 경험치를 다 못 먹는 느낌이다. 앞으로 열심히 공부해서 다음 프로젝트에선 더 많은 것들을 보고, 배우고, 정리할 수 있으면 좋겠다.

개발자로서 성장

개발은 11주 동안 진행했다. 프로젝트를 진행하면서 생기는 궁금한 것들은 즉시 해결되었기에 프로덕트 개발이 상당히 즐거웠다. 애매 모호한 서비스 요건은 대각선에 있는 PM들에게 달려갔고, 디자인이나 사용자 인터랙션이 궁금하면 뒤에 있는 디자이너에게 물어봤다. 일이 즐거웠던건 둘째치고 나는 이번 프로젝트에서 개발자로서 어떤 성장을 했는지 돌이켜 봤다.

기술 스택의 확장

나는 Java를 사용하는 백엔드 개발자로 시작했다. 주로 Spring MVC, Spring Boot, Spring Cloud, JPA, MyBatis를 사용했다. 내 블로그 포스트 주제들만 봐도 대부분 백엔드와 관련된 내용들이었다. 작년 스타트업에서 일할 땐 Vue.js를 사용했다. 프레임워크를 사용하여 화면 개발은 가능했지만, 풀-스택 개발자라고 하기엔 어림도 없던 실력과 지식 수준이었고 나도 깊게 파고들지 않았다. 퍼블리셔(publisher)의 역할이라고 생각한 스타일 작업은 거의 쳐다도 안 봤다.

이 곳에 와서 사정이 달라졌다. 팀은 풀-스택 개발자를 원했기 때문에 초반엔 프론트엔드 관련된 지식을 탐구하는데 많은 시간을 보냈다. JavaScript, React, CSS, SaSS 관련된 강의나 책들을 찾아 보고 블로그 주제로 선정해서 글을 쓰기 시작했다. 공부하면서 느꼈지만, 프론트엔드 관련된 기술 스택들은 상당히 심오하고 그만큼 알아나가는 재미가 있었다. 이번 프로젝트에선 MVP(minimum viable product)를 처음부터 릴리즈 버전까지 모두 직접 개발했다. 화면 스타일, 프론트엔드 서비스, 백엔드 서비스까지 내가 모르는 코드가 없었다. 좋은 프론트엔드 서비스 코드를 작성하기 위해 이전보다 고민이 많아졌다. 고민이 늘었다는 것은 잘하기 위해 노력을 한다는 좋은 신호라고 생각한다. 프로젝트가 끝나고 여유 시간동안 더 딥-다이브(deep-dive)할 계획을 세웠다.

시스템 분석 및 리팩토링 능력

신규 서비스이긴 했지만, 레거시 시스템에 의존도가 높았다. 아무래도 비즈니스의 많은 부분이 레거시 시스템에 녹아 있다보니 분석할 시간이 필요했다. 혼자서 했다면 시간이 오래 걸렸겠지만, 팀 개발자들과 함께 탐색해나가니 하루 이상을 넘어가는 경우는 거의 없었다. 레거시 시스템을 확인해나가는 과정에서 아래와 같은 어려움을 겪었고 결국엔 해결해냈다.

  • MSA(microservice architecture) 구조인데 처음엔 서비스들 사이의 연결 고리를 찾기 어려웠다.
    • 처음 시스템을 구축할 때 외주사에서 만들어준 아키텍처 구성도를 보면서 어떤 서비스들이 있는지 식별했다.
    • 현재 운영팀에 문의해서 서비스들 사이의 연결 관계를 확인하고 필요한 서비스들을 받아서 디버깅하기로 결정했다.
  • 디버깅을 위해 다운 받은 서비스들은 실제로 동작하지 않았다.
    • 서비스를 띄우기 위해 로컬에 별도로 필요한 jar 파일이나 dll 파일의 경로가 환경 변수로 설정되지 않은 문제로 보였다.
    • 서비스 실행을 방해하는 예외(exception)와 관련된 의존성들을 과감하게 제외시키니 서비스가 정상적으로 동작했다.
  • 비즈니스 로직이 산재했다.
    • 백엔드와 쿼리에서 적절한 비즈니스 로직을 찾을 수 없었는데 JSP 파일에 하드 코딩된 로직이 3000 줄 넘어가는 것을 보고 경악했다.
    • 특정 날짜마다 돌아가는 쿼츠(quartz) 서비스에서 SQL 프로시저(procedure)를 돌리는데 자기들만의 기준으로 중요한 데이터들을 엎어쳤다.
  • 사내 EAI(enterprise application integration) 시스템과 연결된 메세징 서비스의 프레임워크가 생소했다.
    • 아파치 카멜(Apache Camel)이라는 메세징 프레임워크를 사용 중이었다.
    • 아파치 카멜의 동작 메커니즘과 TDD 실천을 위한 테스트 작성 방법들을 공부하고 고민했다.
  • 지저분한 메시징 서비스 리팩토링
    • 다른 프로젝트의 코드를 복사, 붙혀넣기하면서 계속 돌려썼다는 것을 의미 없는 코드나 설정들을 보면서 확신했다.
    • 레거시 시스템의 메세징 서비스를 우리의 비즈니스를 위한 별도 서비스로 다시 만들었다.
    • 적절한 테스트 코드를 작성한 후 테스트가 깨지지 않는 선에서 의미없는 코드들은 제거하고 메소드들을 작게 나누는 리팩토링을 수행했다.
    • 리팩토링을 수행하니 숨은 비즈니스 로직들이 보이기 시작했는데 이를 커버할 수 있는 테스트 코드들을 추가했다.

레거시 시스템과 씨름하다보니 몇 가지 재밌는 일들이 있었다. 한번은 레거시 서비스를 디버깅하는 중에 막히는 부분이 있었는데 시스템 운영자에게 문의를 하니 엉뚱한 소리를 했다. 우리는 디버깅 포인트들을 찍어놓고 데이터를 보면서 이야기를 하고 있었지만, 자꾸 우리가 틀렸다는 식으로 이야기했다. 나와 @jskim1991은 우리가 틀리지 않았다는 확신이 있었고 라인을 하나씩 읊어가면서 설명하니 나중엔 자신이 착각했다고 시인했다. @jskim1991이 주먹을 번쩍 들어서 분노를 표현했는데 당시 장면은 지금 떠올려도 웃긴다.

다음으로 다른 운영자에게 로컬 서비스가 EAI 시스템과 연결이 되지 않는 현상에 대해 문의했었다. 동작하는 모습과 아키텍처 구조를 보면 EAI 시스템으로부터 응답을 받지 못하는게 이상했다. 집요하게 문의하니 시스템 운영자는 로컬에선 응답을 받을 수 없다며 나를 한심한 개발자 취급했다. 자기 자리로 오면 알려주겠다는 식으로 말하고 전화를 끊었는데 분한 마음에 코드와 설정을 꼼꼼히 확인해보니 IP가 잘못 매칭되어 있었다. IP를 제대로 맞춰주니 EAI 시스템으로부터 응답 메시지를 받을 수 있었다.

저희가 맞았고 운영자님들께서 틀리셨습니다.

TDD(Test Driven Development)

처음 테스트 코드를 작성하기 위한 연습을 돌이켜보면 테스트를 하나 작성하는데 오랜 시간이 걸렸다. 특히 프론트엔드 쪽 테스트는 더 어려웠다. 기술 스택은 어색했고 비동기 처리 때문인지 테스트가 원인을 알 수 없이 깨질 때도 많았다.

테스트를 먼저 작성하고, 실패시키고, 통과시키기 위한 구현체를 작성하라고?

구현할 프로덕션 코드는 금방 생각해냈지만, 테스트 코드는 쉽사리 떠오르지 않았다. 구현 코드를 검증하기 위한 테스트 코드를 작성하는 연습을 프로젝트 투입 후에도 쉬지 않았다. TDD 연습을 위해 TODO 어플리케이션을 몇 번이나 만들고 지웠는지 모른다. 우리는 제품 딜리버리 뿐만 아니라 고객사 개발자들의 실력 향상까지 책임지는데, 집에서 테스트 코드를 작성할 때마다 옆에 있는 가상의 개발자에게 설명하는 연습을 했다. 거실에 있던 와이프는 나를 미친놈이라고 생각했을지 모른다.

연습한 성과는 확실히 있었다. 개발 이터레이션 동안 종종 막힐 때도 있었지만, 생각보다 원활히 테스트들을 작성해나갔다. 사용자 스토리가 명확하다면 테스트를 작성하는데 큰 어려움이 없었다. 중간에 비즈니스 요건이 변경되었거나 신규 기능이 기존 로직을 비집고 들어올 때마다 이전에 작성된 테스트들은 우리들에게 용기를 주었다.

지금 스토리를 우선 진행하고 테스트가 깨지는 부분이 있으면 살펴봐요.

부족했던 점

다음에 더 잘하기 위해 이번 프로젝트에서 무엇이 부족했는지 생각해 봤다.

What is next?

나는 MVP 서비스를 만들 때 발생할 수 있는 리스크를 미리 감지하는 테크니컬 디스커버리에 적극적으로 참여했지만, 실속 있지는 않았던 것 같다. 당시 상황들이 정확히 기억나진 않지만, 내가 항상 좋다고 생각한 아이디어들은 그 다음 우리가 어떤 액션을 취할건지 고민을 했을 때 함께 떠오르는 것들이 많았다.

모바일 앱에 웹뷰로 서비스하기로 했어. 안 되면 백업 플랜은 무엇이 적절하지?
레거시 클라우드에 서비스를 배포하기로 했어. 배포해보려면 무엇이 필요하지?

다음 우리가 취해야하는 액션들을 생각하고 필요한 것들을 꼬리에 꼬리를 물면서 떠올리는 연습이 필요할 것 같다. 이번에 릴리즈가 늦어졌는데 가동계 배포를 위한 준비를 처음부터 개발과 함께 진행했다면 회사 정책 등으로 릴리즈 시기가 밀리진 않았을 거 같다. 제한된 시간동안 해결할 것들이 많기 때문에 미리 리스크를 수면 위로 끄집어 올릴 수 있는 집요함을 장착할 필요가 있다는 생각이 들었다.

꼼꼼하지 못한 일 처리

모든 테스트가 정상적으로 동과했으니 우리의 로직은 문제가 없어요.

테스트가 모두 통과해서 코드를 커밋(commit)하고 푸시(push)했는데 두 번이나 문제를 일으켰다. 첫번째는 로컬에서 사용할 수 없는 빈(bean)을 만들었는데 다른 페어의 로컬에서 서비스를 띄우니 에러가 발생했다. 두번째는 개발 환경에 테이블이 제대로 준비되지 않았는데 예외 처리도 똑바로 하지 못 해서 개발계 배포한 서비스가 문제가 됐다. 예전 MES를 운영할 땐 단위 테스트들이 없어서 로컬에서 서비스를 띄우고 많은 테스트를 하고 코드를 올렸다. 개발 환경과 스테이징 환경은 잘 동작했더라도 가동계에 배포할 때는 식은 땀을 흘렸는데 벌써 그런 쫄깃함을 잊었나보다. 아니면 단위 테스트라는 안전 장치가 느슨함을 만들었는지도 모른다. 앞으로는 운영 중인 서비스를 변경한다는 마음가짐으로 더 꼼꼼하게 일하는 버릇을 들여야겠다.

로컬에서 서비스를 한 번씩만 띄워 봤더라면 문제를 발견했을 거라는 아쉬움이 남았다. 스타일을 입히는 작업도 아직 꼼꼼함은 많이 부족한 것 같다. 큰 틀이나 형태는 비슷했지만, 세세한 디테일들은 다른 페어에서 많이 작업해줬다.

XP 개발자

프로젝트가 끝나고 일본에서 오신 PM분께서 피드백 워크샵을 진행해주셨다. 좋은 피드백을 주는 방법에 대한 워크샵이었는데, 왜 피드백이 필요한지 설명하기 위한 도입 부분이 상당히 인상적이었다. 도입부는 '우리가 변화에 빠르게 대응하고, 문제를 해결하기 위해 어떤 것들이 가치(value)가 있다고 믿고 있는지'에서부터 시작했다. 믿고 있는 가치를 지키기 위한 원칙(principle)들을 소개하고, 원칙을 밑바탕으로 우리가 지금 어떤 활동(practice)들을 하고 있는지 이야기해주었다.

다음 날 몇 팀원들과 이야기를 해보니 다들 어제 워크샵이 너무 좋았다는 평가를 들려줬다. 나는 팀원들과의 대화에서 나를 포함한 팀원들이 애자일과 XP에 대한 일본 PM분의 철학과 신념에 공감하고 있다는 느낌을 받았다. 그 분이 자신의 철학을 다른 사람에게 설득력 있게 전달하기 위해 얼마나 많은 공부를 했는지 상상조차 되지 않는다. 프로젝트를 돌이켜보면 나는 고객들에게 VMWare 개발자들은 “열정 있고 일을 잘한다.”라는 인상은 심어줬을지 모르겠지만, XP 가치와 원칙을 전달하고, 왜 팀이 애자일스럽게 움직여야하는지 깊은 공감을 이끌어내진 못 했다고 본다. 나는 애자일 문화와 XP 개발 방법론을 전파해야하는 XP 개발자, 애자일 컨설턴트로서의 점수는 높지 않았다.

TDD(Test Driven Development)

TDD 사이클을 지키는 일에는 익숙해졌지만, 당연히 완벽한 TDD를 구사했다고 이야기하진 못 한다. 최근 랩스 개발자 한 분과 대화에서 나는 유저 스토리를 커버할 수 있는 테스트를 작성할 줄은 알지만, 좋은 테스트 코드란 무엇인지 고민해보지 않았다는 점을 깨달았다. 읽고 있는 책에서 소개하는 좋은 테스트 코드의 4가지 특성을 이야기해주셨다.

  • 회귀 방지
  • 리팩토링 내성
  • 빠른 피드백
  • 유지 보수성

나는 4가지 특성 중에 어떤 것도 고민해보지 않았다. 읽고 있다는 책 제목을 묻고 대화가 끝나자마자 구매했다. 그리고 프로젝트 마지막 쯤엔 생각치 못한 유스 케이스(use case)로 단위 테스트를 통해 커버하지 못한 버그를 발견했다. 이런 부분들도 어떻게 잘 메꿀 수 있을지 고민해봐야겠다.

모자란 부분을 채우는 방법

아무래도 책을 많이 읽어야 할 것 같다. 시간은 한정되고 몸은 하나이다 보니 경험은 한정적일 수 밖에 없다. 다른 사람들의 경험이나 노하우를 책을 통해서 배우고 아는 것을 넓혀갈 필요가 있다고 느꼈다. 올해 초반에 작년을 회고했던 글 마지막을 보면 올해 읽고자 목표로 삼은 책들이 있었다.

실제로 프로젝트 기간동안에 지하철을 타고 출퇴근하면서 읽은 책들은 다음과 같다.

한번 읽었다고 끝이 아닌 것 같다. 책을 덮고 나면 내가 뭘 읽었는지 머리 속에 남지 않는데 다시 읽어보면서 내가 얻은 인사이트들을 문서로 정리해나갈 생각이다. 올해 읽을 책들을 우선 순위 별로 다시 나열해보면 다음과 같다.

2022년을 반이나 지내고보니

카테고리:

업데이트:

댓글남기기