다시 아무도 모르는 시대
10장
스마트폰이 처음 나왔을 때도 비슷한 말을 들었다.
세상이 바뀔 거라고.
처음에는 조금 과장이라고 생각했다.
휴대전화로 인터넷을 한다고 해도 결국 작은 화면일 뿐이라고 생각했다. PC에서 하던 걸 조금 불편하게 옮겨놓은 정도라고 봤다.
그런데 몇 년 지나지 않아 정말 많은 게 달라졌다.
웹 화면을 만들 때도 모바일을 따로 생각해야 했고, 앱 개발자라는 직군이 자연스럽게 생겼다. 회사는 갑자기 모바일 전략을 이야기하기 시작했고, 기존 시스템에도 새로운 API가 필요해졌다.
나는 그때도 새로운 쪽 중심에 있지는 않았다.
누군가는 앱을 만들었고, 누군가는 모바일 서비스 구조를 설계했다.
나는 기존 시스템을 연결했다.
모바일에서 주문이 들어오면 기존 주문 시스템으로 넘기고, 기존 회원 정보를 앱에서 쓸 수 있게 하고, 결제 시스템과 포인트 시스템이 모바일에서도 문제없이 돌아가게 만들었다.
새로운 화면 뒤에는 오래된 시스템이 있었다.
그리고 그 오래된 시스템은 생각보다 쉽게 바뀌지 않았다.
한번은 모바일 주문 프로젝트에서 문제가 생겼다.
테스트에서는 잘 되던 주문이 운영에서만 간헐적으로 실패했다.
앱에서는 결제가 끝났다고 나왔는데 주문이 생성되지 않았다.
처음에는 모두 모바일 쪽을 의심했다.
“앱에서 요청이 두 번 나가는 거 아니에요?”
“네트워크 끊기면 재호출하는 거 아닙니까?”
로그를 봤다.
앱에서는 정상적으로 한 번만 호출하고 있었다.
서버에서도 요청은 들어왔다.
그다음부터 이상했다.
주문 저장 직전 특정 외부 시스템 응답을 기다리고 있었다.
가끔 그 응답이 늦었다.
타임아웃이 발생하면 주문 트랜잭션 전체가 취소됐다.
문제는 결제는 이미 끝난 뒤였다.
회의가 열렸다.
모바일 개발자.
주문 개발자.
결제 담당자.
외부 업체 담당자.
다들 자기 시스템은 정상이라고 했다.
그 말이 틀린 것도 아니었다.
각자 자기 부분만 보면 그랬다.
나는 화이트보드에 흐름을 그렸다.
앱.
API.
결제.
주문.
외부 시스템.
화살표를 하나씩 그었다.
“결제가 여기서 끝나고요.”
손가락으로 다음 칸을 가리켰다.
“주문 저장 전에 이쪽을 기다리네요.”
누군가 말했다.
“원래 저걸 주문 전에 호출했었나요?”
“PC에서는 그랬어요.”
“PC에서는 문제 없었는데요.”
“모바일은 네트워크 조건이 다르잖아요.”
“외부 시스템은 같은데요.”
나는 잠깐 생각했다.
“호출량이 달라졌을 수도 있고요.”
회의실이 조용해졌다.
모바일 서비스가 시작된 뒤 트래픽이 늘었다.
PC에서는 사용자가 화면을 이동하면서 자연스럽게 시간이 걸렸지만, 앱에서는 과정이 더 짧았다. 특정 시간대에 호출이 몰리는 정도도 달라졌다.
예전 구조가 새로운 사용 방식에서 문제를 일으킨 것이었다.
결국 주문 흐름을 바꿨다.
결제가 끝난 뒤에는 주문을 먼저 저장하고, 외부 시스템 처리는 별도로 넘기도록 했다.
말로 하면 간단했다.
실제로 바꾸는 데는 시간이 꽤 걸렸다.
기존 로직을 건드리면 다른 데서 문제가 생겼다.
오래된 배치가 그 상태값을 보고 있었고, 관리자 화면도 같은 값을 사용했고, 정산 프로그램도 연결돼 있었다.
하나를 바꾸면 세 개가 따라왔다.
그런 일을 할 때마다 나는 비슷한 역할을 맡았다.
“이거 바꾸면 어디 영향 가는지 알아봐주세요.”
“예전 로직 왜 이렇게 돼 있는지 확인해주세요.”
“운영 쪽에서 이상한 데이터가 있는데 좀 봐주세요.”
새로운 것을 만드는 사람은 따로 있었고,
나는 새것이 오래된 것과 부딪힐 때 불려갔다.
처음에는 그게 별로 마음에 들지 않았다.
나도 새로운 걸 하고 싶었다.
누군가 발표 자료에 넣을 만한 걸 만들고 싶었다.
새로운 기술을 적용했다.
새로운 구조를 만들었다.
성능을 몇 배 개선했다.
그런 문장에 내 이름이 들어가면 좋겠다고 생각했다.
그런데 내가 하는 일은 대부분 설명하기 어려웠다.
기존 시스템 영향도 분석.
운영 이슈 대응.
레거시 연동.
데이터 보정.
딱히 멋있어 보이지 않았다.
회사를 옮길 때도 비슷했다.
면접관이 물었다.
“최근 프로젝트에서 주로 어떤 역할 하셨습니까?”
나는 설명을 길게 해야 했다.
주문 시스템이 있었고,
외부 업체가 있었고,
모바일이 새로 붙었고,
기존 결제 방식이 있었고,
그 사이에서 문제가 생겼고.
한참 말하고 나면 면접관이 고개를 끄덕였다.
“그러니까 유지보수 쪽을 많이 하셨네요.”
그 말을 들으면 기분이 조금 가라앉았다.
유지보수.
틀린 말은 아니었다.
그런데 내가 한 일을 아주 작게 만드는 말처럼 느껴졌다.
한동안은 이력서에서 그 단어를 피했다.
시스템 개선.
서비스 안정화.
통합 개발.
조금 더 좋아 보이는 말을 골랐다.
하지만 시간이 지나면서 생각이 바뀌었다.
새로운 시스템을 만드는 프로젝트보다,
이미 돌아가고 있는 시스템을 멈추지 않게 하는 일이 더 어려울 때가 많았다.
새로 만들 때는 잘못되면 다시 만들 수 있었다.
운영에서는 그럴 수 없었다.
지금 이 순간 누군가 주문하고 있었고, 돈을 내고 있었고, 포인트를 쓰고 있었다.
잘못 고치면 바로 사고가 됐다.
데이터 하나를 수정할 때도 확인해야 할 게 많았다.
이 값만 바꿔도 되는지.
다른 테이블과 연결돼 있지는 않은지.
오늘 밤 배치에서 다시 원래대로 돌아가지는 않는지.
정산에 영향은 없는지.
누구도 전체를 정확히 알지 못했다.
오래 일한 사람들은 각자 일부를 기억하고 있었다.
“그거 예전에 그렇게 바꾼 이유가 있을 텐데.”
“무슨 이유요?”
“기억이 안 나네.”
그런 대화가 자주 나왔다.
그러면 오래된 메일을 찾고, 티켓을 찾고, 소스를 뒤졌다.
가끔은 아무 기록도 없었다.
그럴 때는 코드를 읽고 이유를 추측했다.
여기서 왜 이 값을 다시 조회하지?
왜 굳이 두 번 저장하지?
이 조건은 왜 들어갔지?
처음에는 이상해 보이는 코드도 운영 장애 하나를 겪고 나면 이유를 알게 되는 경우가 있었다.
“아, 이것 때문에 넣었구나.”
그 순간은 조금 재미있었다.
고고학 같다는 생각도 들었다.
누군가 오래전에 남겨놓은 흔적을 보고 당시 상황을 추측하는 일.
물론 대부분은 그렇게 낭만적이지 않았다.
급했다.
운영에서 전화가 왔다.
“지금 주문 안 됩니다.”
“언제부터요?”
“한 십 분 된 것 같아요.”
그 순간부터는 이유보다 복구가 먼저였다.
로그를 보고.
서버를 보고.
최근 배포를 확인하고.
DB 상태를 보고.
외부 시스템 상태를 확인했다.
여러 팀이 동시에 메시지를 보냈다.
원인 확인됐나요?
예상 복구 시간 있나요?
고객센터 문의 들어오고 있습니다.
나는 대답했다.
확인 중입니다.
그 말은 아주 많이 썼다.
때로는 정말 아무것도 모르는 상태였다.
그래도 뭔가 해야 했다.
하나씩 지웠다.
DB는 정상.
서버 정상.
외부 API 응답 지연.
최근 배포 없음.
그러다 이상한 점 하나가 보였다.
평소보다 특정 요청이 몇 배 많았다.
원인을 따라갔다.
프로모션 페이지에서 버튼 하나가 잘못 연결되어 있었다.
사용자가 한 번 눌렀는데 요청이 여러 번 발생하고 있었다.
서버를 늘려도 해결될 문제가 아니었다.
문제를 막고,
대기 중인 요청을 정리하고,
정상화되는 걸 확인했다.
한 시간쯤 지나 운영팀에서 메시지가 왔다.
정상 확인됩니다.
나는 의자에 기대었다.
주변 사람들이 하나둘 자리에서 일어났다.
누군가 말했다.
“고생하셨습니다.”
그게 끝이었다.
다음 날이면 다시 평소처럼 돌아갔다.
발표도 없었고, 성과 자료에 크게 적힐 일도 아니었다.
서비스가 멈췄다가 다시 돌아왔을 뿐이었다.
그런 일이 몇 번 반복되면서 나는 알게 됐다.
내가 새것을 가장 잘 만드는 사람은 아니라는 걸.
그리고 이상하게도 그것이 예전만큼 부끄럽지는 않았다.
문제가 생겼을 때 어디부터 봐야 할지 알았다.
누구에게 물어봐야 할지 알았다.
코드만 봐서는 답이 안 나올 때 다른 곳을 볼 줄 알았다.
사람들이 “이상한데요”라고 가져오는 문제를 보면 어디가 이상한지 대략 냄새를 맡을 수 있었다.
설명하기 어려운 능력이었다.
자격증에도 없었고,
프레임워크 이름처럼 이력서에 적기도 애매했다.
그런데 현장에서는 쓸모가 있었다.
어쩌면 나는 무언가를 잘 만드는 개발자가 되지 못했는지도 모른다.
대신 망가진 것을 보고 어디가 이상한지 찾는 개발자가 되어 있었다.