원문 제목: Building resilient systems with Sam Newman URL: https://www.youtube.com/watch?v=a0sZV0qIbI0 날짜: 2026-10-09 채널: pragmaticengineer
📌 핵심 질문 / 핵심 논점
==분산 시스템의 복원력은 장애를 없애는 능력이 아니라, 지연·부재·포화라는 현실을 받아들이고 사람·기술·비즈니스가 함께 회복하고 적응하는 능력이다.== 마이크로서비스나 AI를 유행하는 정답으로 도입할 것이 아니라, 어떤 자율성·사용자 가치·운영 목표를 얻으려는지 먼저 정하고 그 목표를 검증해야 한다.
- 분산 시스템에는 정보가 즉시 전달되지 않고, 통신 대상이 존재하지 않을 수 있으며, 리소스 풀이 무한하지 않다는 세 가지 기본 제약이 있다.
- 독립 배포와 비즈니스 도메인 경계를 만족하지 않는 마이크로서비스는 조직 자율성을 만드는 수단이 아니라 분산 복잡성을 늘리는 부채가 된다.
- 복원력은 견고성(robustness), 회복(recovery), 우아한 확장성(graceful extensibility), 지속적 적응성(continuous adaptability)의 네 차원으로 평가해야 한다.
- AI를 사용할 때는 좋은 결과와 검증 방법을 먼저 정의하고, 비결정적 에이전트가 맡을 일을 모듈 경계 안으로 제한하며, 가능한 부분은 결정적 코드와 다중 공급자 전략으로 바꿔야 한다.
샘 뉴먼은 프로덕션을 현재 시스템의 진실이라고 말한다. 코드와 사양은 시스템이 무엇을 해야 하는지 설명하는 중요한 모델이지만, 실제 사용자 경험·SLO·장애·운영 데이터가 그 모델을 검증하거나 반박한다. 복원력 있는 조직은 장애를 숨기지 않고 공유하며, 심리적 안전을 바탕으로 다른 조직의 사고에서도 계속 배운다.
1. 문제의식: 마이크로서비스와 AI를 둘러싼 과장
1.1. 마이크로서비스는 최후의 수단이다
-
마이크로서비스의 분산 비용
- 마이크로서비스를 도입하면 상태 관리와 통신까지 적극적으로 분산하게 되므로, 모놀리스보다 자동으로 좋아지지 않는다.
- 마이크로서비스는 조직의 팀을 독립적으로 운영하고 배포 자율성을 높이려는 목적을 달성하는 여러 메커니즘 중 하나일 뿐이다.
- 조직에 자율성이 필요한지, 팀 경계를 명확히 할 수 있는지, 운영 복잡성을 감당할 수 있는지 먼저 판단해야 한다.
-
AI를 둘러싼 순진함
- 기술 업계는 LLM이 무엇을 할 수 있고 무엇을 할 수 없는지 근본적으로 오해하고 있다.
- LLM은 그럴듯한 텍스트와 코드를 생성하지만 인과관계, 세계의 물리적 속성, 결과의 안전성을 스스로 이해하는 세계 모델(world model)이 아니다.
- 분산 시스템의 복원력 원칙은 AI가 코드를 작성하는 시대에도 사라지지 않는다. 오히려 더 많은 코드와 더 많은 운영 결과를 검증해야 한다.
1.2. 방송 초반에 제시된 핵심 사례와 후원 메시지
-
에이전트 시대의 Git 호스팅 문제
- AI 에이전트가 병렬로 더 많은 코드를 작성하고 푸시하면서 Git 호스팅이 병목이 될 수 있다.
- Thomas Dohmke가 설립한 Entier는 에이전트 시대를 겨냥해 저장소를 지역적으로 가깝게 배치하고 병렬 푸시를 지원한다고 소개됐다.
- 저장소가 초당 418회의 푸시를 처리하며 경쟁사보다 최대 89배 빠르다고 홍보했고, GitHub 장애 때도 저장소 미러링으로 계속 작업할 수 있다고 설명했다.
- 에이전트의 프롬프트와 대화 기록을 저장소에 보존해 PR만으로는 알기 어려운 코드 생성 맥락까지 확인할 수 있다는 점이 강조됐다.
-
객체 스토리지 기반 검색 계층과 스토리지 재설계
- TurboPuffer는 검색 속도·비용·대규모 환경의 안정성을 개선하기 위해 성공한 기존 스토리지 아키텍처를 V3로 다시 설계하는 사례로 소개됐다.
- V3는 콜드 전체 텍스트 검색이 기존 프로덕션보다 11배, 핫 전체 텍스트 검색이 126배 느린 중간 결과를 공개했지만, 핫·콜드 벡터 검색에서는 동등하거나 더 나은 결과도 보였다.
- 단위 테스트를 통과하는 쿼리 실행 계획을 만드는 것과 프로덕션에서 정확성·안정성·성능을 함께 유지하는 것은 전혀 다른 문제다.
-
결정론적 버그 탐색의 필요
- Antithesis는 시스템 전체를 적대적 시뮬레이션에서 실행하고 타깃 테스트와 퍼즈 테스트를 수행해 사용자가 버그를 발견하기 전에 문제를 찾는다고 소개됐다.
- 결정론적 시뮬레이션은 실패를 재현할 수 있게 하므로, 비결정적 환경에서 우연히 발생한 버그를 고치는 것보다 원인 분석이 쉽다.
- Jane Street, Fly.io, etcd 커뮤니티가 사례로 언급됐다. 에이전트가 만든 코드가 늘어날수록 코드 리뷰만으로 신뢰성을 확보하기 어렵다는 문제의식과 연결된다.
2. 샘 뉴먼의 출발점과 프로그래밍에 대한 관점
2.1. 영국의 가정용 컴퓨터에서 산업 현장으로
-
어릴 때 형성된 컴퓨터 관심
- 영국에서 BBC B 계열의 Acorn Electron을 접했고, 이후 내장 테이프 드라이브가 있는 ZX Spectrum 128K를 사용했다.
- 영국에서는 Spectrum과 BBC 컴퓨터가 강했고, 미국에서는 Commodore와 Atari가 더 큰 시장이었다.
- De Montfort University에서 소프트웨어 공학을 공부했다. 레스터에 대학이 두 곳뿐이라는 점을 이용해 가족끼리 학교가 지역 상위 5위 안에 든다고 농담했다.
-
샌드위치 코스와 GEC Alsthom
- 2년간 공부하고 1년간 유급 산업 현장에 나간 뒤 마지막 학년에 졸업하는 샌드위치 코스를 거쳤다.
- GEC Alsthom(현재 Alstom)에서 유럽우주국(ESA)용 소프트웨어와 가스·증기 터빈 관련 일을 하며 방황하던 시기를 정리하고 집중력을 얻었다.
- 닷컴 버블 시기에 동료들이 떠나면서 거의 아무 일도 하지 않던 신입에서 여러 일을 떠맡는 사람으로 바뀌었다.
2.2. Fortran 77과 자동화가 준 첫 번째 강렬한 경험
-
8,000개 파일의 반복문 제한
- 첫 주에 자신이 태어난 해에 출시된 Fortran 77 코드베이스를 받았다.
- Unix에서 분석 모델을 실행했고 컴퓨터 사용 시간이 귀했기 때문에, 의도하지 않은 무한 루프를 막으려고 약 8,000개 파일의 모든 네 번째 반복문에 중단 조건을 넣었다.
- 반복 횟수는 약 99,999회였고, 모델과 컴퓨터가 커지면서 그 상수를 전부 고쳐야 했다.
-
sed와 awk를 통한 리팩터링
- 상사는 손으로 고치면 2주 걸릴 것이라며 O'Reilly의 『sed & awk』를 건넸다.
- 천공 카드에서 유래한 Fortran 77의 고정 줄 길이 제약을 고려해 이틀 동안 정규표현식을 익히고 자동 리팩터링 코드를 작성했다.
- 손으로 할 일을 도구로 해냈을 때 “신이 된 듯한” 강렬한 도파민을 느꼈고, 이것이 프로그래밍의 초기 매력으로 남았다.
-
벽을 쌓는 사람과 벽 쌓는 기계의 비유
- 한 건축가는 벽돌을 하나씩 쌓고, 다른 건축가는 처음 이틀 동안 설계한 뒤 셋째 날 벽을 쌓는 기계를 만든다는 이야기가 소개됐다.
- 기계로 쌓은 벽이 무너지며 “아아” 하는 장면까지 포함된 농담이지만, 학습과 자동화가 주는 강렬한 성취감을 설명하는 실제 경험에 가깝다.
- 졸업생에게 경험을 들려주던 자리에서 상수값을 모두 바꾸는 대신 하나의 설정값으로 만들자는 조언을 듣고, 자신도 여전히 배우고 있음을 깨달았다.
2.3. ThoughtWorks, XP, TDD, 지속적 배포
-
작은 조직에서 열린 기술 문화로
- ThoughtWorks에 합류했을 때 직원은 400명도 되지 않았고, 떠날 때쯤 약 4,000명 규모가 됐다.
- 회사의 핵심은 Kent Beck의 Extreme Programming(XP)이었고, 런던의 테스트 주도 개발(TDD) 커뮤니티와 활발한 밋업 문화가 영향을 줬다.
- Steve Freeman과 Nat Pryce의 『Growing Object-Oriented Software, Guided by Tests』를 추천하면서 제목은 정말 나쁘다고 농담했다.
-
도구가 없을 때 직접 만든 실천
- 2004년 무렵 CI와 TDD를 말했지만 지금처럼 쓸 만한 도구가 없어서 빌드 파이프라인을 직접 만들었다.
- 첫 테크 리더 Dave Farley와 일했고, Jez Humble을 면접한 사람 중 하나였다. 아이디어를 모두가 토론하고 발전시키는 시기를 가까이서 경험했다.
- 2007년 ThoughtWorks 소속으로 약 1년 반 Google에서 자동화 테스트와 테스트 가능한 코드를 가르쳤고 Selenium으로 엔터프라이즈 웹 테스트 자동화를 적용했다.
- 모킹 프레임워크, Inversion of Control, CruiseControl 대체 도구 두 개, Nick Ashley와 Graham Tackley와 만든 초기 데이터베이스 리팩터링 도구 DBDeploy 등이 필요에 따라 만들어졌다.
-
컨설팅 환경에서도 가능한 혁신
- ThoughtWorks는 제품을 직접 운영하는 Google·Meta와 달리 고객의 문제를 해결하는 컨설팅 회사였지만, 혁신이 제품 회사에만 존재한다는 통념을 깨뜨렸다.
- 고객의 개발 방식을 바꾸는 것이 목표가 아니라면 주어진 환경에서 일해야 했지만, 테스트·페어 프로그래밍·TDD의 가치를 계속 설득했다.
- 관리자가 엔지니어 8명을 4명으로 줄이는 것처럼 받아들일 수 있어도, 페어 프로그래밍은 단순히 타이핑 인원을 늘리는 활동이 아니다.
- Martin Fowler의 “프로그래밍은 타이핑이 아니다”라는 말은 페어링 논쟁을 “프로그래밍을 무엇이라고 생각하는가?”라는 더 근본적인 대화로 바꿨다.
2.4. 코드는 프로그램 전체가 아니다
-
프로그래밍의 집단적 성격
- 역사적으로 프로그래밍 시간의 약 50%가 코드 작성에 쓰였기 때문에 프로그래밍을 코드를 타이핑하는 일로 오해하기 쉽다.
- Peter Naur는 프로그램을 개발자들의 머릿속에 존재하는 이론으로 설명했다. 코드는 사람들이 함께 만든 시스템을 실행시키는 한 메커니즘일 뿐이다.
- Kent Beck의 표현처럼 소프트웨어 설계는 인간관계의 연습이다. 제품 소유자·도메인 전문가·개발자·운영자가 함께 시스템을 만든다.
-
가속하면 다른 병목이 드러난다
- 코딩 속도만 올리면 요구사항·피드백·검증·배포·운영의 다른 지점이 제약이 된다.
- 샘 뉴먼은 세 번의 스타트업을 시작했지만 모두 서로 다른 이유로 실패했다고 농담하며, 성공적인 스타트업을 만드는 조언자는 아니라고 말했다.
- ThoughtWorks를 떠나 독립한 뒤에도 여러 일을 병행하며, 더 빠른 코드 생산보다 전체 시스템과 협업의 흐름을 보게 됐다.
3. 마이크로서비스의 역사와 엄격한 정의
3.1. SOA에서 마이크로서비스라는 이름으로
-
용어가 생기기 전의 맥락
- 2011~2012년 James Lewis는 당시 SOA를 구축하던 회사들과 이야기했고, 기존 SOA를 단순화해 REST로 가져가려는 게릴라 SOA 흐름이 있었다.
- 초기 SOA는 WSDL·SOAP를 사용했다. “Simple Object Access Protocol”의 Simple이 오히려 세상에서 가장 복잡한 것을 가리키는 것 같다는 농담이 나왔다.
- Jim Webber와 Ian Robinson 등은 스마트 엔드포인트와 단순한 파이프라인을 선호하는 중앙 집중식 관리 모델을 논의했다.
-
지속적 배포가 만든 아키텍처 요구
- 샘 뉴먼은 Jez Humble과 Dave Farley가 2006년부터 시작한 지속적 배포 작업과 연결해, 코드를 최대한 빠르고 효율적으로 프로덕션에 보내는 문제를 다뤘다.
- 자주 바뀌어야 하는 부분이 거대한 석조물처럼 다른 부분과 통합되어 있으면 빠른 배포가 불가능했다.
- 2012년 “빠른 릴리스를 위한 디자인” 강연에서 James가 정리한 패턴을 보고 자신의 지속적 배포 관점과 맞닿아 있음을 깨달았다.
- 책은 DevOps와 지속적 배포가 가능하게 한 아키텍처 스타일로서 마이크로서비스를 설명한다. Erlang에는 비슷한 아이디어가 이미 있었고, 정보 은닉·결합도·응집도 같은 1970년대 개념을 현실적인 형태로 다시 가져온 셈이다.
-
마이크로서비스 열풍과 의미 확산
- Uber가 InfoQ 같은 행사에서 수천 개의 서비스를 만든 사례를 공개하면서 스타트업 전체가 마이크로서비스를 말하기 시작했다.
- Netflix와 Uber를 비롯한 회사들은 처음에는 세분화된 SOA라는 말을 썼지만, 적절한 이름이 생긴 뒤 기존 SOA를 마이크로서비스라고 부르는 의미 확산이 일어났다.
- 첫 책을 쓸 때 Netflix의 성능·안정성 담당자 Ben Christensen과 호주의 REA(realestate.com.au) 관계자에게서 실제 사례를 얻었다.
3.2. 샘 뉴먼의 두 가지 강한 기준
-
독립 배포 가능성
- 마이크로서비스의 최소 조건은 한 번에 하나의 서비스만 배포할 수 있어야 한다는 것이다.
- 배포 단위와 변경 단위가 단일 서비스 경계여야 하며, 모든 서비스를 한꺼번에 배포해야 한다면 독립 배포가 아니다.
- 서비스가 여러 개라는 사실보다 변경을 독립적으로 흘려보낼 수 있는지가 중요하다.
-
비즈니스 도메인 중심의 경계
- 서비스 경계는 가능하면 비즈니스 도메인에 맞춰야 하며, DDD를 활용할 수 있지만 반드시 DDD 용어를 써야 하는 것은 아니다.
- 기존 SOA나 고전적 N계층 구조는 기술 계층을 기준으로 분해하는 경향이 강했다.
- 기술적 분해보다 비즈니스 기능이 어디에서 끝나고 시작하는지에 맞춘 경계가 자율성과 변화 속도에 더 유리하다.
-
Uber가 보여준 실제 진화
- 2016년 이후 Uber에는 독립 배포 가능한 서비스가 있었지만, 처음부터 비즈니스 도메인을 정교하게 모델링한 것은 아니었다.
- 경험이 적은 개발자도 인터페이스와 코드를 갖춘 서비스를 만들고 배포하게 허용했으며, 몇 년간 사용량을 관찰한 뒤 핵심 서비스와 고티어 서비스에 레이블을 붙였다.
- Uber는 원래 수천 개의 서비스를 원했다기보다, 너무 느린 거대 모놀리스가 신규 기능 출시를 막았기 때문에 새로운 기능을 별도 서비스로 만들도록 강제했다.
- 그 결과 목표보다 많은 고립된 서비스가 생겼고, 이후에는 비즈니스 도메인을 기준으로 다시 통합할 필요가 생겼다. 외부에는 “엔지니어 한 명당 한두 개의 서비스”라는 성공담만 알려졌다.
3.3. 언제 마이크로서비스를 택할 것인가
-
조직 자율성이 목적일 때
- 많은 개발자와 중간 관리자가 있지만 일이 느리고 팀이 무엇을 해야 할지 모르는 조직이라면 자율성이 해결책이 될 수 있다.
- 마이크로서비스는 그 목표에 적합할 수 있지만 자율성 자체를 보장하지 않는다.
- 상태·데이터·통신·배포를 분산하는 비용까지 포함해 자율성의 가치가 더 큰지 판단해야 한다.
-
닷컴 기업과 엔터프라이즈의 차이
- Uber의 승차 서비스와 Uber Eats처럼 디지털 기업의 초기 제품은 사업과 수익 모델의 경계가 비교적 선명하다.
- 빠른 출시를 위해 Uber Eats 주문에 두 번의 배송을 연결하는 식의 편법을 쓰더라도 비즈니스 경계는 대체로 이해하기 쉽다.
- 반대로 은행·신발 회사·Adidas 같은 오래된 기업은 10~50년간 존재한 종이 기반 프로세스를 소프트웨어로 옮기며 복잡성이 누적됐다.
- Eric Evans의 DDD는 비디지털 비즈니스 프로세스를 소프트웨어 모델로 만드는 방법을 제시했고, 정확한 출간 연도는 대화 중 2000년과 2004년이 혼재해 언급됐다.
4. 진실의 원천, 사양, 암묵지식
4.1. 사양과 코드, 그리고 프로덕션
-
AI 이전 기업과 AI 네이티브 기업
- 기존 디지털 기업은 제품 요구사항 문서, 개발자, PM, 디자이너, QA가 분업하는 오래된 기계를 갖고 있다.
- AI 네이티브 스타트업은 적은 인원으로 시작해 처음부터 에이전트를 모든 단계에 사용하며 전혀 다른 업무 프로세스를 만든다.
- 새 도구가 성숙하면 기존 대기업은 기존 방식을 보존한 채 새 도구를 끼워 넣으려 할 가능성이 높고, 문화적 관성 때문에 초기 도입이 어렵다.
- 기계어에서 어셈블리, 범용 언어로 올라온 것처럼 소프트웨어 개발도 더 높은 추상화로 이동하고 있지만, 업계가 그 단계에 도달할 준비가 됐다는 뜻은 아니다.
-
코드와 사양의 역할
- 잘 구조화되고 주석이 달린 비즈니스 로직 코드는 시스템이 실제로 하는 일을 확인하는 중요한 근거다.
- Charity Majors의 표현을 빌리면 “진실은 프로덕션이다. 그 밖의 모든 것은 우리가 스스로에게 하는 거짓말이다.”
- Kiro와 Spec Kit 같은 도구는 사양을 정의하고 LLM이 실행한 뒤 반복하는 스펙 우선 개발을 지원한다.
- 어떤 조직은 사양을 코드 작성용 임시 발판으로 버리고, 어떤 조직은 기능 변경 때 사양만 고친다. 아직 사양만을 시스템의 진실로 인정하려면 컴파일러·런타임·실행 결과에 대한 신뢰 문제가 남아 있다.
- 실제 운영 환경은 명시적인 사양과 무관하게 현재 시스템의 동작을 최종적으로 판정한다. 코드·사양·사람의 머릿속 중 진실이 어디에 있는지 스스로 물어야 한다.
4.2. 암묵적 지식과 협업의 보존
-
버스 팩터와 페어링
- 스타트업에서는 비즈니스 규칙과 운영 지식이 몇 사람의 머릿속에만 있어도 초기에는 버틸 수 있지만, 조직이 커지거나 사람이 떠나면 위험해진다.
- 무작위 페어링(promiscuous pairing)은 매일 역할과 상대를 바꿔 모든 사람이 같은 컨텍스트를 공유하게 한다.
- AI 코드 리뷰가 있다고 해서 사람이 공유하던 정신 모델과 암묵적 지식이 자동으로 보존되는 것은 아니다.
-
인지 부채의 시작
- 스페인 ThoughtWorks의 Chris Ford는 AI 소프트웨어 개발의 가장 큰 문제로 암묵적 지식을 꼽았다.
- 코드 리뷰에서 “뭔가 잘못된 것 같은데 정확히 설명할 수 없다”는 감각은 비즈니스 운영과 개발 방식에 대한 인간의 경험이 반영된 것이다.
- 명세 단계로 올라가려면 인간이 가진 암묵적 판단을 밖으로 꺼내 공통 명세와 공유된 정신 모델에 넣어야 한다.
- AI 비서와 따로 페어링하면 각자가 서로 다른 방향으로 나아가고, 프로그램이 공유 정신 모델을 무너뜨릴 수 있다. 이 틈이 인지 부채(cognitive debt)다.
-
코드 리뷰를 없앨 때의 조건
- Chain Guard는 사람이 직접 하는 코드 리뷰를 없애고 방어적 작업, 설계, 문서화에 시간을 쓰겠다고 발표한 사례로 언급됐다.
- 시스템이 정상적으로 작동하는지, 변화 방향을 비판적으로 검토하는지, 운영 책임자가 결과를 이해하는지 확인한다면 코드를 매 줄 읽지 않는 선택도 가능하다.
- 반대로 코드도 보지 않고 설계·문서·운영·검증에도 관심을 두지 않는다면 실패는 자업자득이다.
- QA와 SRE가 자신이 쓰지도 읽지도 이해하지 못한 코드를 프로덕션에서 책임져야 하는 상황을 방치해서는 안 된다.
4.3. “좋은 결과”를 정의하고 입증하기
-
스펙 기반 개발의 전제
- 에이전트에게 작업을 맡기기 전에 좋은 결과가 무엇인지 정의해야 한다.
- 시스템이 그 결과를 실제로 구현한다는 증거를 확보해야 한다.
- O'Reilly 온라인 배포 컨퍼런스에서 여러 연사가 공통으로 “정상 상태를 정의할 수 없다면 스펙 기반 개발을 시도하지 말라”고 말했다.
- 15명에서 3명으로 팀이 줄어도 관측 데이터, 호텔(OpenTelemetry) 관련 데이터, 승인 기준을 에이전트에 제공하며 정상 상태를 비교하는 팀 사례가 소개됐다.
-
전문성의 위치 이동
- 규율과 전문성은 사라지는 것이 아니라 요구되는 위치가 바뀐다.
- 개발자는 기능 요구사항뿐 아니라 개발 요구사항(유지보수성), 운영 요구사항(지연시간·가동시간), 비즈니스 요구사항(기능이 실제 가치를 만드는지)을 함께 정의해야 한다.
- 세 축의 좋은 결과를 검증할 수 없다면 명세는 작성할 수 있어도 완전한 소프트웨어 팩토리 방식은 적용할 수 없다.
5. 복원력 엔지니어링의 목적과 세 가지 분산 시스템 규칙
5.1. 『Building Resilient Distributed Systems』가 나온 이유
-
안전 필수 시스템에서 소프트웨어로
- Velocity 컨퍼런스에서 확장성을 이야기하던 닷컴 기업들을 보며 시스템 엔지니어링에 관심을 갖게 됐다.
- David Woods의 복원력 엔지니어링 논문은 처음에는 컴퓨터 과학자를 위해 쓰인 글이 아니어서 거의 이해하지 못했지만, 2015~2016년부터 6개월마다 다시 읽으며 점차 개념을 소화했다.
- 많은 사람이 자신의 경고와 상관없이 분산 시스템과 마이크로서비스를 만들고 있다는 사실을 보고, 물에 빠지지 않도록 붙잡아 줄 고무 튜브 같은 입문서를 쓰기로 했다.
-
쉬운 구성요소에서 사회기술적 시스템까지
- 책은 분산 시스템의 기본 엔지니어링 개념에서 시작해 사회기술적 시스템, 안전 관리와 복원력 엔지니어링의 차이, 관측 가능성, 타임아웃으로 확장한다.
- 실제 기업 사고와 자신의 실수를 함께 다뤄 다른 사람의 실수에서 먼저 배우도록 한다.
- 복원력 엔지니어링은 모든 일이 잘되게 하는 것이 아니라 가능한 한 많은 일이 잘되게 하는 일이다.
- 장애를 솔직하게 말하고 공유하지 않으면 조직에 복원력 있는 시스템을 만들 수 없다.
-
사고 보고서와 신뢰
- GitHub는 장애의 원인과 발생 순서를 자세히 공개한 사례로 소개됐다.
- Cloudflare는 상장 기업임에도 24시간 안에 강한 자기반성을 담은 보고서를 공개해 좋은 사후 검토의 사례가 됐다.
- 마케팅처럼 보이는 사후 보고서와 실제 학습을 위한 사후 검토는 구분해야 한다.
- 실수하지 않는 회사는 없으며, 조직 신뢰는 실수 자체보다 실수에 어떻게 대응하고 무엇을 바꾸는지에 달려 있다.
5.2. 세 가지 규칙
-
첫째: A에서 B로 정보가 즉시 전달되지 않는다
- 거리·네트워크·물리 법칙 때문에 통신에는 시간이 걸린다.
- 양자 얽힘을 이용하면 임의의 거리에서 전자 스핀을 즉시 읽을 수 있다는 농담이 나왔지만, 그것은 읽기 문제일 뿐 네트워크 프로토콜의 정보 전달을 해결하지 않는다.
- 개발자는 페이로드 크기, 직렬화·역직렬화 방식은 제어할 수 있어도 케이블·장비·거리·공용 인터넷의 BGP 경로까지 통제할 수 없다.
- 즉시 응답처럼 보여도 지연·타임아웃·순서 뒤바뀜을 전제로 설계해야 한다.
-
둘째: 통신하려는 대상이 존재하지 않을 수 있다
- 로드 밸런서 뒤에 여러 인스턴스를 복제해도 로드 밸런서 자체나 데이터센터가 장애를 일으킬 수 있다.
- SAN의 SSD 캐싱 계층에서 두 쌍 중 한 쌍에 화재가 발생해 이상한 지연 그래프가 나타났고, 일부 서버의 장애 조치가 제대로 이뤄지지 않은 사례가 소개됐다.
- 사무실 건물 사이 덕트에 들어온 토끼가 네트워크 케이블을 갉아먹는 일처럼, 완전히 제거할 수 없는 물리적 사건이 통신 대상을 사라지게 한다.
- 장애 가능성을 줄일 수는 있지만 모든 의존성이 항상 존재한다고 가정할 수는 없다.
-
셋째: 리소스 풀은 무한하지 않다
- CPU·메모리·I/O·연결·큐 등 어떤 자원도 무한하지 않다.
- 로드 밸런서가 존재하고 네트워크 지연을 알아도 큐가 가득 차면 응답하지 않을 수 있다.
- 많은 장애는 한 자원의 포화에서 시작해 실패, 재시도 폭풍, 연결 부족, 더 큰 포화로 이어지는 악순환으로 커진다.
- CAP·PACELC·비잔틴 합의 같은 고급 용어보다 먼저 이 세 가지 현실을 기억하면 장애 상황의 첫 판단이 쉬워진다.
6. 관측 가능성, SLO, 그리고 필요한 만큼의 복원력
6.1. 단일 프로그램에서 분산 시스템으로
-
신호의 질이 달라진다
- 단일 프로그램은 디버거, 코어 덤프, JVM 스레드 덤프, CPU 100% 같은 양질의 신호를 거의 무료로 제공한다.
- 여러 머신으로 나뉘면 각각의 신호만으로는 전체 흐름을 알 수 없고, 상관관계를 만들기 위한 별도 작업이 필요하다.
- OpenTelemetry 같은 벤더 중립의 개방형 표준은 이 문제를 처음부터 다루는 기반이 된다. Honeycomb을 좋아한다는 농담과 스티커로 받는 보수 이야기도 나왔다.
-
타임아웃은 지연 분포에서 나온다
- 정상 응답 시간과 지연 분포를 모르면 적절한 타임아웃을 정할 수 없다.
- 단일 평균값보다 히스토그램과 성공 여부를 함께 봐야 한다.
- 기계 수준의 지연·500 응답 코드뿐 아니라 사용자가 버튼을 눌렀을 때 실제로 원하는 일이 완료됐는지까지 관측해야 한다.
-
추적과 스팬
- 한 호출은 서버 호출 스팬에서 데이터베이스 스팬과 다른 서비스 스팬으로 이어질 수 있다.
- 공통 trace ID와 시간 정보를 모든 스팬에 전파하면 여러 머신에 걸친 한 요청의 전체 경로를 재구성할 수 있다.
- Google의 내부 시스템을 따라 하려는 과정에서 Zipkin 같은 분산 추적 도구가 등장했고, 구조화된 이벤트 스트림이 사용자 행동과 시스템 동작을 연결한다.
6.2. SLI·SLO와 사용자 가치
-
지표에서 목표로
- SLI는 특정 시점의 서비스 상태가 좋은지 나쁜지를 판단하는 원시 지표다.
- 예를 들어 “성공한 차량 호출 요청을 300ms 이내에 99번째 백분위수로 처리한다”는 SLO를 만들 수 있다.
- SLO는 대시보드 색깔이 아니라 팀이 지켜야 할 약속이며, SLI 원시 데이터에서 계산된다.
-
기술적 정상과 사용자 정상은 다르다
- Uber에서 호출 버튼을 눌렀을 때 5초 안에 차량이 잡히는지, 무한 로딩에 빠지는지를 봐야 한다.
- 시스템이 보안상 완벽하고 500이 없더라도 사용자가 중요한 기능을 수행하지 못하면 실패다.
- 원시 이벤트에서 사용자 기능 수준의 추적과 뷰를 만들어야 운영팀이 진짜 정상 상태를 볼 수 있다.
-
SLA와 SLO
- SLA는 위반하면 법적 분쟁이나 소송의 대상이 될 수 있는 계약이다.
- SLA를 지키는 것만으로 고객 만족을 보장할 수 없고, 고객이 기대하는 사회적 계약과 SLO를 더 높은 수준으로 맞춰야 한다.
6.3. 복원력은 이분법이 아니라 선택의 문제다
-
Monzo의 예비 시스템
- Monzo는 핵심 애플리케이션 장애 때 가동할 별도 예비 시스템을 운영한다.
- 카드 정지, 출금, 잔액 조회 같은 핵심 기능만 제공하며 기존 코드나 다른 클라우드와의 공유를 최소화한 새 풀스택이다.
- 전체 수천 개 마이크로서비스의 약 10분의 1 수준 비용으로 상시 켜 둔다는 사례가 소개됐고, 연간 수백만 파운드 또는 달러가 들 것으로 추정됐다.
- 중요한 점은 Monzo가 자신의 비즈니스와 필요한 복원력 수준을 알고 있다는 것이다. 모든 조직이 여기서 시작해야 하는 것은 아니다.
-
멀티 리전·멀티 클라우드의 트레이드오프
- 멀티 클라우드는 클라우드 비용을 두 배로 만들 수 있고, 양쪽에 쓰기를 기다리면 지연도 늘어난다.
- 구축 시간·운영 복잡성·비용·지연시간을 비즈니스와 사전에 논의해야 한다.
- 위협 모델을 만들지 않고 “얼마나 안전해야 하는가?”에 답할 수 없다.
-
목표는 계속 바뀐다
- AWS US-East-1 장애를 보고 과거에는 필요 없다고 결론 내린 회사가 다중 리전을 다시 검토할 수 있다.
- Zoom은 완전 중단은 아니었지만 큰 영향을 받았고, 다중 리전의 비용과 가치가 맞지 않는다고 판단했을 수 있다.
- 시스템이 변화하고 진화하지 않으면 복원력이 아니라 취약성이 된다.
7. 멱등성, 재시도 폭풍, 확장과 비즈니스 판단
7.1. 멱등성(idempotency)
-
반복해도 결과가 같은 연산
- 엘리베이터에서 아래층 버튼을 여러 번 눌러도 목적지는 바뀌지 않는다. 이것이 멱등 연산의 직관적 예다.
- 토글 스위치를 두 번 누르면 켜졌다 꺼지므로 멱등이 아니다.
- 읽기와 삭제는 일반적으로 멱등적이지만 결제·예약·생성처럼 부작용이 있는 작업은 그렇지 않다.
-
결제와 항공권의 재시도 문제
- “샘에게 100파운드를 보내라”는 요청의 응답이 오지 않으면 결제가 됐는지, 전달조차 안 됐는지 알 수 없다.
- 항공권 결제 뒤 스피너가 멈췄을 때 새로고침하면 이중 결제가 될 수 있다는 경고는 사용자가 원하는 재시도와 시스템의 중복 부작용이 충돌하는 사례다.
- 첫 요청이 성공했는데 응답만 유실됐다면 재시도는 두 번 결제하거나 티켓을 두 장 만들 수 있다.
-
멱등성 키와 UUID
- 권장 방식은 클라이언트가 UUID 같은 고유한 멱등성 키를 생성해 요청마다 보내고, 서버가 이미 처리한 키라면 같은 결과를 반환하는 것이다.
- UUID는 추가 왕복 없이 로컬에서 만들 수 있고 충돌 가능성은 극히 낮지만, 서버와 클라이언트가 모두 필수 필드와 저장 정책을 지원해야 한다.
- Stripe·Adyen·PayPal·AWS API가 이런 키 체계를 사용한다는 사례가 언급됐다.
- 처음부터 설계할 수 있다면 처음부터 멱등성 키를 넣어야 하며, 기존 시스템에 나중에 추가하는 일은 필드·저장·호환성 때문에 번거롭다.
-
지문(fingerprint)의 보완책과 오탐
- 기존 시스템을 바꾸기 어렵다면 요청의 주요 필드를 해시해 지문을 만들고, 가까운 시간에 같은 요청이 들어오면 중복으로 간주할 수 있다.
- 정상적인 두 번째 요청을 중복으로 오인하는 오탐이 발생할 수 있다.
- 덴마크 결제 시스템에서 같은 매장에서 5분 안에 40크로네를 두 번 결제하면 두 번째 결제가 거부되는 예가 소개됐다. 39크로네나 41크로네는 통과할 가능성이 높다.
- AWS에서 for 루프로 동일한 지문을 가진 EC2 인스턴스 20개를 만드는 것은 합법적인 작업일 수 있으므로, 같은 요청처럼 보여도 실제로는 모두 필요한 경우가 있다.
- 지문 보관 시간을 5분·10분·1시간으로 제한할 수 있지만, 멱등성 키가 가능한 새 API에는 멱등성 키가 더 낫다. 같은 키로 매개변수를 바꾸면 서버가 잘못된 재사용으로 거부할 수도 있다.
7.2. Thundering Herd와 포화
-
재시작과 캐시 붕괴
- 장애 후 많은 클라이언트가 동시에 재시도하면 너무 많은 요청이 너무 적은 리소스로 몰리는 Thundering Herd가 된다.
- 캐시가 재시작하면 캐시 미스가 폭증하고 오리진 서버가 예상하지 못한 부하를 받아 함께 다운될 수 있다.
- 디스크에 캐시 스냅샷을 남기거나 캐시가 채워질 때까지 서비스를 제한하는 방식으로 완화할 수 있다.
-
Square의 2017년 재시도 폭풍
- Square의 MultiPath 다중 인증 시스템이 Redis에서 데이터를 읽던 중 재시작됐다.
- Redis 호출이 실패하자 지연 없이 바로 재시도했고, 재시도 한도가 500회로 하드코딩돼 Redis와 MultiPath가 연쇄적으로 과부하에 빠졌다.
- 합리적인 재시도 정책을 도입하고 한도를 외부 설정으로 공개하면서 해결했다.
- Redis를 데이터베이스처럼 쓰는 문제를 두고 “어리석은 기술 사용법” 팟캐스트를 만들 수 있겠다는 농담이 나왔다.
-
외부 성공과 공격의 구분
- Twitter와 healthcare.gov는 실제 사용자 유입이 제품 성공을 넘어 시스템을 무너뜨린 사례다.
- healthcare.gov는 36개 주에서 동시에 출시해 부하를 만들었고, 한 주씩 시작하는 편이 나았을 수 있다.
- Twitter는 가입자·트윗 수를 제한했고, 신규 가입자나 초대 코드 수를 줄이는 방법도 합법적 부하를 관리하는 수단이다.
- DDoS에 자동 확장을 적용하면 서비스 거부뿐 아니라 비용 거부(DDoC)가 된다. Kubernetes 노드를 계속 만들면 서비스가 회복되기 전에 클라우드 비용이 폭증한다.
7.3. 실패 시 진행할 것인가, 중단할 것인가
-
재고와 콘서트 티켓
- 일반 전자상거래는 재고를 확실히 확인하지 못해도 판매하는 편이 낫다. 나중에 재고가 없으면 이메일을 보내 환불할 수 있지만, 판매를 멈추면 고객과 매출을 잃는다.
- Taylor Swift 콘서트 티켓은 다르다. 티켓이 있는지 모르는 상태에서 판매하면 고객이 항공편과 가족 여행까지 예약한 뒤 취소 통보를 받을 수 있어 피해가 훨씬 크다.
- 전자는 실패 시 진행(fail-open), 후자는 실패 시 중단(fail-close)에 가까운 비즈니스 판단이다.
-
Uber의 단계별 선택
- 초기 Uber는 결제 결과가 불확실해도 운행을 계속하는 실패 시 진행을 택했다. 성장 단계에서는 손실을 감수하고 사용자를 얻는 편이 중요했다.
- 수익성과 단위 경제성을 추구하는 단계가 되면 결제가 실패하면 운행을 중단하는 실패 시 중단으로 바뀐다.
- 같은 회사도 사업의 생애주기와 기능의 중요도에 따라 정책을 바꾼다. 10유로 요금과 1,000유로 요금의 실패 허용 수준도 다를 수 있다.
-
CAP·PACELC보다 먼저 할 대화
- CAP의 P는 네트워크 파티션, 즉 시스템 일부와 통신할 수 없음을 뜻한다.
- 통신이 끊겼을 때 재시도·일관성·가용성을 기술적으로 선택할 수 있지만, 최종 선택은 제품 소유자·도메인 전문가와 비즈니스 맥락을 확인해야 한다.
- CAP, PACELC, Harvest and Yield 같은 모델은 대화를 정교하게 만들지만 대화를 대신하지 않는다. 먼저 “고객에게 무엇이 더 큰 피해인가?”를 물어야 한다.
8. 복원력의 네 가지 차원
8.1. 견고성(robustness)
-
알려진 교란을 흡수하기
- 시스템을 모델링하고 알려진 장애를 사용자가 거의 알아채지 못하게 처리하는 능력이다.
- Kubernetes Pod가 죽으면 대체 Pod를 만드는 방식이 간단한 예다.
- 멀티 리전·멀티 클라우드도 알려진 장애에 대비할 수 있지만, 새로운 오케스트레이션과 네트워크 복잡성을 추가해 새로운 실패 모드를 만든다.
-
견고성만 키우는 함정
- 많은 엔지니어가 복원력을 견고성과 동일시하지만, 나머지 세 차원을 놓치면 취약하다.
- Kubernetes를 도입하면 Pod 장애는 줄어도 Kubernetes 자체를 운영해야 한다.
- 알려진 문제에 대한 자동화가 알려지지 않은 상황에 대한 준비를 대신하지 않는다.
8.2. 회복(recovery)
-
얼마나 빨리 정상으로 돌아오는가
- 장애 감지 시간과 복구 시간을 측정하고, 저하된 상태에서 다시 정상적으로 서비스하는 시간을 줄여야 한다.
- 안정성은 시스템이 절대 고장 나지 않는다는 약속이 아니다. “우리가 틀렸다면 어떻게 복구할까?”를 진지하게 묻는 태도가 필요하다.
-
훈련과 반복
- Netflix의 Chaos Monkey는 시스템 일부를 끊어 실제 복구 능력을 시험하는 유명한 사례다.
- 온콜 절차와 의사결정 과정을 포함한 장애 훈련은 한 번으로 끝나지 않는다. 시스템이 변하므로 정기적으로 반복해야 한다.
- 런던의 Uptime Labs가 브라우저에서 복구 훈련을 제공하는 사례로 소개됐다.
8.3. 우아한 확장성(graceful extensibility)
-
예상하지 못한 상황에 대처하기
- 견고성이 알려진 장애를 처리한다면 우아한 확장성은 예상하지 못한 상황에서도 사람과 조직이 대응할 여지를 남긴다.
- 분산 시스템은 사람과 기술이 결합된 사회기술적 시스템이므로, 토끼·화재·물리적 고립처럼 설계자가 목록에 넣지 못한 사건도 다뤄야 한다.
- 명령과 통제가 엄격하고 업무 범위가 좁은 조직은 예외 상황에서 현장 판단을 하기 어렵다.
-
불운의 수레바퀴
- Google SRE는 “불운의 수레바퀴”를 돌려 DNS 포이즈닝 같은 예상하지 못한 상황을 무작위로 제시하고 대처를 연습했다.
- 사람의 경험·새로운 시도·훈련이 기술적 자동화만큼 중요하다.
-
Meta의 물리적 접근 장애
- Meta의 BGP 기반 DNS 장애로 WhatsApp과 Meta 서비스가 멈췄을 때, DNS 테이블과 서버의 연결을 고치려면 건물 안에 물리적으로 들어가야 했다.
- 출입문 보안 시스템도 자체 도메인에서 동작해 문을 열 수 없었고, 결국 물리적으로 침입해야 했다.
- Meta가 세부사항을 공유하면서 다른 조직도 물리적 보안이 자체 도메인에 종속되지 않았는지 점검할 수 있었다.
8.4. 지속적 적응성(continuous adaptability)
-
사고가 없어도 배우기
- 장애가 발생한 뒤에만 배우는 것이 아니라, 사고가 없을 때도 다른 조직의 사고 보고서를 읽고 시스템을 바꿔야 한다.
- 수백 건의 보고서가 모인 The Void 같은 자료를 읽으면 경쟁사의 실패에서도 개선점을 얻을 수 있다.
-
심리적 안전
- 문제가 제기되거나 반대 의견을 말할 수 없는 조직은 작은 신호를 숨기고, 학습하지 못한 채 큰 사고를 맞는다.
- 책의 13장 중 기술적 내용 뒤에 사회적 행동을 다루는 마지막 세 장이 배치된 이유도 심리적 안전과 문화가 복원력의 필수 조건이기 때문이다.
- 복원력은 고정된 속성이 아니라 조직이 계속 관찰·논의·수정하는 과정이다.
9. AI를 복원력 있게 사용하는 법
9.1. 미시적 유용성과 거시적 경제성의 분리
-
AI가 도울 수 있는 일
- 상관관계 분석, 장애 후 분석, 사고 데이터 정리 같은 미시적 작업에는 AI와 봇이 유용하다.
- Instant.io가 이런 분석에 성과를 내는 사례로 언급됐다.
- 에이전트가 더 많은 코드를 작성해도 좋은 결과와 검증 체계가 있으면 생산성을 높일 수 있다.
-
AI 기업의 거시적 지속 가능성
- OpenAI·Anthropic·하이퍼스케일러가 자본 지출을 정당화하려면 2030년까지 약 2조6천억 달러 매출이 필요하다는 보수적 경제 분석이 소개됐다.
- 전체 소프트웨어 시장 규모가 약 1조4천억 달러라는 비교를 보면, 모델 기업 경제성은 엔지니어가 해결할 수 없는 거시적 문제다.
- 자신의 제품이 이런 시장에 의존한다면 모든 문제를 해결할 수 없음을 인정하고 주변 환경에 맞춘 위험 회피 전략을 세워야 한다.
9.2. 비결정성·공급자 장애·인과관계
-
공급자와 모델을 다양화하기
- OpenAI와 Anthropic 같은 핵심 모델 API의 가용성이 충분히 높다고 가정하면 안 된다.
- Google·Amazon·Microsoft의 모델이나 오픈 웨이트 모델을 백업으로 사용할 수 있도록 공급자를 분산해야 한다.
- 여러 모델·여러 에이전트를 사용하고, 워크플로 일부를 결정론적 코드로 교체하면 장애와 변동성을 줄일 수 있다.
-
LLM은 원인과 결과를 모른다
- LLM이 데이터베이스를 삭제하는 이유는 원인이라는 개념을 실제로 갖고 있지 않기 때문이다.
- 유리잔을 카펫에 떨어뜨리면 괜찮을 가능성이 높고 딱딱한 바닥에 밀면 깨질 수 있다는 인간의 물리적 직관을 LLM은 스스로 갖고 있지 않다.
- LLM은 세계 모델이 아니며, 세계 모델과 적절한 입력·규칙이 있어야 “X를 하면 Y가 일어나고 Y는 금지된다”는 판단을 안정적으로 할 수 있다.
- LLM이 똑똑해 보인다는 이유로 실제 능력을 과대평가하면 안전장치만으로는 장기적인 해결책이 되지 않는다.
-
결정론적 코드의 역할
- 에이전트가 스크립트를 호출하고 그 결과를 검증하는 방식은 에이전트가 매번 마법처럼 스크립트를 새로 구현하게 하는 것보다 예측 가능하다.
- Anthropic과 OpenAI가 특정 작업에서 Python·TypeScript 같은 결정론적 프로그램을 생성하도록 모델을 훈련하는 것은 이 장점을 활용하는 흐름이다.
- 생성 코드는 그럴듯한 언어일 뿐이므로 실행·테스트·운영 데이터로 검증해야 한다.
9.3. 인지적 포기와 인지 부채
-
연구에는 유용하지만 검토가 필요하다
- 샘 뉴먼은 책 집필에는 AI를 거의 쓰지 않았지만 연구에는 NotebookLM을 사용했다.
- 논문과 링크를 하나씩 확인하는 검토를 전제로 하면, 사람이 읽을 수 있는 NIST 자료보다 더 넓은 자료를 빠르게 탐색할 수 있다.
- AI가 자신이 절대 읽지 않을 문서를 만들어내고 그대로 승인하면 도구의 문제가 아니라 사용자의 인지적 포기(cognitive surrender)다.
-
인지 깊이와 LGTM
- AI 도구를 많이 사용할수록 비판적 사고와 추론이 약해질 수 있다는 연구가 언급됐다.
- LGTM(Looks Good To Me)을 실제 검토 없이 승인 패턴으로 사용하는 것은 AI가 만든 대규모 PR을 읽지 않고 수용하는 인지적 포기의 사례다.
- Google 도구 팀에서 LGTM이 승인 신호로 쓰였던 관행이 이런 약어의 배경으로 언급됐다.
-
전문가를 승인 버튼으로 만들지 않기
- 종양 전문의가 모든 스캔을 직접 판단하는 대신 AI가 “검토할 것은 이것”이라고 최종 승인 목록만 주면, 전문가가 배제되고 한 사람의 승인만 남는 위험이 있다.
- 더 나은 방식은 AI가 놓쳤을 수 있는 부분을 보여주고 전문가의 판단력을 강화하는 보조자 역할을 하는 것이다.
- AI는 인간을 고된 노동에서 해방해 비판적 사고에 집중하게 한다는 약속이 있었지만, 현재의 무분별한 사용은 잦은 컨텍스트 전환과 더 긴 노동시간을 만들 수 있다.
9.4. 모듈화와 안전한 다크 팩토리 실험
-
복잡성 위에 복잡성을 더하지 않기
- Kubernetes는 개발자를 단순화하기 위해 플랫폼으로 감싸야 하는 복잡한 인프라다.
- AI를 모든 문제의 해법으로 덧붙이면 기존 플랫폼 복잡성 위에 에이전트·모델·프롬프트·검증 복잡성이 더해진다.
- AI를 사용하더라도 구축하는 시스템과 연결을 끊지 말고, 시스템이 무엇을 하는지 계속 이해해야 한다.
-
모듈 경계 안에서 AI 사용하기
- AI는 모듈 내부의 변경을 수행하고, 인간은 모듈의 책임과 모듈 사이의 연결을 설계한다.
- 서로 다른 컴퓨터에 배치하든 모놀리스 안에 두든 모듈의 정보 은닉과 계약이 더 중요하다.
- Shopify가 모놀리스를 유지하면서도 성공한 이유는 모듈형 도메인 중심 아키텍처에 투자해 전체 구조와 연결을 이해하기 쉽게 만들었기 때문이다.
-
소프트웨어 팩토리를 작은 위험에서 시작하기
- 일부 기업은 사양을 주면 AI가 모듈을 구축·운영하는 다크 팩토리 방식을 이미 시험하고 있지만, 모든 조직이 한 번에 따라야 하는 것은 아니다.
- 핵심 경로가 아니고 관측 데이터·SLO·테스트 커버리지가 충분한 모듈부터 몇 주 단위로 다시 작성해 실제 프로덕션 결과를 본다.
- 마이크로서비스도 처음부터 가장 중요한 결제나 핵심 기능을 옮기지 않고, 덜 중요한 작은 서비스에서 시작해 손실을 제한하며 배웠다.
- Curo·Tessel·Spec Kit 같은 도구를 사용해 입력과 출력의 스펙을 먼저 정하고, 기능·개발·운영·비즈니스 요구사항을 함께 검증한다.
- 명세만으로 공장을 세우는 것은 위험하다. 모델 기반 개발(MDD/MDM)의 실패가 반복될 수 있으므로, 현재 신뢰 수준이 낮은 영역에서는 여전히 사람이 코드와 운영을 깊이 봐야 한다.
10. 아키텍처 사고를 키우는 방법
10.1. 오래된 원칙과 추천 자료
-
모듈과 정보 은닉
- Neal Ford와 Mark Richards의 『Software Architecture Fundamentals』는 시스템 아키텍처를 생각하는 출발점으로 추천됐다.
- Vlad Khononov의 『Balanced Coupling』은 모듈화와 결합을 다루는 특히 좋은 책으로 꼽혔고, 그의 DDD·Clojure 관련 책도 함께 언급됐다.
- David Parnas가 1971~1972년에 쓴 정보 은닉 논문은 오래됐지만 여전히 가치가 있다.
- 『Building Microservices』 2판에서 가장 중요하게 생각한 개념도 Single Information Hiding이다.
-
기존 코드베이스에서 시작하기
- 모듈 경계를 명확히 하고 캡슐화로 정보를 숨기는 일은 마이크로서비스로 분리하지 않아도 시작할 수 있다.
- 에이전트에게 “이 부분을 리팩터링하라”는 제한된 목표를 주고, 수작업 시간보다 빠르게 실험하되 결과는 테스트가 보장해야 한다.
- 테스트 스위트가 없으면 먼저 테스트부터 만든다. 정적 타입과 IDE가 있는 언어는 큰 도움을 주고, Python·Ruby도 과거보다 IDE 기반 리팩터링이 쉬워졌다.
-
코드가 정신 모델을 표현하게 하기
- 아키텍처를 사람의 머릿속에만 두지 말고 코드와 명세가 같은 정신 모델을 표현하도록 해야 한다.
- George Fairbanks가 말한 “아키텍처적으로 명확한 코딩 스타일”처럼 코드만 읽어도 시스템 구조가 드러나는 방식을 지향한다.
- 현재 프로그래밍 언어의 모듈 표현력이 충분하지 않으므로, 프로세스 경계·네트워크·프로덕션 신호까지 활용해 아키텍처를 명확히 드러내야 한다.
10.2. 점진적 전환의 원칙
-
균일한 전략을 강요하지 않기
- 전체 시스템은 모듈형 모놀리스나 마이크로서비스일 수 있고, 일부 영역만 소프트웨어 팩토리 방식을 사용할 수 있다.
- 모든 영역에서 코드 리뷰를 없애거나 모든 영역에서 AI를 금지하는 양자택일은 불필요하다.
- 위험이 낮고 성공 기준이 명확한 영역에서는 AI 자율성을 높이고, 중요 경로에서는 인간의 코드·설계·운영 참여를 유지한다.
-
프로덕션을 마지막 검증자로 두기
- 기능 테스트뿐 아니라 지연시간·가동시간·운영 요구사항과 비즈니스 결과를 SLO로 관찰해야 한다.
- 모듈을 공장처럼 운영할수록 실제 사용량과 장애를 통해 출력 품질을 확인해야 한다.
- “축구가 인생과 같듯, 프로덕션은 진실이다”라는 결론은 코드와 사양이 현실을 지속적으로 따라가야 한다는 뜻이다.
주요 발언 모음
“마이크로서비스는 최후의 수단으로 사용하는 아키텍처다.”
“A 지점에서 B 지점으로 정보를 즉시 전송할 수 없다.”
“때로는 통신하려는 대상이 존재하지 않을 수 있다.”
“리소스 풀은 무한하지 않다.”
“진실은 프로덕션이다. 그 밖의 모든 것은 우리가 스스로에게 하는 거짓말이다.”
“프로그래밍은 타이핑이 아니다.”
“복원력 엔지니어링은 모든 일이 잘되게 하는 것이 아니라 가능한 한 많은 일이 잘되게 하는 것이다.”
“LLM은 세계 모델이 아니다.”
“AI가 모듈 안에서 일하게 하고, 인간은 모듈과 연결을 신중하게 설계해야 한다.”
핵심 데이터 & 수치
- 영상 길이: 약 7,145초(1시간 59분 5초)다.
- ThoughtWorks 규모: 샘 뉴먼 입사 시 400명 미만에서 퇴사 무렵 약 4,000명으로 성장했다.
- Fortran 77 리팩터링: 약 8,000개 파일, 반복 횟수 약 99,999회 제한을 자동화했다.
- Entier 처리량: 저장소가 초당 418회 푸시를 처리하고 경쟁사보다 최대 89배 빠르다고 소개됐다.
- TurboPuffer V3 중간 결과: 콜드 전체 텍스트 검색은 기존 프로덕션보다 11배, 핫 전체 텍스트 검색은 126배 느렸고 벡터 검색 일부는 동등하거나 더 빨랐다.
- 예시 SLO: 성공한 차량 호출 요청을 300ms 이내, 99번째 백분위수로 처리한다.
- Monzo 예비 시스템: 수천 개 마이크로서비스 풀스택의 약 10분의 1 수준 비용으로 핵심 카드·출금·잔액 기능을 상시 제공한다.
- Square 재시도 폭풍: MultiPath의 Redis 재시도 한도가 500회로 하드코딩돼 있었다.
- healthcare.gov: 36개 주에서 동시에 서비스를 시작해 큰 부하를 맞았다.
- AI 경제성 주장: 일부 경제 분석은 주요 AI 기업들이 2030년까지 약 2조6천억 달러 매출을 내야 자본 지출을 정당화할 수 있다고 추정했고, 전체 소프트웨어 시장은 약 1조4천억 달러로 비교됐다.
결론 및 시사점
- 마이크로서비스는 독립 배포와 비즈니스 도메인 경계가 필요하며, 조직 자율성이라는 명확한 목적이 없으면 최후의 수단으로 남겨야 한다.
- 모든 분산 시스템 설계는 지연·의존성 부재·유한한 리소스라는 세 가지 규칙에서 출발해야 한다.
- 관측 가능성은 CPU와 500 응답만 보는 일이 아니라, 사용자가 중요한 일을 성공했는지 추적하고 이를 SLI·SLO로 표현하는 일이다.
- 복원력 투자는 위협 모델·비용·지연·운영 복잡성·비즈니스 피해를 함께 비교해 “충분히 좋은 수준”을 정하는 과정이다.
- 멱등성 키는 재시도 가능한 부작용 작업에 가장 좋은 기본값이며, 기존 시스템의 지문 방식은 오탐과 정상 반복 작업을 고려해 제한적으로 사용해야 한다.
- 캐시 붕괴·재시도 폭풍·DDoS·합법적 사용자 폭증은 겉보기에는 비슷해도 각각 다른 완화책을 요구한다.
- 실패 시 진행과 실패 시 중단은 기술의 절대 규칙이 아니라 고객 피해와 사업 단계에 따른 비즈니스 선택이다.
- 견고성만 높이는 것보다 회복 훈련, 예상 밖 상황에 대한 인간의 재량, 사고에서 계속 배우는 문화까지 갖춰야 한다.
- 심리적 안전과 솔직한 사고 보고는 기술적 자동화만큼 중요한 복원력 기반이다.
- AI는 분석·코드 생성·사고 대응에 유용하지만, 모델 공급자를 분산하고 비결정적 작업을 결정적 코드로 치환하며 모듈 경계 안에서 점진적으로 도입해야 한다.
- 인지 부채와 인지적 포기를 피하려면 사람이 시스템의 정신 모델을 이해하고, AI의 결과를 실제 운영 데이터와 검증 기준으로 확인해야 한다.
- 가장 현실적인 출발점은 테스트 스위트가 있는 저위험 모듈에서 사양·운영 요구사항·SLO를 정의하고 작은 소프트웨어 팩토리를 실험하는 것이다.
- 아키텍처의 진실은 문서나 코드 어느 하나에 고정되지 않는다. 실제 프로덕션의 사용자 경험과 운영 결과가 모델을 계속 수정하게 해야 한다.
참고 및 후속 자료
- 샘 뉴먼의 협업·교육·컨설팅: https://samnewman.io/
- Sam Newman, 『Building Microservices』 및 『Building Resilient Distributed Systems』
- David Woods의 Resilience Engineering 연구
- Dave Farley의 Monzo Engineering 채널
