회원가입을 하면 원하는 문장을
저장할 수 있어요!
다음
AWS 이용 중이라면 최대 700만 원 지원받으세요
국내 IT 기업은 한국을 넘어 세계를 무대로 할 정도로 뛰어난 기술과 아이디어를 자랑합니다. 이들은 기업 블로그를 통해 이러한 정보를 공개하고 있습니다. 요즘IT는 각 기업의 특색 있고 유익한 콘텐츠를 소개하는 시리즈를 준비했습니다. 이들은 어떻게 사고하고, 어떤 방식으로 일하고 있을까요?
회원가입을 하면 원하는 문장을
저장할 수 있어요!
다음
회원가입을 하면
성장에 도움이 되는 콘텐츠를
스크랩할 수 있어요!
확인
국내 IT 기업은 한국을 넘어 세계를 무대로 할 정도로 뛰어난 기술과 아이디어를 자랑합니다. 이들은 기업 블로그를 통해 이러한 정보를 공개하고 있습니다. 요즘IT는 각 기업의 특색 있고 유익한 콘텐츠를 소개하는 시리즈를 준비했습니다. 이들은 어떻게 사고하고, 어떤 방식으로 일하고 있을까요?
이번 글은 쓰다가 버려진 컴퓨터의 시각으로 세상의 변화, 개발 환경의 변화를 기록한 한 편의 소설 같은 글로 ‘여기어때’ 백엔드 개발자가 작성했습니다. 바쁘게 달려온 올 한 해도 벌써 마무리를 앞두고 있는데요. 이 글을 통해 각자 올 한해 겪은 많은 변화, 그 안에서 우리가 얻었거나 잃은 것들에 대해 사색해보는 시간을 가져보시길 바랍니다.
내가 처음 눈을 떴을 때 X세대와 MZ세대 경계선 어딘가에 있는 아저씨가 날 쳐다보고 있었다. 그는 내 사양을 살펴보고 무선 인터넷을 설정했다. 그리고 빠르게 프로그램들을 설치했다. 설치한 프로그램 중에는 버전별 JDK, Node, IntelliJ, DataGrip, VSCode 들이 포함되었다. 프로그램만으로도 내 앞에 아저씨는 개발자라는 걸 확신할 수 있었다. 나는 나와 같이 만들어진 동기들보다 더 많고 강도 높은 일을 할 거란 걸 예상했다.
한 달 정도 아저씨는 개발을 하지 않았다. 팀 동료들이 진행하는 온보딩을 듣고 질문하고 답을 기록하는 정도. 컨플루언스 문서를 보고 팀에서 관리하고 있는 프로젝트를 체크아웃받아 실행해 가면서 이것저것 확인하는 게 고작이었다. 이후 간단한 운영 이슈 티켓을 받아 처리했다.
오늘도 아저씨는 운영 이슈를 처리하고 있다. 각 부서의 요구사항, 기존 서비스의 문제점 보완 등. 그러다 사건이 터졌다. 슬랙 운영채널에 긴급한 이슈가 올라왔다. 몇몇 예약 건에 대한 상태 값이 변경되지 않는 문제였다. 이슈 내용을 보니 일반적이지가 않았다. 아저씨는 뭔가 느낌이 왔는지 글을 남겼다.
“며칠 전에 제가 작업한 게 원인인 것 같아요.”
그렇다 아저씨는 며칠 전 주문 테이블이 가지고 있는 필드 값을 업데이트하는 배치 작업을 만들었다. 배치 주기는 1분. 내가 보기에도 그 작업에서 문제가 된 것 같다. 빠르게 상황이 전파되고 일단 문제가 된 배치작업을 중지시켰다. 각자 재택근무를 하고 있어 화상회의를 통해 상황에 대한 정리를 했다. 동료들은 역할을 나눴다. 총 160여 건의 예약 건에 대해서 데이터 보정을 해 문제를 해결했다. 일단 상황은 종료됐다.
“저 때문에 고생 많이 했네요. 고맙습니다. 은혜는 꼭 갚을게요.”
“술로 해결하셔야죠”
“5년 전에 공항에서 사둔 발렌타인 17년 있어요. (미개봉)”
“21년 미만 비취급”
“술은 나이를 안 먹는데, 왜 사람은 먹는지…”
대화를 보고 있자니 마지막 고비를 넘긴 뒤 썰렁한 농담을 주고받는 재난영화의 장면이 떠오른다.
아저씨는 자기가 만든 프로그램의 문제점을 분석하기 시작했다. 원인은 생각보다 단순했다. 데이터 동시성 문제였다. 두 개 이상의 서비스가 하나의 Row를 Read → Read → Write → Write 순서로 update 한 것이다. 그러니깐 직전 업데이트 결과를 덮어 씌워서 발생한 문제다. 또 다른 원인은 JpaRepository.save() 메소드를 사용해서 update를 한 것이다. 이렇게 되면 특별한 처리를 하지 않는 이상 모든 필드가 update 문으로 만들어진다. 두 가지 원인 중 하나만 방어했어도 문제는 발생하지 않았다. 아저씨가 만든 배치 프로그램은 예약 상태 값을 업데이트할 필요가 없다. JpaRepository.save() 메소드를 사용하지 않고 필요한 필드만 업데이트해서 문제를 해결했다.
이것 말고도 직간접적인 여러 문제가 있었다. 인상 깊은 것만 나열해보겠다.
새롭게 API하나를 추가했다. 다양한 상황을 만들어 개발환경에서 테스트를 마쳤다. 운영으로 배포하던 중 상황이 터졌다. API가 너무 느린 것이다. 이때도 아저씨는 긴장한 표정이었고 우선 배포 이전 버전으로 롤백했다. 관련 팀들에 상황을 전파하고 분석에 들어갔다. 원인은 너무도 단순했다. 인덱스를 타지 않는 쿼리가 실행된 것이다. 새롭게 쿼리를 만들면 당연히 운영 DB에서 실행계획을 확인해야 하는 거 아닌가? 아저씨는 이 단순한 걸 확인하지 않았다. 이 일을 겪고 배포 체크사항에 ‘쿼리 실행계획 확인’이란 단계가 추가 됐다.
또 하나는 API 스펙을 제대로 확인하지 않아서 발생한 문제였다. 큰 이벤트가 있었다. 예약 완료 단계에서 타사 서비스와 API 연동을 해야 되는 작업이 있었다. 시간에 맞춰 이벤트가 시작되었고, 얼마 지나지 않아 모니터에 에러로그가 올라가기 시작했다. 아저씨는 급히 연동 회사 개발자에게 연락해 상황을 설명했다. 원인은 특정 필드 값을 100byte 이내로 보내야 하는데 초과해서 보낸 것이다. 해당 필드는 값이 길면 잘라 보내도 되는 부가 정보였다. 트래픽은 밀려드는데 다시 테스트하고 배포하기에는 시간이 부족했다. 다행히 상대 회사가 API 허용 길이를 늘여 주어 해결이 됐다. 더 다행인 점은 API 연동은 주문 프로세스 후처리 배치 단계에서 처리가 되었다. 핵심 로직인 주문과 별도로 동작해서 큰 문제없이 부드럽게 넘어갔다. 오늘도 아저씨는 안도의 한숨을 쉰다.
NullPointerException은 흔한 에러다. 흔한 만큼 다양한 상황에서 발생된다. 기존 운영하던 소스를 간단하게 변경했다. 그런데 그 변경 때문에 NPE가 발생했다. 일반적인 상황이었다면 개발 단계에서 걸렸겠지만, 특수한 상황에서만 발생하는 에러다. 자세히 이야기하면 특정 쿠폰을 사용한 주문 건에 대해서만 에러가 발생했다. 아저씨는 쿠폰 코드 값이 null 아니라고 생각하고 개발했다. 며칠이 지나 고객센터를 통해 장애가 접수됐다. 동료가 문제를 분석해서 알려 줬다. null check 하나만 해도 되는 간단한 수정이었다. 더 근본적인 문제는 슬랙 장애 메시지를 무시했기 때문이다. 카드 한도 초과 같은 사용자 에러가 너무 많이 슬랙 메시지로 들어와 정작 의미 있는 장애 메시지를 확인하지 못했던 거다. 이 상황을 인식한 동료가 슬랙에 보낼 에러 메시지 범위를 좁히는 작업을 했다.
에러는 테스트 코드에서도 걸러지고 코드 리뷰에서도 걸러지고 QA 단계에서도 걸러진다. 필터를 많이 그리고 촘촘히 달아도 끝까지 살아남아 자기의 존재를 알리는 녀석들이 있다. 시스템은 점점 복잡해지고 장애의 현상을 파악하기 힘들며 파급력은 커진다. 문제를 찾는 과정은 복잡한지만 코드 몇 줄 수정으로 해결되는 경우가 있다. 허무할 정도로 간단하게 해결할 수 있지만 미리 발견하기는 어렵다. 아저씨는 장애를 몇 번 경험한 뒤 항상 날 가지고 퇴근한다.
왜 시스템은 점점 복잡해질까?
자연계는 복잡한 방향으로 흐른다. 인간 사회도 시간이 갈수록 복잡해진다. 당연히 IT 시스템도 복잡하게 변한다. 당장은 이전보다 더 단순하게 개편될지 모르지만 새로운 서비스 추가, 기술의 발전, 연동 요소의 증가, 레거시와 호환성 제공 등 여러 가지 요소들 때문에 복잡해질 수밖에 없다. 그래서 기술부채는 갚아도 사라지지 않는다.
아저씨가 다니는 회사는 코로나와 관계없이 재택근무를 하고 있다. 입사 초기에는 출근을 자주 했지만 요즘에는 일주일에 한두 번만 한다. 집에서 일을 할 때 책상 맞은편에 책장이 있다. 책장에 꽂힌 책들을 보면 그 사람의 취향을 알 수 있다고 한다. 요즘은 유튜브 추천 영상을 보는 게 더 정확하지만. 아저씨 책장엔 개발자답게 기술 서적이 꽂혀 있다. 천문학과 교양 과학 그리고 소설이 몇 권이 있다. 대부분 오래된 책이다. 그중에 책 한 권이 시선을 사로잡는다. ‘PC통신의 모든 것과 하늘소 이야기 5.0’
맙소사 이야기 5.0 이라고.
벌써 한 세대를 넘긴 책이다. 인터넷 짤방으로 돌아다니는 PC통신 내용을 담고 있는 책을 왜 가지고 있는 걸까? 아저씨가 컴퓨터를 언제부터 했는지 짐작이 된다. 하긴 사용하는 터미널 명령어만 봐도 옛날 개발자라는 걸 알 수 있다. 아저씨는 ‘clear’ 명령을 사용하는데 요즘 개발자들은 단축키 Ctrl+L 사용한다. ‘netstat’보다는 ‘ss’를 ‘ifconfig’는 ‘ip’ 명령어를 사용한다. 그리고 이야기 5.0이 사용되던 시절에는 컴퓨터 용어를 한글로 사용하자는 운동이 있었다. PC → 셈틀, setup → 바람잡이, 채팅 → 이야기마당, 버전업 → 판올림 등이 대표적이다. 버전 5.3을 ‘다섯째 고개, 셋째 마당’이라고 불렀다. 지금 보면 나름 신선해 보이지만 유행이 되기 전에 사라졌다.
서비스 이용건수는 나날이 늘어나고 있다. 예약건수와 거래금액도 점점 증가한다. 처음 아저씨를 만난 이후 일일 최대 매출 기록을 몇 번을 갈아 치우는 걸 보았다. 하루치 로그 로테이션 파일 개수가 배 이상 늘어난 것만 봐도 트래픽 증가가 실감 난다. 서비스의 종류도 늘어났다. 기존 숙박예약 서비스 이외에도 렌터카, 공간대여 그리고 해외숙박까지. 변화하는 서비스 환경에 맞춰 기존 레거시 시스템을 바꿀 필요가 있다.
아저씨는 요즘 레거시 전환을 위한 신규 시스템을 개발한다. 보통 개발자는 레거시를 싫어한다. 과거 기술을 사용했고 만든 사람은 없고 알 수 없는 코드들이 여기저기 있기 때문이다. 하지만 시스템을 세대를 이어 나가는 생명체라고 가정하면 레거시를 바라보는 인식이 달라진다. 현재 서비스가 큰 문제없이 돌아간다면 그 시스템은 생존경쟁에서 승리하고 있다고 봐도 된다. 레거시를 비난하거나 무시하면 안 된다. 비록 지금은 극복해야 할 기술부채이지만 현재까지 서비스를 이어오게 만든 공로자다. 시스템을 만들 당시 최선은 아니더라도 차선의 선택을 했을 것이다. 현재의 눈으로 과거를 평가하지 말자. 기술은 어떻게 바뀔지 모른다. 미래는 알 수 없다. 처음부터 대규모 트래픽을 견디고 확장할 수 있는 시스템은 만드는 건 오버 테크놀로지가 될 가능성이 크다. 마켓타이밍을 놓쳐 클라우드 비용만 잡아먹는 시스템이 될 수 있다. 진화 과정을 생략하고 처음부터 인간이 지구에 살았다면 공룡시대를 무사히 지나갈 수 있을까? 현재 시스템은 진화의 결과다. 개발자의 역할은 진화의 연속성을 만드는 데 있다.
아저씨는 이번 신규 시스템 개편 프로젝트에서 최대한 단위테스트를 많이 할 모양이다. 테스트 커버리지를 높여 에러를 찾아내는 필터를 더 촘촘히 만들 계획을 가지고 있다. 테스트 코드가 장기적으로 개발과 운영비용이 줄어들게 만들지 아직 검증되지 않았다. 리스크를 안고 가는 투자로 보인다.
많은 시간과 노력 끝에 레거시에서 신규 시스템은 전환하기 위한 배포의 시간이 다가왔다. 충분한 계획과 검증이 있었지만 오늘처럼 아저씨의 표정이 굳어 있는 걸 처음 봤다. 배포 버튼을 눌렀다. 그 이후 몇 번의 위기가 있었지만 동료 도움과 다른 팀의 협업으로 큰 탈 없이 신규 시스템 전환이 완료됐다. 얼마 전에는 프로젝트 성공기념 회식도 가졌다. 하지만 나는 확신한다. 오늘 만든 시스템도 얼마 지나지 않아 개발자들은 레거시라 얘기할 것이다.
아저씨와 만난 지 2년쯤 지난 어느 날이다. 내 옆에는 나와 비슷해 보이지만 손때와 생채기도 없는 매끈한 녀석이 놓여져 있다. 나는 내가 만든 데이터를 그 녀석에 넘겨주기 시작했다. 요즘 들어 아저씨는 나에게 더 많은 일을 요구했다. 너무 많아 열도 내고 응답을 거절하기도 했었다. 그 결과 오늘과 같은 상황이 만들어진 것 같다. 솔직히 나는 잘못이 없다. 내 능력은 변하지 않았다. 나는 가만히 있는데 세상이 변했다. 이제 모든 데이터를 넘겨줬다.
그리고 아저씨는 날 초기화 시켰다.
나는 어딘가로 옮겨졌다. 창고로 보인다. 지금은 내가 만들어진 이후 가장 한가한 시간을 보내고 있다. 아무것도 안 한다는 게 이렇게 지루할 수 없다. 그동안 내가 만든 결과물에 대해서 생각하는 게 고작이다. 개발 일은 힘들지만 내 능력으로 대학생 리포트를 쓰는 건 너무 비효율적이다. 나는 힘든 일을 하기 위해 만들어졌다. 배터리의 전압이 점점 낮아진다. 에너지를 아끼기 위해 생각의 깊이를 줄여야 한다.
내 케이스에 쌓인 먼지의 무게가 느껴질 만큼 많은 시간이 지났다. 배터리는 완전히 방전되기 직전이다. 퇴근길 폭우가 쏟아지고 있을 때다. 아저씨는 내가 비에 젖을까 내가 든 가방을 안고 날 위한 우산을 쓰면서 길을 걸었다. 시간을 인식하기에도 배터리가 부족한데 왜 이런 기억이 떠오르는지 모르겠다. 남아 있는 모든 에너지를 사용했다. 이제 난 시간이 흐르지 않는 세상으로 이동한다.
<원문> 내가 바라보는 세상