한 줄 정의
폐기(deprecation)란 같은(혹은 더 나은) 기능을 제공하는 새 시스템으로 이주를 순차적으로 진행하여 낡은 시스템을 완전히 걷어내는 과정입니다. 코드는 자산이 아니라 부채이므로 기능이 같다면 시스템은 적을수록 좋습니다. 그런데 폐기는 새로 만드는 일보다 어렵습니다 — 하이럼의 법칙·애착·정치 같은 사회적 장애물이 기술적 문제보다 크기 때문입니다. 그래서 희망에 기대지 말고 소유자·일정·도구로 체계적으로 관리해야 합니다.
쉽게 말하면
새 집으로 이사를 갔는데 옛 집 월세를 아직도 내고 있는 상황을 떠올려봅니다. 짐을 절반만 옮겼다면 두 집을 동시에 관리해야 하고, 옛 집과 새 집 사이로 물건을 나르는 수고까지 더해집니다. 진짜로 비용이 끝나는 순간은 옛 집을 텅 비우고 ‘계약을 해지’할 때입니다. 이 마지막 한 걸음이 바로 폐기입니다.
그런데 이게 묘하게 안 끝납니다. “이 책장은 추억이 있어서 도저히 못 버리겠어”(옛 시스템에 대한 애착), “어, 나 아직 옛 집 주소로 카드 명세서를 받고 있었네”(인지하지 못한 의존성), “언젠가 정리하지 뭐”(희망 폐기) 하는 사이 두 집 월세는 계속 빠져나갑니다. 결국 계약을 끝내려면 “○월 ○일에 집을 비운다”고 날짜를 못 박고(강제 폐기), 정 안 되면 이삿짐을 대신 빼주는 전담 인력(폐기 팀)을 불러야 합니다.
이 장 전체는 결국 “새 시스템을 만드는 것이 절반, 낡은 시스템을 끝까지 비워 계약을 해지하는 것이 나머지 절반인데, 후자가 더 어렵다” 는 이야기입니다.
왜 중요한가?
소프트웨어는 디지털 자산이라 비트 자체가 늙지는 않습니다. 하지만 새로운 기술·라이브러리·기법·언어가 등장하며 주변 환경이 끊임없이 변하기 때문에 기존 시스템은 가만히 있어도 서서히 구식이 됩니다. 낡은 시스템을 유지하려면 관리 비용이 계속 들고 난해한 옛 기술에 대한 전문지식까지 필요해집니다.
여기서 끝이 아닙니다. 더 무서운 건 신식과 구식 시스템을 같은 일에 동시에 굴리는 상황입니다. 당장은 문제없어 보이지만, 두 시스템을 함께 유지보수하는 비용은 날이 갈수록 눈덩이처럼 불어납니다. 두 시스템은 정보를 교류하느라 복잡한 변환 코드를 끼고 살게 되고, 둘 다 계속 버전업하며 서로 의존하게 되어 하나를 떼어내기가 점점 더 어려워집니다. 이 상태가 오래가면 신식 시스템의 개선마저 지연됩니다 — 구형과의 호환성을 계속 유지해야 하기 때문입니다.
폐기가 제대로 작동하면 시스템을 운영·업그레이드하는 과정의 중복 투자와 복잡성이 줄어 자원을 아끼고 개발 속도가 빨라집니다. 반대로 제대로 폐기시키지 못하면 시스템을 방치할 때보다 더 큰 비용을 치를 수 있습니다. 점점 커지고 복잡해지는 소프트웨어 생태계를 오래도록 관리하려면, 새 소프트웨어를 구축·운영하는 것만으로는 부족하고 낡았거나 더는 쓰이지 않는 시스템을 반드시 없애줘야 합니다.
핵심 내용
폐기시키는 이유 — 코드는 자산이 아니라 부채
이 논의는 “코드는 자산이 아니라 부채다” 라는 전제에서 출발합니다. 코드가 자산이라면 낡은 시스템의 비중을 줄이고 제거할 이유가 없습니다. 코드에는 비용이 따라옵니다. 비용 일부는 구축 과정에서 발생하지만, 사실 대부분은 구축 이후 생이 끝날 때까지 유지보수하는 데서 발생합니다 — 운영 자원, 그리고 주변 생태계의 진화에 발맞춰 코드베이스를 업데이트하는 노력입니다.
코드가 부채라면 왜 이 책의 대부분을 '잘 짠 코드'에 할애했을까?
코드 ‘자체’는 가치를 창출하지 않습니다. 가치를 만들어내는 건 ‘기능’입니다. 사용자의 요구에 부합하는 기능이 자산이고, 그 기능을 구현하는 코드는 목적지로 가기 위한 수단일 뿐입니다.
똑같은 기능을 하는 두 코드가 있다고 합시다. 하나는 이해하기 쉬운 한 줄짜리이고, 다른 하나는 1만 줄짜리 난해한 스파게티 코드입니다. 우리는 전자를 선호합니다. 코드 자체는 비용을 낳으므로 기능이 같다면 코드는 단순할수록 좋습니다.
따라서 우리가 극대화해야 할 지표는 ‘얼마나 많은 코드를 작성했는가’가 아니라 ‘단위 코드당 얼마나 많은 기능을 제공하는가’입니다. 더 많은 기능을 기대하며 코드의 ‘양’만 늘려서는 안 되고, 오히려 지나친 코드나 더 이상 필요 없는 시스템을 제거해야 합니다. 이때 필요한 것이 바로 폐기 정책과 절차입니다.
주의할 점은 ‘오래됨 = 구식’이 항상 성립하지는 않는다는 것입니다. 몇 해에 걸쳐 정교하게 다듬어져 자기 영역에서 독보적인 소프트웨어가 되는 경우도 있습니다. 조판 소프트웨어 LaTeX는 수십 년 동안 성숙하여 이제는 거의 변경할 게 없어졌습니다. 폐기는 ‘시대에 뒤처졌고, 비슷한 기능의 대체재가 존재하는’ 시스템에 적합한 것이지 단지 나이가 많다고 들이대는 도구가 아닙니다.
그리고 폐기에는 한 가지 현실적 제약이 있습니다. 한 조직이 동시에 진행할 수 있는 폐기 작업의 양에는 한계가 있다는 점입니다.
도로 재포장 비유
우리 모두는 말끔한 도로를 선호합니다. 그렇다고 어느 날 국토교통부가 모든 도로를 봉쇄하고 동시에 새로 포장하기 시작한다면, 공사가 끝날 때까지 누구도 아무 데도 갈 수 없습니다. 대신 적정한 수의 도로에 집중해 순서대로 진행하면 다른 곳의 교통을 방해하지 않으면서 빠르게 끝낼 수 있습니다. 폐기도 마찬가지입니다. 폐기 대상을 신중하게 선택한 다음, 집중해서 빠르게 완료하는 것이 중요합니다.
폐기가 그토록 어려운 이유
근본적인 어려움은 기술이 아니라 사람과 사용 패턴에 있습니다.
하이럼의 법칙 — ‘되니깐 쓰는 것’을 한꺼번에 떼어낸다
사용자 수가 늘수록 시스템은 설계자가 예상하지 못한 방식으로 이용될 가능성이 커집니다. 사용자가 발견한 새로운 사용법은 ‘되니깐 쓰는 것’이지 시스템이 ‘보장하는 동작’이 아닙니다. 문제는 시스템 하나를 제거하는 것이 돌이킬 수 없는 변경이라는 데 있습니다. 동작 방식이 바뀌는 정도가 아니라 완전히 사라지는 것이라, 이런 급진적 변경은 ‘되니깐 쓰던’ 기능과 함께 이를 잘 활용하던 수많은 사용자까지 한꺼번에 떼어내버립니다.
새 시스템은 ‘더 좋지만 분명히 다르다’
폐기는 보통 같은(혹은 더 나은) 기능을 제공하는 새 시스템이 준비된 다음에야 고려됩니다. 그런데 새 시스템은 더 좋은 동시에 분명히 ‘다를’ 것입니다. 만약 낡은 시스템과 완벽히 같다면 (운영팀은 몰라도) 기존 사용자에게는 이주할 의미가 전혀 없을 테니까요. 그래서 두 시스템의 기능이 일대일로 일치하는 일은 드물며, 옛 시스템의 쓰임 하나하나를 새 시스템 기준으로 새로 확인해야 합니다.
애착이라는 의외의 저항
옛 시스템을 향한 애착이 저항으로 나타나기도 합니다. 특히 그 시스템을 직접 만든 사람이라면 “난 이 코드가 좋아!” 같은 형태로 반발합니다. 몇 년을 쏟아 만든 무언가를 걷어내라고 설득하는 일은 말처럼 쉽지 않습니다. 공감할 수 있는 반응이지만 시스템이 낡으면 조직에 비용을 발생시키므로 결국 제거해야 합니다. 구글은 이 거부감을 완화하려고 코드 리포지터리에서 제거된 코드의 과거 이력까지 검색할 수 있게 했습니다 — 언제든 다시 찾을 수 있다는 사실이 상실감을 줄여줍니다.
설계 단계에서부터 폐기를 고려하기
‘언젠가 폐기될 시스템을 설계한다’는 개념은 소프트웨어에서는 생소하지만 다른 엔지니어링 분야에서는 흔합니다. 원자력 발전소를 설계하려면 훗날 수명이 다한 원자로를 어떻게 해체하고 그 자금을 어떻게 조달할지까지 반드시 고려해야 합니다. ‘이 시설은 언젠가 해체해야 한다’는 사실을 인지하느냐가 실제 설계에 큰 영향을 줍니다.
불행히도 소프트웨어는 그렇게 깊게 고민해 설계되는 경우가 드뭅니다. 많은 엔지니어가 유지보수보다 새 시스템 구축·론칭을 원하고, 기업 문화 역시 새 제품을 빠르게 출시하도록 독려하므로 처음부터 폐기를 고려할 동기가 떨어집니다. 사력을 다해 만드는 창조물의 종말을 계획하는 일은 심리적으로도 쉽지 않습니다.
구글이 엔지니어링팀에 권장하는, 설계 단계에서 던져야 할 두 질문은 다음과 같습니다.
매끄러운 폐기를 위한 두 가지 설계 질문
- 내 제품의 고객이 잠재적인 대체품으로 이주하기가 얼마나 쉬울까?
- 내 시스템을 한 부분씩 점진적으로 교체하려면 어떻게 해야 할까?
두 질문 모두 결국 시스템이 의존성을 이용하고 외부로 제공하는 방식과 깊이 관련됩니다. 한 가지 더 알아둘 것은, 프로젝트의 장기 지원 여부는 조직이 그 프로젝트를 처음 승인할 때 사실상 결정된다는 점입니다. 한 번 론칭된 소프트웨어에 할 수 있는 일은 셋 중 하나입니다 — 계속 지원하거나, 조심스럽게 폐기시키거나, 외부 요인으로 운영을 중단하거나. 그러니 기대 수명 동안 제대로 지원하지 못할 것 같은 프로젝트라면 애초에 시작하지 않는 편이 낫습니다.
폐기의 두 유형 — 권고와 강제
폐기는 ‘희망컨대 이 서비스는 언젠가 종료될 것입니다’부터 ‘내일 종료하니 대비하세요’까지 다양합니다. 크게 권고(advisory) 와 강제(compulsory) 로 나뉩니다.
권고 폐기 — ‘희망은 전략이 아니다’
권고 폐기(advisory deprecation) 는 기한이 없고 조직에서도 우선순위가 높지 않은(혹은 자원을 투입할 의지가 없는) 경우입니다. 담당 팀은 고객이 이주하기를 바라지만 서둘러 돕거나 옛 시스템을 바로 걷어낼 계획은 없습니다. 그래서 희망 폐기(aspirational deprecation) 라 불러도 좋습니다. 고객이 알아서 움직여주길 희망할 뿐입니다.
Quote
참고로 SRE팀의 친구들은 ‘희망은 전략이 아니다’라고 말해주더군요.
권고 폐기는 새 시스템 출시를 알리고 얼리어답터에게 권하기에 좋은 수단입니다(단, 베타가 아니라 기능·안정성 모두 정식 서비스 수준일 때만). 하지만 기존 사용자를 이주시키는 데는 효과가 거의 없습니다. 일종의 중력이 작용하는 듯, “제발 새 시스템을 써주세요”라고 아무리 외쳐도 이미 기존 시스템을 쓰는 곳이 많으면 계속 기존 시스템을 이용하려는 경향이 큽니다. 구글의 경험상 권고 폐기는 새 시스템의 혜택이 ‘정말 좋다’ 정도가 아니라 ‘혁신적이다’ 수준일 때만 자가 이주를 끌어냈습니다. 어중간한 혜택으로는, 심지어 대폭적인 개선이 있어도 권고만으로 모두를 움직이게 하기는 힘듭니다.
강제 폐기 — 종료일을 못 박기
강제 폐기(compulsory deprecation) 는 대개 낡은 시스템의 지원 종료일을 못 박는 형태입니다. 종료일 이후까지 이주를 끝내지 못한 시스템은 제대로 작동하지 않습니다. 큰 조직에서 이를 효율적으로 수행하려면 기존 시스템 제거를 전담하는 별도 팀을 꾸리는 게 가장 좋습니다 — 이주 전문지식을 집중시키고, 다른 팀의 이주를 성공적으로 이끌수록 보상하며, 조직 전체에 적용할 도구를 개발하게 합니다.
강제 폐기가 잘 굴러가려면 두 가지가 동시에 필요합니다.
- 집행 권한 — 일정이 고정불변이어야 한다는 뜻은 아니지만, 충분히 경고했다면 기한을 넘겨서까지 옛 시스템을 쓰는 시스템에 문제가 생겨도 책임을 묻지 않을 수 있어야 합니다. 이 권한이 없으면 고객 팀은 폐기를 무시하고 더 시급해 보이는 새 기능 구현에 매진합니다.
- 적극적 지원 — 동시에, 인력 지원 없이 강제 폐기를 밀어붙이면 고객은 이를 ‘지원 없이 떠넘겨진 의무’로 받아들여 반발합니다. 눈에 보이는 혜택도 없이 그저 서비스를 똑같이 유지하기 위해 급한 일을 미뤄야 하는, 이른바 ‘제자리 달리기(running to stay in place)’ 같은 마찰이 생깁니다. 그래서 강제 폐기에는 반드시 전담 팀의 적극적 지원이 따라야 합니다.
정책만으로는 부족하다 — 핵심 인프라의 정치
정책적으로 뒷받침되더라도 강제 폐기는 정치적 반대에 직면할 수 있습니다. 옛 시스템을 쓰는 마지막 고객이 하필 조직 전체가 의존하는 핵심 인프라를 관장하는 팀이라면, 공지한 기한을 지키자고 정말 그 인프라를 정지시킬 수 있을까요? 거기에 의존하는 모든 서비스를 희생하면서까지? 핵심 팀이 거부하면 폐기를 강제하기는 현실적으로 매우 어렵습니다.
인지하지 못한 의존성 찾아내기
단일 리포지터리와 의존성 그래프가 큰 도움이 되지만, 그래프 분석만으로 모든 의존성을 빠짐없이 찾기는 쉽지 않습니다. 자신이 구식 시스템에 의존한다는 사실조차 모르는 팀이 있을 수 있기 때문입니다. 그래서 구글은 D-데이 몇 달~몇 주 전에 서비스를 점진적으로 일시 중단하는 일정을 계획해 공표합니다. DiRT(재해 복구 테스트) 연습과 비슷하게, 이 실험을 통해 인지하지 못하던 의존성이 새로 드러나는 경우가 많습니다. 이따금 구현 전용 심볼의 이름을 일부러 바꿔, 자신도 모르게 그 심볼에 의존하던 사용자를 찾아내기도 합니다.
폐기 경고 — 실행 가능성과 적시성
권고든 강제든, 시스템이 폐기 대상임을 프로그래밍적으로 알려주면 좋습니다. 다만 단순히 표시만 해두고 사람들이 알아서 이주하길 바라는 건 다시 ‘희망은 전략이 아니다’에 부딪힙니다. 폐기 경고는 새 사용자 유입은 잘 막아주지만 기존 사용자 이주에는 효과가 거의 없습니다.
게다가 경고는 날이 갈수록 불어납니다. A → B → C 의존 관계에서 C의 경고가 A까지 전이되기 시작하면, 사용자는 범람하는 경고에 파묻혀 아예 무시해버립니다. 의료 분야에서 말하는 경보 피로(alert fatigue) 입니다.
flowchart LR C["C (폐기 대상)"] -->|경고 발생| B["B"] B -->|경고 전이| A["A (최종 이용자)"] A -.->|"범람하는 경고에 파묻혀<br/>전부 무시 = 경보 피로"| A
그래서 폐기 경고에는 반드시 두 가지 특성이 담겨야 합니다.
| 특성 | 의미 | 잘못된 예 → 올바른 예 |
|---|---|---|
| 실행 가능성(actionability) | 평균적 엔지니어가 이론뿐 아니라 실질적인 조치를 바로 취할 수 있어야 함 | ”이 API는 폐기됩니다”(끝) → 대체 API와 데이터 이주 단계까지 알려주는 도구·이메일 |
| 적시성(relevance) | 사용자가 실제로 관련 동작을 수행하는 바로 그때 떠야 함 | 커밋 수 주 후 / 제거 직전 주말 → 함수를 쓰는 코드를 작성하는 순간 / 이주 몇 달 전 안내 |
기회가 될 때마다 경고를 쏟아내고 싶은 충동은 자제해야 합니다. 안일한 경고는 우호적인 엔지니어까지 질리게 만듭니다. 구글은 ErrorProne이나 clang-tidy 같은 도구로 경고가 표시되는 상황 자체를 제어합니다 — 예를 들어 새로 추가·변경되는 코드가 폐기 대상 API를 쓸 때만 경고하여 의존성이 새로 늘어나는 것을 막습니다. 더 거슬리는 경고(의존성 그래프에 폐기 대상 표시 등)는 강제 폐기 시에만 추가합니다.
폐기 프로세스 관리
폐기는 구축이 아니라 해체가 목적이라 결이 전혀 다를 것 같지만, ‘관리하고 실행해야 한다’는 점에서는 다른 엔지니어링 프로젝트와 똑같습니다. 차이가 두드러지는 세 지점만 짚어봅니다.
프로세스 소유자
시스템이 아무리 경고를 쏟아내도 소유자가 명확하지 않으면 폐기는 진척되지 않습니다. 소유자를 명시적으로 두는 게 자원 낭비처럼 보일 수 있지만 훨씬 효율적입니다.
소유자 없는 폐기 = 모든 낡은 시스템을 영원히 유지하겠다는 선언
소유자 없이는 아무것도 폐기시키지 마세요. 그리고 폐기 업무를 시스템 이용자에게 절대 떠넘기지 마세요. 이용자에게 떠넘기면 결국 권고 폐기와 같아져 결코 말끔하게 끝나지 않습니다.
특히 위험한 건 버려진 프로젝트입니다. 여전히 활발히 쓰이지만 소유자나 유지보수 주체가 불명확한 프로젝트 — 원래 소유자는 후속 프로젝트로 옮겨갔고, 예전 프로젝트는 자신에게 의존하는 주요 프로젝트들이 모두 사라지기를 소망하며 어두운 지하 동굴에 방치된 신세입니다. 이런 프로젝트는 저절로 사라지지 않으므로, 폐기 전문가를 배정해 주된 목표로(사이드 프로젝트가 아니라) 제거해야 합니다. 다른 일과 경쟁하게 만들면 폐기는 십중팔구 우선순위에서 밀립니다. 폐기처럼 ‘중요하지만 긴급하지 않은’ 청소 업무는 구글의 20% 시간에 많이 이루어집니다.
마일스톤
새 시스템 구축에서는 마일스톤이 명확합니다 — 기능을 하나씩 론칭할 때마다 사용자가 혜택을 얻습니다. 반면 폐기 프로젝트에서는 ‘낡은 시스템 완전 제거’만이 유일한 마일스톤이라 생각하는 함정에 빠지기 쉽습니다. 물론 그 순간이 폐기팀에게 가장 의미 있겠지만, 일을 제대로 했다면 그건 팀 외부에서 가장 인지하기 어려운 마일스톤이기도 합니다(이미 그 시스템을 쓰는 사람이 아무도 없을 테니까요). 게다가 이 단계에 끝내 도달하지 못하는 폐기 프로젝트도 많습니다.
그래서 폐기팀에도 측정 가능하고 점진적인 마일스톤이 필요합니다. 새 제품을 만들 때 주요 컴포넌트를 하나씩 완성하는 걸 마일스톤으로 삼듯, 폐기에서도 핵심 컴포넌트를 하나씩 제거하는 것을 점진적 마일스톤으로 삼아야 합니다. 진척 지표는 다르지만, 점진적 성취를 제때 축하해야 팀 사기가 오른다는 사실은 똑같습니다.
폐기 도구 — 발견·이주·퇴행 방지
폐기 관리에 쓰이는 도구는 발견·이주·퇴행 방지 세 부류로 나뉩니다.
| 부류 | 하는 일 | 구글의 도구 |
|---|---|---|
| 발견(discovery) | 낡은 시스템을 ‘누가(by whom)’, ‘어떻게(how)’ 쓰는지 파악. 폐기 초기엔 이용처를 찾고 예상 못 한 사용이 없는지 확인하는 게 대부분 | Code Search·Kythe(정적 분석)로 코드 실행 없이 이용처 파악, 프로덕션 로그·런타임 샘플로 동적 의존성 발견, 전역 테스트 스위트로 심볼 참조가 모두 제거됐는지 확인 |
| 이주(migration) | 코드베이스를 새 라이브러리·런타임 서비스로 갱신 | 대규모 변경(LSC) 프로세스와 코드 생성·리뷰 도구 |
| 퇴행 방지(anti-regression) | 새로 작성하는 코드가 폐기 대상을 다시 쓰는 ‘퇴행’을 차단 | @deprecated 애너테이션 + Tricorder가 자동 경고·자동 고침 제안, 빌드 시스템의 가시성(visibility) 허용목록 |
특히 퇴행 방지는 폐기 인프라가 챙겨야 할 중요한 역할인데도 자주 간과됩니다. 한쪽에서는 폐기팀이 열심히 이주시키고 다른 한쪽에서는 익숙하다는 이유로 기존 시스템을 쓰는 코드가 계속 추가되는 두더지 잡기 게임이 벌어지면, 전혀 생산적이지 않고 사기마저 떨어집니다. 폐기 시스템 소유자가 @deprecated(자바의 @Deprecated 같은) 심볼을 달아두면 Tricorder가 호출하는 코드 작성자에게 대체 방법을 자동으로 피드백하고, 신규 시스템 코드로 바꿔주는 자동 고침 버튼을 띄우기도 합니다. 거시적으로는 빌드 시스템의 가시성 허용목록으로 폐기된 시스템에 새로 의존하는 일 자체를 막습니다.
비교 / 트레이드오프
권고 폐기 vs 강제 폐기
| 관점 | 권고 폐기 | 강제 폐기 |
|---|---|---|
| 종료일 | 없음 | 명시적으로 못 박음 |
| 강제성 | 없음 (고객 자율) | 있음 (기한 후 미작동) |
| 담당 팀의 역할 | 알림·자가 이주 도구 제공 후 대기 | 전담 팀이 이주를 적극 주도·지원 |
| 새 사용자 유입 차단 | 효과 좋음 | 효과 좋음 |
| 기존 사용자 이주 | 거의 무효 (혁신적 혜택이 있을 때만 예외) | 실제로 발생. 단 정치적 반대·반발 위험 |
| 별명 | 희망 폐기(aspirational) | — |
완전 교체 vs 점진적 개선
폐기 비용까지 따지면 새 시스템으로 완전히 갈아엎는 것보다 기존 시스템을 점진적으로 개선하는 편이 일반적으로 더 저렴할 때가 많습니다. 완전한 신규 이주 비용은 정말 크고 예상보다 훨씬 많이 들곤 합니다. 현장에서 조금씩 리팩터링하여 폐기를 점진적으로 진행하면 기존 시스템을 계속 운영하면서도 이용자에게 더 쉽게 혜택을 줄 수 있습니다. 점진적 개선이 폐기를 완전히 막을 수는 없지만, 관리하기 쉬운 작은 단위로 나눠 한 번에 조금씩 혜택을 줄 수 있습니다.
폐기 비용은 왜 정확히 평가하기 어려운가
폐기 여부를 결정하려면 비용을 따져야 하지만, 그 비용은 곳곳에 흩어져 있어 측정이 어렵습니다. 기존 시스템의 직접적인 유지보수 비용 외에도, 비슷한 시스템을 여러 개 운용하는 데 드는 생태계 비용까지 고려해야 하기 때문입니다 — 구식·신식 중 무엇을 쓸지 고민해야 하고, 공존 기간에는 두 시스템을 연동해야 하며, 그 탓에 새 시스템에 신기능을 추가하려 할 때 낡은 시스템이 연동 문제로 간접적인 방해가 됩니다. 폐기·제거 비용 역시 마찬가지로 흩어져 있는 경우가 많습니다.
내 생각
-
권고 폐기 =
@Deprecated/Sunset헤더/OpenAPIdeprecated: true, 강제 폐기 = API 버전 EOL 날짜 박기. 백엔드 API 버저닝이 이 장의 권고/강제 구분과 정확히 겹칩니다. 헤더만 달아두고 “언젠가 옮기겠지” 기대하는 건 ‘희망은 전략이 아니다’에 그대로 걸립니다 — 클라이언트는 동작하는 한 절대 안 옮깁니다. -
DB 스키마 폐기는 expand-contract로 점진적 마일스톤을 만들 수 있습니다. 컬럼/테이블을 한 번에 드롭하지 않고 ‘새 컬럼 추가 → 양쪽 쓰기 → 읽기 전환 → 옛 컬럼 제거’로 쪼개면, ‘완전 제거’라는 유일 마일스톤 함정을 피하고 단계마다 롤백 여지를 남길 수 있습니다.
-
‘발견’ 도구의 실무 버전은 액세스 로그·APM입니다. deprecated 엔드포인트를 누가 호출하는지 코드 그래프만으로는 안 잡힙니다. 게이트웨이 로그·APM으로 호출 트래픽을 모니터링해 ‘호출 0이 N주 지속’을 제거 신호로 삼는 게 동적 의존성 발견의 현실적 방법입니다.
-
퇴행 방지는 CI에 박아야 합니다. Tricorder의 역할은 ArchUnit·커스텀 lint 룰·CI 게이트로 대체 가능합니다. deprecated 호출을 새로 추가하면 빌드를 깨거나 PR에 경고를 남기지 않으면, 폐기는 끝없는 두더지 잡기가 됩니다.
관련 개념
- Ch14 더 큰 테스트 — DiRT(재해 복구 테스트)와 전역 테스트 스위트. 인지하지 못한 의존성을 드러내고, 폐기 후에도 시스템이 멀쩡한지 보장하는 장치
- Ch09 코드 리뷰 — 이주를 처리하는 대규모 변경 프로세스와 코드 리뷰 도구가 폐기 실행의 핵심 수단