티스토리 뷰
- 저자
- 타이터스 윈터스, 톰 맨쉬렉, 하이럼 라이트
- 출판
- 한빛미디어
- 출판일
- 2022.05.10
독서 기간 : 3/24~4/19
목차
읽기 전
표지에 왜 플라밍고가 있나 궁금했다.
표지를 넘기자마자 설명이 나와있긴 하다. 표지로 선정한 이유는 없이 그냥 플라밍고란 동물에 대한 설명이 있어서 아직도 궁금증이 풀리지 않았다..
읽으면서
구글은 누구나 아는 큰 기업이지만 기업 규모에 상관없이 스타트업이든, 소기업이든 겪을 수 있는 이슈로 시작되었다.
그 이슈의 대처법과 앞으로의 변화 방안이 함께 나와 앞으로도 이렇게 전개가 되는 책이라면 나에게도 도움이 많이 될 거라 생각했다.
SI로도 일해봤지만 솔루션 경력이 대부분이라 더 공감과 관심이 가는 내용들이었다.
리더에게 필요한 정보이거나 현재 적용할 수 없는 기술들은 꽤 많이 사선 읽기 했다.
오래된 기업인 만큼 시행착오를 대신 거쳐줬지만 그 기술을 적용하려면 어느 정도 이상의 규모의 기업에서만 가능할 것 같았다.
내용이 방대해서 나중에 필요할 때 생각나서 적용할 수는 있게 큰 틀만 설렁설렁 읽는 걸로..
관심 있고 중요하다고 생각하는 부분만 발췌한 항목은 아래에.
CHAPTER 1 소프트웨어 엔지니어링이란?
'소프트웨어 엔지니어링은 흐르는 시간 위에서 순간순간의 프로그래밍을 모두 합산한 것이다'
프로그래밍 작업(개발) / 소프트웨어 엔지니어링 작업(개발+수정+유지보수)
하이럼의 법칙
최선의 의도, 최고의 엔지니어, 꼼꼼한 코드리뷰가 뒷받침되더라도 공표한 계약이나 모범 사례를 완벽하게 구현해 냈다고 단정할 수 없다는 현실
현실에서는 API사용자가 명세에는 없는 기능을 찾아 활용하기도 하며, 그 기능이 유용해 널리 쓰이면 추후 API를 변경하기 어렵게 됩니다.
'당장 돌아가야 한다'라는 생각으로 작성한 코드와 '언제까지고 작동해야 한다'라는 생각으로 작성한 코드의 차이를 생각해 보면 어떤 관계인지가 분명하게 그려질 것입니다.
모범사례를 따르고 미래에 대비한 코드는 '클린 하고 유지보수가 가능한 코드'
둘 다 나름의 목적이 있지만, 어느 쪽을 선택할지는 코드의 기대 수명에 크게 좌우됩니다.
나도 위같이 개발을 하나? 생각해 보니 테스트 코드나 개발에 쓰는 로그 소스정도는 정말 몇 분에서 며칠정도만 쓰이는 코드였다. 그 코드들과 릴리즈 되어 계속 쓰는 기능의 코드는 다르게 작성하는 거 보면 모두가 무의식적으로 이를 생각할 것 같았다.
비욘세 규칙
'CI시스템의 자동 테스트에서 발견되지 않는다면 인프라팀의 책임이 아니다'
네가 좋아했다면 CI테스트를 준비해 뒀어야지(네가 좋아했다면 반지를 끼워줬어야지 - single ladies)
프로그래밍과 소프트웨어 엔지니어링
프로그래밍 - 코드 생산
소프트웨어 엔지니어링 - 프로그래밍을 확장하여 소프트웨어의 수명이 다할 때까지 코드를 유지보수하는 문제까지 고려
CHAPTER 3 지식 공유
사회적 규칙
- 거짓된 놀람 금지("뭐라고?! 스택이 뭔지 모른다니 믿을 수가 없네!")
거짓된 놀람은 심리적 안전을 방해하여 구성원들은 모른다는 사실을 인정하기를 두려워하게 됩니다.
- "음, 실제로는..." 금지
지나칠 정도로 세세하게 고쳐주는 행위는 정밀성보다는 자신을 뽐내려는 무의식에 기인하는 경향이 있습니다.
- 뒷좌석 운전 금지
토론 중에 적절한 발언권 없이 끼어들어 의견을 제시하지 마세요.
- 미묘한 '-주의' 금지("이건 우리 할머니도 할 수 있겠네!")
인종주의, 연령주의, 동성애 혐오 발언 같이 편견이 깃든 표현은 다른 이에게 불편함과 무례함, 불안감을 느끼게 합니다.
IT 지식의 도서에 나온 내용이지만, 이름이 '사회적 규칙'인 만큼 일상생활에서도 도움이 될 내용이다.
나부터 이렇게 하지 않도록 주의하기.
체스터슨의 울타리
'무언가를 옮기거나 바꾸려면 그게 왜 그 자리에 있는지부터 이해하자'
CHAPTER 4 공정 사회를 위한 엔지니어링
다양한 계층의 사용자를 위한 제품을 설계할 때 엔지니어가 짊어져야 할 책임
오늘날의 개발은 많이 쓰이는 기능을 먼저 만들고 특수한 상황에 쓰이는 기능이나 개선은 나중으로 미루는 방식으로 주로 진행됩니다. 기술을 접하기에 유리한 사람들에게 우선권을 줌으로써 불평등을 가중하는 방식인 것입니다.
모든 사용자층을 고려하는 일을 설계 막바지까지 미룸으로써 훌륭한 엔지니어의 기준을 낮추는 꼴입니다.
당연히 많이 사용하는 기능을 먼저 개발, 유지보수 해야 한다고 생각했는데 이 부분을 읽고 생각하지 못한 부분이라 놀랐다.
많은, 모든 사용자들을 사용하게 하려면 더 고려할 사항이 많았던 것..
CHAPTER 6 성장하는 조직 이끌기
트레이드오프
두 개의 정책목표 가운데 하나를 달성하려고 하면 다른 목표의 달성이 늦어지거나 희생되는 경우
(네이버 검색)
"좋게(품질), 빠르게(지연시간), 저렴하게(용량) 중 두 개만 선택해!"
트레이드 오프라는 단어를 처음 봤다.
어느 것을 얻으려면 반드시 다른 것을 희생하여야 한다는 의미였다.
품질, 시간, 저렴 중에 2개를 희생시키며 구글 검색에서 선택하는 상황이 실제로 일어났고, 읽으면서 뭘 선택했을지 궁금했는데 ㅋㅋㅋㅋ 매달 반복하며 늘 결정한다고 한다.
정답은 역시 없는 걸까...
CHAPTER 7 엔지니어링 생산성 측정하기
측정할 가치가 있는가?
측정 프로세스가 성가시다면 나머지 엔지니어링 조직들의 작업 속도를 늦추게 됩니다.
속도를 늦추지 않더라도 측정 프로세스가 개입하면서 엔지니어들의 작업 방식이 달라져서 원래의 작업 방식에 존재하던 근본적인 문제를 감춰버리는 상황도 발생할 수 있습니다.
고려해 볼 측면
- 어떤 결과를 기대하고, 왜 그런가?
우리는 중립적인 척하고 싶지만 실제로는 그렇지 않습니다. 우리 모두는 어떤 일이 일어나야 하는지에 대한 선입견을 가지고 있습니다.
- 데이터가 기대한 결과를 뒷받침한다면 어떤 조치를 취하겠는가?
아무런 조치도 취하지 않을 거라면 측정을 해봐야 의미가 전혀 없습니다.
-부정적인 결과가 나온다면 적절한 조치를 취할 것인가?
부정적인 결과가 나와도 결정이 바뀌지 않는 경우가 흔하기 때문입니다.
-결과에 따른 조치는 누가 결정하고, 언제 수행하는가?
측정 의뢰자가 조치를 취할 권한이 있는지를 확인하는 것
위의 네 가지 말고도 도서 안에서는 여러 가지가 나오는데 먼저 언급된 만큼 더 중요한 요소라고 생각한다.
CHAPTER 8 스타일 가이드와 규칙
규칙 만들기
- 규칙의 양을 최소화한다
규칙이 너무 많다면 엔지니어들이 다 기억하지도 못할 것이고 새류 합류한 엔지니어가 적응하기도 어렵습니다.
- 읽는 사람에게 맞춘다
코드는 작성되는 횟수보다 읽히는 횟수가 더 많으며 시간이 지날수록 차이가 벌어집니다.
읽기 난해한 것보다 타이핑하기 지루한 편이 낫습니다.
구글은 '쓰기에 간편한'보다 '읽기에 간단한'쪽에 가치를 둡니다.
CHAPTER 9 코드리뷰
코드리뷰 @구글
구글에서는 어떤 변경이든 '승인'을 얻으려면 세 가지 측면에서의 리뷰를 통과해야 합니다.
첫째. 다른 엔지니어로부터 정확성과 용이성을 평가받습니다.
둘째. 변경되는 코드 영역을 관리하는 코드 소유자로부터 변경 코드가 적절하다는 승인을 받습니다.
셋째. 누군가로부터 '가독성'승인을 받습니다.
통제하는 게 너무 과하게 보일 수 있고, 때로는 정말 과한 것도 사실입니다.
세 역할을 수행할 수 있는 사람 한 명이 처리하기 때문에 이 절차들이 빠르게 진행됩니다.
일을 할수록 코드리뷰의 중요성과 필요성을 느낌에도, 각자의 업무가 바쁘고 여유시간이 주어지지 않아 제대로 진행되기가 쉽지 않았다.
그런 의미에서 위와 같은 구글의 코드리뷰는 부럽기까지 하다.
규모가 클수록 이런 업무를 같이 수행해 줄 엔지니어도 더 늘어난다는 의미이기도 해서 구성원이 많은 곳을 점점 찾게 된다.
잘 설계된 코드 리뷰 프로세스와 코드 리뷰를 중요하게 다루는 문화가 주는 대표적인 이점
- 코드가 정확한지 확인해 줍니다.
- 변경된 코드를 다른 엔지니어도 잘 이해합니다.
- 코드베이스가 일관되게 관리됩니다.
- 팀이 소유권(주인의식)을 더 강하게 느낍니다.
- 지식이 공유됩니다.
- 코드 리뷰 자체의 기록이 남습니다.
내가 작성한 코드가 오래 남을수록 코드리뷰의 필요성을 더 느끼게 된다.
팀으로 일하면서 내 코드가 남에게 읽히거나, 내 코드의 기능에서 확장된 업무를 할 때 코드리뷰가 잘 되었으면 좋았을 텐데.. 하게 된다.
요청하면 거절하실 분들은 적겠지만 그 상황을 마주하기도 쉽지 않을 때가 있다.
문서 작성의 핵심
균형을 잘 잡는 것.
문서를 '짧게' 쓰는 게 유리하다는 사실
지루한 작업 같겠지만 여기에 들이는 비용이 여러분의 문서자료를 읽는 모든 이에게 혜택으로 돌아간다는 사실을 잊지 마세요.
업무시 매뉴얼이나 프로토콜 등의 문서를 작성하기를 좋아하해서 즐기는데 안 그런 사람들도 꽤 많아서 부담스러워하는 것 같다.
그런 사람에게는 이다음 챕터(10. 문서자료)가 도움이 될 것 같다.
CHAPTER 11 테스트 개요
구글은 전통적인 용어인 '단위 테스트'와 '통합 테스트'대신 이 정의를 사용합니다.
작은 테스트
테스트가 단 하나의 프로세스에서 실행되어야 한다.
테스트를 느려지게 하거나 비결정적으로 만드는 주요 원인들로부터 작은 테스트를 떼어 놓는 것.
CPU가 수행할 수 있는 최고 속도로 실행.
중간 크기 테스트
여러 프로세스와 스레드를 활용
외부 시스템과의 통신은 여전히 불허하며 단 한 대의 기기에서 수행
큰 테스트
여러 대의 기기를 활용할 수 있게 됩니다.
종단 간 테스트는 코드 조각이 아닌 설정을 검증하는 게 주된 목적.
빌드나 릴리스 때만 수해 되도록 한다.
테스트 용어만 다를 뿐 전체 프로세스는 낯설진 않았다.
CHAPTER 15 폐기
오래된 시스템을 유지하려면 관리하는 데 지속해서 비용이 들어가고 난해한 옛 기술에 대한 전문지식이 필요합니다.
낡은 시스템을 완전히 걷어내는 과정을 폐기(deprecation)라고 합니다.
폐기는 왜 그리 어려운가?
이 책 곳곳에서 하이럼의 법칙을 언급했습니다. 이 법칙은 폐기에도 어김없이 영향을 줄 만큼 중요합니다. 하이럼의 법칙에 의해 시스템은 사용자 수가 늘수록 설계자가 예상하지 못한, 전에 본 적 없는 방식으로 이용될 가능성이 커져서 폐기 작업을 그만큼 어렵게 만듭니다.
폐기 유형 - 권고 폐기
기한이 없고 조직에서도 우선순위가 높지 않은 경우.
강제성이 없으며 고객이 알아서 움직여주길 희망.
새로운 시스템이 사용자에게 주는 혜택이 매우 클 때 효과가 좋습니다.
폐기 유형 - 강제 폐기
더 적극적인 장려의 좋은 예
낡은 시스템의 지원 종료일을 못 박는 형태로 이루어짐.
CHAPTER 16 버전 관리와 브랜치 관리
버전 관리 시스템은 가장 널리 쓰이는 소프트웨어 엔지니어링 도구
데브옵스(DevOps)가 유행시킨 트렁크 기반 개발이 확장성이 뛰어나다.
CHAPTER 17 Code Search
Code Search는 구글이 이용하는 코드 브라우징 및 검색도구로, 프런트엔드 UI와 다양한 백엔드 요소로 이루어져 있습니다.
'클릭 한 번으로 다음 (예상) 질문에 답해주기'가 Code Search 개발 원칙의 하나가 됨.
CHAPTER 18 빌드 시스템과 빌드 철학
구글 엔지니어에게 구글에서 일하면서 무료 음식과 멋진 제품들 외에 무엇을 가장 좋아하는지 묻는다면 재미난 대답을 듣게 될 것입니다.
구글 엔지니어에게 빌드 시스템은 사랑입니다.
이 부분을 읽고 사랑까지?! 하면서 어떤 내용일지 궁금했다.
빌드 시스템의 목적
- 속도 : 개발자가 명령 하나로 빌드를 수행하고 몇 초 안에 결과 바이너리를 얻을 수 있어야 합니다.
- 정확성 : 소스 파일과 기타 입력 데이터가 같다면 모든 개발자가 어떤 컴퓨터에서 빌드하더라도 항상 동일한 결과를 내어줘야 합니다.
개발자 한 명이 최대 1~2주 동안 몇백 줄 정도의 코드를 작성하는 프로젝트라면 컴파일러 하나면 충분합니다. 스크립트를 이용하면 조금 더 큰 프로젝트도 가능합니다. 하지만 여러 명의 개발자와 여러 머신이 동원되기 시작하면 간단한 방식으로는 더 이상 지탱할 수 없으므로 제대로 된 빌드 시스템에 투자해야 합니다.
태스크 기반 빌드 시스템
셸 스크립트가 기본적인 태스크 기반 빌드 시스템의 좋은 예
태스크 기반 빌드 시스템의 어두운 면
- 빌드 단계들을 병렬로 실행하기 어렵다.
이론적으로는 몇 개의 빌드 단계를 병렬로 실행할 수 있습니다. 하지만 태스크 기반 시스템에서는 병렬로 실행해도 문제 될 게 없어 보이는 태스크들마저 그렇게 하지 못하는 경우가 허다합니다.
- 증분 빌드를 수행하기 어렵다.
좋은 빌드 시스템은 작은 변경으로 전체 코드베이스를 처음부터 다시 빌드하지 않도록 증분 빌드를 수행해 줍니다. 많은 태스크가 단순히 일련의 소스 파일을 가져와서 컴파일러를 실행해 바이너리 파일들을 생성해 줍니다. 따라서 변경되지 않은 소스 파일들은 다시 컴파일할 필요가 없죠. 하지만 추가 정보 없이는 빌드 시스템이 변경 여부를 확신할 수 없습니다.
- 스크립트를 유지보수하고 디버깅하기 어렵다.
태스크 기반 빌드 시스템에 따라오는 빌드 스크립트 자체가 관리하기 어렵습니다.
태스크 기반 프레임워크에서는 성능, 정확성, 유지보수성 문제를 한꺼번에 해결할 수 있는 방법이 없습니다.
아티팩트 기반 빌드 시스템
시스템에게 '무엇'을 빌드할지 정해줄 수 있지만 '어떻게'는 시스템이 알아서 하도록 맡기는 것.
- 외부 의존성 명확히 드러내기
빌드 시스템에서 주의해야 할 문제가 아직 하나 남았습니다. 필요한 의존성을 직접 빌드하지 않고 외부에서 다운로드해야 하는 일이 많다는 것.
의존성 변경은 의식적으로 진행해야 하지만 중앙에서 한 번만 이루어져야 합니다. 개별 엔지니어가 관리하거나 시스템에 의해 자동으로 이뤄지게 두면 안 됩니다.
Bazel을 포함한 일부 빌드 시스템은 외부 의존성 각각의 암호화 해시를 워크스페이스 차원의 매니페스트 파일에 기록하게 하여 이 문제를 해결했습니다. Bazel은 빌드가 실행되면 캐시 해둔 의존 파일들의 실제 해시와 매니페스트에 정의된 예상 해시를 비교하여 둘이 다른 경우에만 파일을 다시 다운로드합니다.
분산빌드
단위 작업들을 여러 컴퓨터에 뿌려 빌드한 후 취합해 최종 결과를 만들어주는 기술
- 원격 캐싱
가장 단순한 분산 빌드는 원격 캐시만 이용하는 형태.
빌드를 수행하는 모든 시스템, 개발자 컴퓨터와 지속적 통합 시스템(CI) 모두 공통의 원격 캐시 서비스를 참조하는 모양새.
- 원격 실행
빌드를 하는 '실제'작업들을 여러 워커에 나눠 수행하는 기술
각 사용자의 컴퓨터에서 구동되는 빌드 도구가 중앙 빌드 마스터에 요청을 보내는 구조.
시간, 규모, 트레이드오프
빌드 시스템의 역할은 세월이 흐르고 규모가 커져도 코드를 쉽게 다룰 수 있게 해주는 것.
어떤 형태의 빌드 시스템을 이용하느냐에 따른 트레이드오프가 존재합니다.
모듈과 의존성 다루기
- 작은 모듈 사용과 1:1:1 규칙
아티팩트 기반 빌드를 구성할 때 처음 떠오르는 질문은 모듈 하나에 어느 정도의 기능을 넣어야 하느냐입니다. Bazel에서 모듈은 빌드 가등한 단위를 지정하는 타깃.
모듈 가시성 최소화
Bazel을 포함한 여러 빌드 시스템은 타깃이 가시성을 명시할 수 있게 합니다. 여기서 가시성이란 자신에게 의존할 수 있는 타깃의 범위를 지정하는 속성
의존성 관리
모듈들은 서로를 참조할 수 있어야 합니다. 그래서 코드베이스를 작은 모듈들로 나누면 많아진 모듈 사이의 의존성을 관리하는 부담이 늘어납니다.
- 내부 의존성
타깃 A가 B를 의존하고 B는 다시 공통 라이브러리인 C를 의존합니다. 이때 A는 C가 정의한 클래스를 사용할 수 있을까요?
문제 될 게 없습니다. (하지만) 날이 갈수록 의존 관계가 더 복잡하게 얽혀서 구글의 빌드가 느려지기 시작했다.
Blaze에 '엄격한 전이 의존성 모드'를 도입하여 이 문제를 해결했습니다. 문제의 의존성을 자동으로 추가할 수 있는 셸 명령어를 오류 메시지에 덧붙여 뿌려줍니다.
'엄격한 전이 의존성'을 적용하는 데도 당연히 트레이드오프가 따랐습니다. 암묵적으로 딸려 들어오던 공통 라이브러리들이 곳곳에 명시되어 빌드 파일이 더 거대해졌습니다.
- 외부 의존성
수동으로 버전을 관리할 경우 아티팩트 리포지터리에서 다운로드할 버전을 빌드 파일에 명시해야 합니다. 자동으로 관리할 때는 소스 파일에 호환 버전의 범위를 명시하고, 빌드 시스템이 범위 안에서 가장 최신 버전을 다운로드해 줍니다.
CHAPTER 19 구글의 코드 리뷰 도구
코드 리뷰의 가장 큰 목적은 코드베이스의 가독성과 유지보수성 개선인데, 리뷰 프로세스가 뒷받침해 줘야 가능한 이야기.
구글 자체 시스템 Critique을 예로 삼아 어떻게 해야 성공적인 코드 리뷰 도구를 도입할 수 있는지 알아보겠습니다.
코드 리뷰 도구 원칙
Critique의 가이드 원칙
- 간결성
Critique의 UI는 불필요한 선택을 줄여 코드 리뷰를 쉽게 진행할 수 있는 매끄러운 인터페이스 제공
- 신뢰 제공
코드 리뷰는 다른 이의 일을 늦추는 게 아니라 힘을 보태주는 활동
- 익숙한 소통 방식
복잡하고 철저한 형식과 규약을 요구하기보다는 변경에 대한 의견을 사용자가 익숙한 방법으로 제시할 수 있도록 한다
-워크플로 통합
웹 기반 코드 편집 도구에서 곧바로 편집할 수 있다.
CHAPTER 20 정적 분석
'프로그램을 실행하지 않은 채로' 소스 코드를 분석하여 버그나 안티패턴등의 잠재적인 문제를 찾아내는 것
정적 : 프로그램을 실행하지 않고 소스 코드를 분석
동적 : 프로그램을 실행하여 분석
Tricorder : 구글의 정적 분석 플랫폼
실패작들과 크게 다른 점은 사용자에게 가치 있는 결과만을 제공한다.
구글의 주 코드 리뷰 도구인 Critique에 통합되어 Critique의 디프 뷰어에 회색 댓글 상자로 경고를 표시
CHAPTER 21 의존성 관리
우리가 통제하지 못하는 라이브러리, 패키지, 그 외 의존성들의 네트워크를 관리하는 일'
소스 관리와 의존성 관리
소스 관리와 의존성 관리는 '이 하위 프로젝트의 개발/업데이트/관리를 우리 조직이 통제하는가?'라는 질문으로 구분 지을 수 있다.
의존성 관리 : 리포지터리, 목표, 개발 프로세스를 팀마다 다르게 가져가는 경우, 이 팀들이 생산하는 코드끼리의 연동과 조율
소스 관리 : 조직이 크더라도 단 하나의 저장소에서 모든 걸 관리
'다른 조건이 모두 같다면 의존성 관리 문제보다는 소스 관리 문제를 택하라'
의존성 관리 문제보다는 소스 관리 문제가 생각하기도 훨씬 쉽고 처리 비용도 훨씬 저렴
의존성 관리가 어려운 이유
- 요구사항 충돌과 다이아몬드 의존성
libbase는 liba와 libb모두에서 쓰이며, liba와 libb는 상위 노드인 libuser가 이용할 때,
이러한 충돌 문제를 쉽게 해결하는 유일한 방법은 모두와 호환되는 더 상위 혹은 하위 버전의 라이브러리를 찾는 것뿐.
의존성 임포트하기
프로그래밍 측면에서 보면 직접 처음부터 새로 짜는 것보다 기존 인프라를 재활용하는 게 분명히 더 낫습니다.
호환성 약속
우리 의도와 상관없이 업그레이드해야만 할 경우 비용 고려
- 호환성이 얼마나 잘 지켜지나요?
- 진화가 얼마나 빠르게(크게) 이루어지나요?
- 변경 처리 방법은 무엇일까요?
- 각 버전의 지원 기간은 어떻게 되나요?
- C++
거의 무한대의 하위 호환성 제공
API 호환성뿐만 아니라 바이너리 아티팩트들과의 하위 호환성도 꾸준히 제공
- Boost
C++라이브러리인 boost는 버전 간 호환성을 보장하지 않습니다.
특정 릴리스가 운 좋게 완벽하게 안정적이라서 많은 프로젝트에서 사용하기에 적합할 수 있습니다만, 다른 버전과의 호환성은 우선순위가 높지 않습니다.
임포트 시 고려사항
필요한 기능을 제공하는지 확인했고 숨겨진 보안 취약점이 없다고 가정한다면 같은 기능을 직접 새로 구현하는 것보다 이미 있는 것을 재사용하는 게 당연히 저렴합니다. 예외는 거의 없습니다.
'소프트웨어 엔지니어링'으로 발을 옮기는 순간 똑같은 의존성들이 미묘하게 더 비싸집니다.
의존성 자체에 대한 질문들
- 여러분이 실행해 볼 수 있는 테스트가 딸려있는 프로젝트인가요?
- 테스트는 모두 통과하나요?
- 의존성 제공자는 누구인가요? C++표준 라이브러리나 자바의 Guava 라이브러리를 사용하는 것과 깃허브나 npm에서 임의의 프로젝트를 선택해 사용하는 것은 매우 다른 이야기입니다.
- 지향하는 호환성 정책은 어떠한가요?
- 앞으로 어떤 분야나 용도를 지원해 나갈 것인지 자세히 설명하고 있나요?
- 얼마나 인기 있는 프로젝트인가요?
- 언제까지 이용할 건가요?
- 파괴적인 변경이 얼마나 빈번하게 행해지고 있나요?
의존성 임포트하기 @구글
구글 프로젝트들이 이용하는 의존성들의 압도적 다수를 구글이 직접 개발
설계상 소스코드 버전관리에 해당
(이론상의) 의존성 관리 ★
'외부에서 가져온 혹은 완벽하게 통제할 수 없는 코드는 어떻게 관리하나요? 업데이트는 어떻게 하고, 세월과 함께 변화하는 의존 관계는 어떻게 관리하나요?'
안정적인 의존성 관리 체계란 시간과 규모 모든 면에서 유연해야 합니다.
의존성 관리 해법 네 가지
- 변경 불가(정적 의존성 모델)
애초에 변경 자체를 허용하지 않으면 기존 의존성 때문에 불안해할 일이 사라집니다. 가장 간단한 방법.
API변경, 기능(동작) 변경 아무것도 안됩니다.
- 유의적 버전(SemVer)
semantic versioning, 숫자 세 개(메이저, 마이너, 패치), 가장 대표적인 방법.
메이저 : API가 변경되어 의존성을 이용하던 기존 코드를 깨뜨릴 수 있음
마이너 : 순수하게 기능 추가만 있음(기존 코드를 깨뜨리지 않음)
패치 : API에 영향을 주지 않는 내부 구현 개선과 버그 수정
모든 버전 요구사항을 충족하는 의존성 버전을 찾는 행위를 버전선택, 만족스러운 버전 조합이 네트워크에 존재하지 않는 상황을 의존성 지옥이라고 합니다.
- 하나로 묶어 배포하기
애플리케이션 구동에 필요한 의존성들을 모두 찾아서 애플리케이션과 함께 배포하는 방법
- 헤드에서 지내기
트렁크 기반 개발을 의존성 관리 영역까지 확장한 것
특히 최근에 boost의 버전을 뭘로 택하느냐에 대한 시행착오가 며칠이나 있었다^_T.. GLIBC와 서드파티와 안 맞는 게 34305848개.. 의존성 지옥 상황에 놓일 뻔했다.
유의적 버전의 한계
현시점까지 업계 표준 의존성 관리는 바로 유의적 버전입니다.
하지만 한계가 존재합니다.
- 지나치게 구속할 수 있다
실제로 라이브러리 하나에서 제공하는 인터페이스들 모두가 서로 연결되어 있는 경우는 거의 없습니다.
필요 이상으로 버전을 높여서든 SemVer 숫자를 충분히 세밀하게 적용하지 못해서든, SemVer가 과도하게 구속한다면 자동 패키지 관리자와 SAT 솔버가 의존성을 업데이트할 수 없다고 말할 것입니다.
-확실하지 않은 약속일 수 있다.
SemVer의 패치 버전은 내부 구현만 달라져서 이론적으로는 '안전한'변경, 하이럼의 법칙과 완전히 반대되는 아이디어.
-버전업 동기
메이저 버전업을 하지 못하도록 위축시키는 요인
호환성에 민감한 프로젝트는 오랜 기간 메이저 버전업을 하지 않음.
자원이 무한할 때의 의존성 관리
현재 업계가 SemVer에 의지하는 이유 3가지
- 내부 정보만 있으면 됩니다.(API 제공자가 다운스트림 사용자가 어떻게 이용하는지 알 필요 없다)
- 충분한 테스트를 수행할 컴퓨팅 자원, 테스트 결과를 모니터링해 줄 CI시스템이 존재하지 않아도 됩니다.
- 관행입니다.
의존성 내보내기
오픈 소스로 공개했는데 조직에 해를 끼치는 경우
- 구현 품질이 떨어지거나 제대로 관리하지 못하면 조직의 평판을 떨어뜨립니다.
- 동기화를 유지할 수 없다면 선의의 릴리스가 엔지니어링 효율을 떨어뜨릴 것입니다.
gflags프로젝트는 담벼락 너머로 던지기(내던지듯 넘긴 후 더는 책임지지 않는 개발 방식을 말함) 릴리스가 될 운명이기도 했다.
핵심 정리
소프트웨어 엔지니어링 프로젝트에서 의존성 추가는 공짜가 아닙니다. 의존성 네트워크에서 신뢰 관계를 지속하는 문제는 매우 복잡합니다. 여러분의 조직에 의존성을 임포트 할 때는 장기 지원 비용까지 고려해서 신중하게 결정해야 합니다.
SemVer 기반 패키지 관리에 최소 버전 선택 전략을 가미하면 충실성이 올라갑니다. 버전업의 위험성을 추정하는 일은 여전히 사람에 의지하지만, API제공자가 테스트한 구성과 소비자가 사용할 구성이 비슷해질 가능성이 확실히 높아집니다.
단위 테스트, 지속적 통합, (저렴한) 컴퓨팅 자원이 의존성 관리를 이해하고 처리하는 방식에 변화를 가져올 수 있습니다.
의존성을 제공하는 일 역시 공짜가 아닙니다. 담벼락 너머로 던지고 잊어버리는 방식은 여러분의 평판을 떨어뜨리고 호환성 문제를 일으키기 쉽습니다.
CHAPTER 23 지속적 통합
지속적 통합 continuous integration(CI)
팀원들이 작업 결과를 자주 통합하는 소프트웨어 개발 방식.
통합할 때마다 자동 빌드하여 통합 오류를 빠르게 찾아낸다.
-> 가능한 한 조기에 자동으로 발견하는 것
지속적 통합의 핵심 개념
- 빠른 피드백 루프
버그는 발견하는 시점이 늦을수록 처리 비용이 거의 기하급수적으로 증가
- 자동화
CI는 빌드와 릴리스 프로세스를 자동화.
지속적 빌드와 지속적 배포라고 한다.
- 지속적 빌드
가장 최근의 코드 변경을 헤드에 통합한 다음 자동으로 빌드와 테스트를 수행합니다.
- 지속적 배포
최신 코드와 설정 정보를 가져와서 릴리스 후보를 만들어내는 작업.
자동화된 프로세스가 만든, 서로 밀접하게 관련된 요소들로 구성된 배포 가능한 단위. 지속적 빌드를 통과한 코드, 설정 정보, 기타 의존성들을 조합해 만든다.
CHAPTER 24 지속적 배포
- 속도는 팀 스포츠입니다.
- 변경은 격리해 평가해야 합니다.
- 현실을 직시하세요.
- 쓰일 기능만 배포해야 합니다.
- 원점으로 회귀하세요.
- 빠를수록 안전합니다.
CHAPTER 25 서비스형 컴퓨트
열심히 코드를 작성했다면 이를 실행해 줄 하드웨어가 필요하다. 이 하드웨어를 구입하거나 임대
서비스형 컴퓨트(Compute as a Service(Cass))의 본질
힘든 일은 자동으로
- 간단한 자동화
먼저 하나의 머신에 바이너리를 배포하고 시작시키는 과정을 셸 스크립트로 쉽게 자동화할 수 있습니다.
각 머신을 모니터링하는 일도 자동화할 수 있습니다.
이상이 감지되면 SSH로 해당 머신에 접속하여 프로세스가 살아 있는 경우라면 프로세스를 종료하고 다시 시작해 문제를 해결합니다.
->장애 여부를 사람이 눈으로 모니터링하는 대신 각 머신에 이상 감지용 에이전트를 두고 장애 시 자동으로 프로세스를 종료시킵니다.
->프로세스를 다시 실행하기 위해 머신에 로그인할 필요 없이 전체 실행을 'while true; do run && break; done' 셸 스크립트로 감싸줍니다.
- 스케쥴링 자동화(조건)
사용 가능한 머신의 전체 목록을 알고 있습니다.
요청 시 미사용 머신을 선택하여 제품 바이너리를 자동으로 배포합니다.
읽고 나서
발매된 지 얼마 안 됐을 때부터 유명해서 모르는 사람이 적은 책이라는 게 놀랍다.
700페이지가 넘는데 다들 제대로 읽었을까?
IT 지식을 높게 요구하는 책은 아니라서 '구글'이라는 회사와 그 안의 조직, 돌아가는 문화에 대해 알고 싶으면 추천합니다.
하지만 개발 관련 지식이 1도 없으면 읽다가 포기하거나 반 정도밖에 관심이 없을 것 같지만요..
제일 흥미를 갖고 읽었던 챕터는 빌드시스템과 의존성이었다.
빌드 시스템은 적지만 이직을 하며 기업마다 달랐고, 현재의 조직에서도 변경된 적이 있었기 때문에 구글은 어떻게 적용했을지 궁금했다.
의존성은 업무를 하면서도 종종 부딪치면서 좋은 방법을 고민했던 파트라 꼼꼼하게 읽은 기억이다. 말 그대로 다른 라이브러리와의 의존성이나, 이 챕터에서 다루는 다른 팀과 공통으로 쓰는 API라든가.. 의존성지옥까지..
'도서 리뷰' 카테고리의 다른 글
| [독서모임] 지적 대화를 위한 넓고 얕은 지식 1 (2) | 2024.07.29 |
|---|---|
| [독서모임] 신더 (0) | 2024.07.28 |
| [독서모임] 천 개의 파랑 (0) | 2024.04.20 |
| [독서모임 9주] 그리고 아무도 없었다 (0) | 2024.03.03 |
| [2월]혼자 공부하는 컴퓨터 구조+운영체제 (0) | 2024.03.01 |
