DevOps & Infrastructure

레이어링의 덫: 왜 우리는 소프트웨어를 너무 복잡하게 만드는가

우리는 래퍼를 위한 래퍼를 추가하며 추상화 레이어에 익사하고 있습니다. 원래의 문제는요? 이미 오래전에 잊혔습니다. 이제 그 대가에 대해 이야기할 때입니다.

{# Always render the hero — falls back to the theme OG image when article.image_url is empty (e.g. after the audit's repair_hero_images cleared a blocked Unsplash hot-link). Without this fallback, evergreens with cleared image_url render no hero at all → the JSON-LD ImageObject loses its visual counterpart and LCP attrs go missing. #}
매우 겹겹이 쌓인 투명한 레이어들의 시각적 은유, 가장 아래에는 작고 거의 보이지 않는 문제가 있습니다.

Key Takeaways

  • 소프트웨어 개발은 점점 더 과도한 추상화 레이어에 발목 잡혀 원래의 문제를 모호하게 만들고 있습니다.
  • 레이어링의 역사적 의도는 복잡성을 격리하는 것이었지만, 문제는 문제를 연기하고 지연시키는 방향으로 퇴보했습니다.
  • 이러한 레이어링 추세는 독점 소프트웨어에 국한되지 않으며, 오픈소스 생태계 내에서도 만연한 문제입니다.
  • 과도한 추상화의 대가에는 엔지니어 생산성 감소, 시스템 비효율성, 그리고 근본적인 명확성 상실이 포함됩니다.
  • 이를 해결하려면 새로운 추상화를 지속적으로 추가하는 것보다 단순화와 코드 제거를 우선시해야 합니다.

자, 이건 추상적인 개념에 대한 이야기가 아닙니다. 여러분의 화요일에 대한 이야기입니다. 6밀리초 걸릴 요청이 어떻게 800밀리초씩이나 걸리는지 추적하는 시니어 엔지니어에 대한 이야기입니다. 큐블릿(kubelet)이 도대체 뭔지조차 모르겠다고 화면 가득한 YAML만 바라보는 주니어 엔지니어에 대한 이야기입니다. 이건 우리가 시스템을 너무 계층화하고, 추상화로 너무 많이 포장해서, 애초에 실제 문제가 무엇이었는지 아무도 기억하지 못하게 되는 상황에 대한 이야기입니다.

우리는 레이어를 집어 듭니다. 이건 보편적인 반사 작용입니다. 코드. 인프라. 프로세스. 조직. API를 클라이언트로 감쌉니다. 클라이언트를 어댑터로 감쌉니다. 어댑터를 서비스 객체로 감쌉니다. 서비스 객체를 팩토리로 감쌉니다. 배포는 파이프라인을 얻습니다. 파이프라인은 오퍼레이터를 얻습니다. 오퍼레이터는 플랫폼을 얻습니다. 플랫폼은 포털을 얻습니다. 팀은 부족을 얻습니다. 부족은 챕터를 얻습니다. 탁월함 센터. 석고가 모든 상처에 맞습니다. 상처 자체는요? 결코 검토되지 않습니다.

이 충동은 너무 뿌리 깊어서 대안은 거의 등록조차 되지 않습니다. 그저 감싸는 대신 근본적인 것을 제거할 수는 없을까요? 거의 묻지 않습니다. 그것을 만든 팀은 옆방에 있습니다. 프로젝트는 지난 분기 검토에 있습니다. 그것을 파헤쳐야 할 엔지니어는 또 다른 래퍼로 더 깔끔하게 닫히는 티켓 13개를 가지고 있습니다. 그래서 래퍼가 들어갑니다. 1년 후, 그것은 래퍼를 얻습니다.

왜 이런 일이 발생했을까요? 격리의 신화

레이어드 아키텍처는 고귀한 기원을 가지고 있었습니다. 1968년 다익스트라의 아이디어죠. 복잡성을 제한하기 위한 규율 잡힌 레이어링. 각 레이어는 정의된 인터페이스를 제시했습니다. 전체 스택을 머릿속에 넣지 않고도 하나의 레이어에 대해 추론할 수 있었습니다. 훌륭했죠. 지금도 그렇습니다.

4년 후 파르나스는 정보 은닉(Information Hiding)을 제시했습니다. 변하는 것을 안정적인 인터페이스 뒤에 숨기는 것. 한 곳에서의 변화가 모든 것을 망가뜨리지 않도록 하는 것입니다. 레이어는 이것의 적용이었습니다. 의도는 복잡성을 격리하는 것이었습니다. 연기하는 것이 아니라.

파르나스와 3세대 클라우드 추상화 사이 어딘가에서, 동사가 바뀌었습니다. 격리하는 것이 연기하는 것이 되었습니다. 한때 누수를 막았던 레이어는 이제 아래의 지저분한 부분을 봐야 하는 순간을 연기하기 위해서만 존재합니다. 쿠버네티스 오퍼레이터는 안정적인 추상화를 숨기는 것이 아니라, 아무도 읽고 싶어 하지 않는 YAML을 숨깁니다. 재시도 데코레이터는 깔끔한 인터페이스를 제한하는 것이 아니라, 영원히 고장 난 상위 스트림 서비스를 덮어씌웁니다. ORM은 데이터베이스를 추상화하는 것이 아니라, 실제 쿼리가 무엇이어야 하는지에 대한 대화를 연기합니다.

어휘는 살아남았지만, 그 규율은 사라졌습니다.

복잡성의 대가: 단순히 느려지는 것 이상

소프트웨어 진화에 관한 레만의 두 번째 법칙: 명시적인 작업 없이는 복잡성이 증가한다는 것입니다. 몇 안 되는 문장이 더 잘 숙성되었습니다. 그는 이를 열역학에 비유했습니다. 엔트로피는 기본값입니다. 질서는 에너지를 필요로 합니다. 그리고 그 에너지는요? 새로운 기능을 배송하지 않고, 티켓을 닫지 않고, 아키텍처 검토를 위해 멋진 다이어그램을 남기지 않기 때문에 아무도 자금을 지원하지 않는 작업입니다.

우리는 방어적인 코드 경로가 증식되는 상황에 놓입니다. 모든 API 호출에는 재시도가 있습니다. 모든 값에는 null 검사가 있습니다. 모든 캐시에는 무효화 논리가 있습니다. 필 칼튼은 두 가지 어려운 것이 있다고 말했습니다. 캐시 무효화와 이름 짓기입니다. 우리는 첫 번째 것을 우리의 기본 아키텍처 패턴으로 부지런히 만들었고, 결과 값을 담는 변수 이름에는 여전히 동의하지 못하고 있습니다.

비용은 캐시만이 아닙니다. 바로 사람입니다. 시니어 엔지니어는 아침을 6밀리초가 800밀리초가 된 이유를 추적하는 데 보냅니다. 그녀는 재시도 데코레이터, 어댑터 클래스, 서비스 메시 사이드카, 2023년부터 건드리지 않은 폴백 전략을 탐색합니다. 바닥에는요? 인덱스가 누락된 데이터베이스 쿼리입니다. 인덱스가 들어갑니다. 800밀리초가 6밀리초로 줄어듭니다. 재시도 데코레이터는 그대로 남습니다. 어댑터도 그대로 남습니다. 사이드카도 그대로 남습니다. 그것들을 제거하는 것은요? 또 다른 분기 작업입니다. 하지만 그 분기에는 다른 계획이 있습니다.

잃어버린 것은 효율성만이 아닙니다. 명확성입니다. 시스템에 대해 추론하는 능력입니다. 작동하는 것을 만드는 기본적인 즐거움, 즉 영원히 디지털 덕트 테이프와 난해한 구성으로 유지되는 것을 관리하는 것이 아니라 말입니다. 이것은 단순한 기술적 문제가 아니라 문화적인 문제입니다. 우리는 새로운 추상화로 포장된 기능을 배송하는 것—진행의 외양—을 진정한 엔지니어링의 어렵고 빛나지 않는 작업, 즉 이해하고, 단순화하고, 제거하는 것보다 더 높게 평가했습니다.

원하는 대로 작동하지 않으면, 위에 레이어를 추가합니다.

이것이 문제입니다. 우리는 원래 것이 고장 났는지 묻지 않습니다. 그냥 덮어버립니다. 그러고는 석고에도 석고가 필요하다고 불평합니다.

대안이 있을까요? 물론입니다. 어려운 대화, 리팩토링, 그리고 때로는 가장 빠른 길은 뒤로 돌아가는 것—매우 편리하게 숨겨졌던 핵심 문제로 돌아가는 것—임을 인정하는 것이 필요합니다.

우리는 스스로에게 물어야 합니다. 시스템을 구축하고 있는 걸까요, 아니면 연기된 결정의 기념비를 구축하고 있는 걸까요? 왜냐하면 지금은 후자처럼 느껴지기 때문입니다.

이게 오픈소스의 용도인가?

오픈소스가 해독제라고 기대할 수 있습니다. 투명성이 지배하고, 레이어가 보이고, 근본적인 코드를 검사하고 이해할 수 있는 곳이죠. 때로는 그렇습니다.

하지만 오픈소스에서도 같은 압력이 적용됩니다. 인기 있는 프로젝트는 복잡한 생태계가 됩니다. 기여하려는 개발자는 종종 같은 선택에 직면합니다. 기존 래퍼를 해킹하거나, 수개월 동안 깊은 내부를 이해하여 레이어를 제거해야 합니다. 물론 가장 쉬운 길은 또 다른 래퍼입니다. 오퍼레이터의 근본적인 로직을 리팩토링하는 것보다 오퍼레이터에 새로운 구성 플래그를 추가하는 것이 더 쉽습니다.

이것은 흥미로운 아이러니를 만듭니다. 우리는 오픈소스의 검사 가능성을 옹호하지만, 그것을 접근 가능하게 만드는 도구 자체가 종종 불투명해집니다. 기계가 20개 레이어 깊이라면, 기계를 이해한다는 약속은 무너집니다.

패턴은 보이지 않습니다. 보편적이기 때문입니다. 우리는 코드, 인프라, 프로세스, 조직에서 그렇게 합니다.

이 진술은 출처 자료에서 발췌한 것으로, 암울한 현실입니다. 이것은 버그가 아니라, 우리의 집단적 접근 방식의 특징입니다. 도구는 오픈 소스일 수 있지만, 진정한 이해로 가는 길은 점점 더 봉쇄되고 있습니다.

이것이 미래에 무엇을 의미할까요? 더 많은 복잡성. 더 많은 혼란. 더 많은 엔지니어가 새로운 길을 개척하는 대신 매듭을 푸는 데 하루를 보낼 것입니다. 물론, 우리가 의식적으로 단순화라는 어려운 작업을 받아들이기로 결정하지 않는 한 말입니다. 이는 코드 추가만큼이나 코드 제거를 중요하게 여기는 것을 의미합니다. 단순히 기능 속도뿐만 아니라 명확성과 감소에 초점을 맞춘 프로젝트에 자금을 지원하는 것을 의미합니다.

팔기 어렵습니다. 하지만 대안은 엔지니어들이 스스로 만든 복잡성의 노예가 되어, 기계 속의 유령을 영원히 쫓는 소프트웨어 환경입니다.


🧬 관련 통찰

Written by
Open Source Beat Editorial Team

Curated insights, explainers, and analysis from the editorial team.

Worth sharing?

Get the best Open Source stories of the week in your inbox — no noise, no spam.

Originally reported by Dev.to