한 줄 정의

마이크로커널 아키텍처

최소한의 기능만 가진 코어 시스템 에, 독립형 플러그인 컴포넌트 를 꽂아 기능을 확장하는 모놀리스 스타일입니다.

쉽게 말하면

VS Code를 떠올리면 됩니다. 갓 설치한 직후의 VS Code는 텍스트 편집·파일 탐색·검색 정도만 하는 가벼운 에디터입니다. 언어별 인텔리센스, 디버거, Git 그래프, 테마, 리모트 개발 같은 기능은 전부 확장 프로그램(Extension) 이 붙으면서 채워집니다. VS Code의 코어 시스템은 의도적으로 얇게 유지되고, 실제 “IDE다운” 경험은 마켓플레이스의 플러그인들이 만들어냅니다.

코어 시스템은 “모든 사용자에게 공통되는 기본 흐름”만 담고, 고객·지역·컨텍스트마다 달라지는 맞춤 로직은 전부 플러그인으로 격리합니다. 새로운 변형이 필요하면 코어를 건드리는 대신 플러그인 하나를 추가하고 레지스트리를 갱신하면 끝입니다.

왜 이렇게 설계했는가?

  • 해결하는 문제: 커스터마이징 이 본질인 도메인을 모놀리스로 유지하면서 확장성·적응성을 확보해야 할 때의 구조입니다. 미국 보험사의 주(state)별 규칙, 국제 배송업체의 나라별 법·물류 변형, 세법 양식처럼 “공통 뼈대 + 다양한 변형” 문제에 딱 맞습니다.
  • 이게 없다면: 코어 시스템이 if (deviceID.equals("iPhone6s")) { ... } else if (...) { ... } 같은 거대한 분기문으로 부풀어 오릅니다. 순환 복잡도(cyclomatic complexity)가 폭발하고, 새 기기·새 규칙을 추가할 때마다 코어의 핵심 로직을 건드려 회귀 테스트 비용이 쌓입니다.

토폴로지

마이크로커널은 코어 시스템플러그인 컴포넌트 라는 두 종류의 요소만으로 이뤄진 비교적 단순한 모놀리스입니다.

flowchart LR
    subgraph Monolith["애플리케이션"]
        direction LR
        P1[플러그인] -.- C[코어 시스템]
        P2[플러그인] -.- C
        P3[플러그인] -.- C
        P4[플러그인] -.- C
        P5[플러그인] -.- C
        P6[플러그인] -.- C
    end

코어 시스템은 애플리케이션의 일반적인 처리 흐름을, 플러그인 컴포넌트는 고객·지역·컨텍스트마다 달라지는 특화된 처리를 담당합니다.

애플리케이션 기능들이 이렇게 격리되면서 확장 능력·적응성이 향상되고 맞춤형 처리 로직이 가능해집니다.

핵심 내용

코어 시스템

공식적으로는 시스템을 실행하는 데 필요한 최소한의 기능성 으로 정의됩니다. 이클립스의 코어 시스템은 파일 열기, 텍스트 변경, 파일 저장 같은 기초적인 텍스트 에디터에 불과하지만, 거기에 플러그인들을 꽂으면 IDE가 되는 식입니다.

좀 더 실용적인 정의는 정상 경로(happy path) 입니다. 맞춤형 처리가 거의 없는, 애플리케이션의 일반적인 처리 흐름이 코어에 해당합니다. 다시 말해 마이크로커널은 순환 복잡도 를 코어에서 떼어내 플러그인에 밀어 넣는 구조입니다.

분할 방식에 따른 코어 구현

코어 시스템 자체는 크기와 복잡도에 따라 계층형으로 구현하거나, 모듈형 모놀리스로 구현할 수 있습니다.

분할 방식설명예시
계층형 코어 (기술적 분할)표현/비즈니스/영속성 계층으로 쪼갠 전통적 구조소규모·중규모 제품 기반 앱
모듈형 코어 (도메인 분할)도메인 서비스들을 조립해 코어를 구성. 각 도메인 서비스가 해당 도메인용 플러그인들을 품음고잉 그린 앱의 Payment Processing(신용카드/PayPal/기프트카드 결제 도메인)

계층형 코어 (기술적 분할 방식)

flowchart TB
    subgraph 코어["코어 시스템 (계층형)"]
        direction TB
        L1[표현 계층]
        L2[비즈니스 계층]
        L3[영속성 계층]
        L1 --- L2 --- L3
    end
    P1[플러그인] -.- 코어
    P2[플러그인] -.- 코어
    P3[플러그인] -.- 코어
    P4[플러그인] -.- 코어

모듈형 코어 (도메인 분할 방식)

flowchart TB
    subgraph 코어["코어 시스템 (모듈형)"]
        direction LR
        D1[도메인 컴포넌트]
        D2[도메인 컴포넌트]
        D3[도메인 컴포넌트]
    end
    P1[플러그인] -.- 코어
    P2[플러그인] -.- 코어
    P3[플러그인] -.- 코어
    P4[플러그인] -.- 코어
표현 계층의 위치

코어의 표현(presentation) 계층 은 코어 내부에 포함하거나, 백엔드와 분리된 별도 UI로 구현할 수 있으며, 더 나아가 UI 자체도 다시 마이크로커널 스타일로 구성할 수 있습니다. 세 가지 변형은 다음과 같습니다.

1. 내장된 UI (단일 배포 단위) — UI가 코어 내부에 포함된 기본형

flowchart TB
    subgraph Monolith["애플리케이션"]
        UI[사용자 인터페이스]
        P1[플러그인] -.- C[코어 시스템]
        P2[플러그인] -.- C
        P3[플러그인] -.- C
        P4[플러그인] -.- C
        UI --> C
    end

2. 별도의 UI (다중 배포 단위) — UI와 백엔드가 각각 독립 배포되는 구조

flowchart TB
    subgraph UIApp["UI 배포 단위"]
        UI[사용자 인터페이스]
    end
    subgraph Backend["백엔드 배포 단위"]
        P1[플러그인] -.- C[코어 시스템]
        P2[플러그인] -.- C
        P3[플러그인] -.- C
        P4[플러그인] -.- C
    end
    UI --> C

3. 별도의 UI (다중 배포 단위, 모두 마이크로커널) — UI 자체도 마이크로커널로 구성

flowchart TB
    subgraph UIApp["UI 배포 단위 (마이크로커널)"]
        UP1[플러그인] -.- UC[사용자 인터페이스<br/>코어 시스템]
        UP2[플러그인] -.- UC
        UP3[플러그인] -.- UC
    end
    subgraph Backend["백엔드 배포 단위 (마이크로커널)"]
        P1[플러그인] -.- C[코어 시스템]
        P2[플러그인] -.- C
        P3[플러그인] -.- C
    end
    UC --> C

브라우저가 확장 프로그램(UI 플러그인)을 로드하고, 백엔드 코어 시스템이 또 다른 플러그인 집합을 관리하는 이중 마이크로커널 이 대표적인 예입니다.

플러그인 컴포넌트

플러그인은 코어 기능성을 개선하거나 확장 하는 독립형 구성요소로, 특화 처리·추가 기능·맞춤형 코드를 담습니다. 변동성(volatility; 변경 빈도)이 높은 코드를 격리하는 데 쓰이므로 이상적으로는 플러그인 간 의존성이 없어야 합니다.

고잉 그린 예시로 본 플러그인의 가치

전자제품 재활용 애플리케이션에서 기기마다 평가 규칙을 코어에 직접 두면 다음처럼 됩니다.

public void assessDevice(String deviceID) {
    if (deviceID.equals("iPhone6s")) {
        assessiPhone6s();
    } else if (deviceID.equals("iPad1"))
        assessiPad1();
    } else if (deviceID.equals("Galaxy5"))
        assessGalaxy5();
    } else ...
        ...
    }
}

플러그인 컴포넌트로 격리하면 이렇게 바뀝니다.

public void assessDevice(String deviceID) {
    String plugin = pluginRegistry.get(deviceID);
    Class<?> theClass = Class.forName(plugin);
    Constructor<?> constructor = theClass.getConstructor();
    DevicePlugin devicePlugin =
        (DevicePlugin)constructor.newInstance();
    devicePlugin.assess();
}

코어는 “레지스트리에서 플러그인을 찾아 호출한다”는 제네릭(generic) 흐름 만 담당하고, 기기별 복잡한 평가 규칙은 전부 독립형 플러그인 안으로 들어갑니다. 새 기기 지원은 플러그인 추가 + 레지스트리 갱신으로 끝납니다.

점대점 연결: 컴파일 기반 vs 런타임 플러그인

플러그인-코어 연결은 기본적으로 점대점(point-to-point) 입니다. 플러그인 진입점 클래스의 메서드 호출이 ‘파이프’ 역할을 합니다. 연결 시점에 따라 두 종류로 나뉩니다.

종류연결 시점장점단점대표 프레임워크
런타임 플러그인실행 시점코어·다른 플러그인 재배포 없이 추가/제거 가능프레임워크 의존OSGi, Penrose, Jigsaw, Prism(.NET)
컴파일 기반 플러그인소스 코드 수준관리 단순플러그인 수정·추가 시 모놀리스 전체 재배포-
플러그인을 어떻게 패키징하는가?

세 가지 선택지가 있습니다.

  1. 공유 라이브러리 (JAR, DLL, 루비 젬): 기기별 플러그인을 assessment_iphone6s.jar, assessment_galaxy5.jar처럼 이름에 기기명을 박아 배포합니다.
  2. 패키지 / 이름공간: 동일 코드베이스 내에서 app.plug-in.<도메인>.<컨텍스트> 패턴으로 조직화합니다. 예: app.plugin.assessment.iphone6s. plug-in 노드는 자기완결 규칙을 상기시키고, 도메인·컨텍스트 노드는 그룹화와 탐색을 돕습니다.
  3. 원격 서비스 / REST: 플러그인을 독립 서비스(심지어 마이크로서비스)로 구현하고 REST나 메시징으로 호출합니다. 결합도가 낮아지고 확장성·처리량이 올라가며 프레임워크 없이 런타임 변경이 가능합니다.
flowchart LR
    P1[플러그인] <-->|REST| C[코어 시스템]
    P2[플러그인] <-->|REST| C
    P3[플러그인] <-->|REST| C
    P4[플러그인] <-->|REST| C

원격 플러그인은 비동기 호출까지 조합하면 반응성까지 개선할 수 있습니다. 고잉 그린이라면 “평가 시작해” 요청만 비동기로 보내고 결과는 메시징 채널로 받는 식입니다.

대신 마이크로커널이 모놀리스에서 분산 아키텍처로 바뀌어 복잡성·비용이 증가하고, 서드파티 온프레미스 제품에 끼워 팔기는 어려워집니다.

플러그인이 응답하지 않으면 요청을 완료할 수 없다는 가용성 문제도 생깁니다.

마이크로커널성의 스펙트럼

Quote

플러그인을 지원하는 모든 시스템이 마이크로커널인 건 아니지만, 모든 마이크로커널은 플러그인을 지원합니다.

시스템이 얼마나 마이크로커널에 가까운지를 마이크로커널성(microkernality) 이라 부르며, 코어에 얼마나 많은 독립형 기능이 없는지 로 결정됩니다.

flowchart LR
    L["<b>기능성 적음</b><br/>순수 마이크로커널<br/>예: 린터"] ---|"코어 시스템의<br/>기능성 / 변동성"| R["<b>기능성 많음</b><br/>풍부한 코어<br/>예: 웹 브라우저"]
  • 린터(linter): 소스를 파싱해 AST를 내놓을 뿐, 실제 검사 규칙은 플러그인이 없으면 거의 쓸모가 없습니다. 순수 마이크로커널입니다.
  • 웹 브라우저: 확장 프로그램 없이도 충분히 기능합니다. 스펙트럼의 반대 끝입니다.

코어의 변동성을 파악하는 것은 “단지 플러그인 지원 시스템”인지 “진짜 마이크로커널”인지 고를 때의 기준이 됩니다.

레지스트리

코어가 사용 가능한 플러그인과 접근 방법 을 알려면 플러그인 레지스트리 가 필요합니다. 레지스트리 항목에는 이름·데이터 계약·원격 접근 프로토콜 세부 사항 같은 정보가 담깁니다.

구현 방식은 단순한 맵부터 외부 서비스 디스커버리까지 선택할 수 있습니다.

Map<String, String> registry = new HashMap<String, String>();
static {
  //점대점 접근 예시
  registry.put("iPhone6s", "Iphone6sPlugin");
 
  //메시징 예시
  registry.put("iPhone6s", "iphone6s.queue");
 
  //REST 예시
  registry.put("iPhone6s", "https://atlas:443/assess/iphone6s");
}

규모가 커지면 아파치 주키퍼(ZooKeeper)Consul 같은 디스커버리 도구를 레지스트리로 끌어다 쓰는 것이 일반적입니다.

계약

플러그인-코어 간 계약(contract) 은 보통 플러그인 도메인 전반에 걸쳐 표준화 되어 있습니다. 자바 인터페이스·클래스, 혹은 XML/JSON/객체 형태로 구현할 수 있습니다.

public interface AssessmentPlugin {
    public AssessmentOutput assess();
    public String register();
    public String deregister();
}
 
public class AssessmentOutput {
    public String assessmentReport;
    public Boolean resell;
    public Double value;
    public Double resellPrice;
}

역할·책임의 분리

assessmentReport문자열(String) 이라는 점에 주목하세요. 보고서 세부 사항을 포맷하고 해석하는 것은 코어의 책임이 아니며, 코어는 그저 출력하거나 사용자에게 표시하기만 합니다. 역할·책임이 명확히 나눠져 있다는 뜻입니다.

서드파티 플러그인과 어댑터

어댑터 패턴으로 맞춤형 계약 흡수

서드파티가 개발한 플러그인이라면 아키텍트가 맞춤형 계약(custom contract) 을 통제할 수 없습니다. 그런 경우 플러그인마다 전용 코드를 코어에 두지 않도록, 플러그인 계약과 표준 계약(에이전트가 정한) 사이에 어댑터(adapter) 를 배치하는 것이 정석입니다.

데이터 토폴로지

마이크로커널은 보통 단일 데이터베이스(관계형)를 쓰는 모놀리스로 구현됩니다. 플러그인이 중앙 공유 DB에 직접 붙는 경우는 드뭅니다. 데이터베이스 접근은 코어의 책임이고, 플러그인은 코어에서 데이터를 전달받습니다. 결합도를 낮추기 위한 관행입니다.

flowchart LR
    DS1[(데이터 저장소)] <--- P1[플러그인]
    P2[플러그인] ---> DS2[(데이터 저장소)]
    P3[플러그인] ---> DS3[(데이터 저장소)]
    P4[플러그인] ---> DS4[(데이터 저장소)]
    P1 -.- C[코어 시스템]
    P2 -.- C
    P3 -.- C
    P4 -.- C
    C --> DB[(데이터베이스)]

다만 개별 플러그인이 자신만 접근 가능한 별도 데이터 저장소 를 가질 수는 있습니다. 기기 평가 플러그인이 자체 규칙 엔진이나 embedded DB에 평가 규칙을 담아두는 식입니다. 이 저장소는 시스템 외부에 있을 수도, 플러그인·모놀리스 배포의 일부로 내장될 수도 있습니다.

클라우드 고려 사항

기본적으로 모놀리스 아키텍처라 클라우드 선택지가 단순합니다.

접근구성평가
전체 클라우드 배포애플리케이션 전체를 컨테이너/서비스로 올림무난
데이터만 클라우드데이터 → 클라우드, 마이크로커널 → 온프레미스가능
플러그인만 클라우드코어 → 온프레미스, 플러그인 → 클라우드비권장

"플러그인만 클라우드" 접근 주의

모듈성 관점에서는 매력적으로 보이지만 반응성에 심각한 문제 를 일으킵니다. 마이크로커널은 팀이 핵심 작업흐름을 플러그인들로 구현하기 때문에 플러그인 호출이 잦고 한 번에 상당한 양의 정보가 오갑니다. 코어-플러그인 분리에서 생기는 네트워크 지연이 그대로 운영 오버헤드가 됩니다.

일반적인 위험

변동성 높은 코어 시스템

코어는 안정적이어야 한다

마이크로커널의 코어는 초기 개발 후에 가능한 한 안정적 이어야 합니다. 시스템 변화를 플러그인으로 흡수하는 게 이 스타일의 철학인데, 팀이 코어를 계속 건드리면 철학이 무너집니다.

원인은 대개 아키텍트가 코어 시스템의 변동성을 잘못 판단한 것 입니다. 처음부터 코어에 들어갈 기능과 플러그인으로 뺄 기능을 정밀하게 식별하지 않으면, 뒤늦게 큰 비용의 리팩터링으로 되돌아와야 합니다.

플러그인 의존성

전이적 의존성 충돌

마이크로커널은 플러그인들이 서로 통신하지 않고 오직 코어와만 통신할 때 가장 잘 동작합니다. “플러그인은 쓰지만 마이크로커널은 아닌” 시스템들은 대부분 의존성 없는 플러그인(dependency-free plug-in) 을 사용합니다.

이클립스 IDE처럼 복잡한 마이크로커널에서는 어쩔 수 없이 플러그인 간 의존성이 생기는데, 이 경우 전이적 의존성 충돌(transitive dependency conflict) 을 코어가 해소해야 합니다. 두 플러그인이 같은 핵심 라이브러리의 서로 다른 버전에 의존하는 순간 버전 충돌 지옥이 열립니다. 가능한 한 플러그인 간 의존성은 피해야 합니다.

거버넌스

마이크로커널에서 거버넌스의 핵심은 아키텍트가 마이크로커널 철학을 얼마나 잘 지키는지 확인하는 것 입니다.

  • 코어 시스템의 변동성 확인: 구체적 코드 검사보다는 버전 관리(version control)의 변경 빈도 를 확인하는 적합성 함수가 효과적입니다. 코어 변경 커밋이 일정 임계치를 넘으면 경고를 띄우는 식입니다.
  • 코어 시스템의 변경 속도: 코어가 얼마나 자주 바뀌는지 추적합니다.
  • 계약 테스트: 플러그인들이 서로 다른 버전의 계약을 지원하는 점진적 진화 상황에서 특히 중요합니다.
  • 토폴로지에 대한 기타 구조적 검증: 플러그인이 코어를 거치지 않고 DB에 직접 붙거나, 플러그인끼리 직접 호출하는 등의 위반을 잡아냅니다.

팀 토폴로지 고려 사항

이 아키텍처에서는 팀을 토폴로지에 따라 코어 시스템 팀과 플러그인 팀 들로 나누는 것이 가장 자연스럽습니다.

팀 유형적합도이유
스트림 정렬 팀 (기능 전담 팀)높음코어 시스템이 시스템의 핵심 기능성을 구축하는 스트림 정렬 팀에 안성맞춤입니다. 애플리케이션 유형에 따라서는 플러그인도 이 팀이 담당할 수 있습니다
활성화 팀 (역량 코칭 팀)매우 높음일부 행동방식을 플러그인으로 분리해 A/B 테스트와 실험을 진행할 수 있기 때문입니다
난해한 하위시스템 팀 (전문 도메인 팀)높음특화된 행동방식을 플러그인으로 위임할 수 있습니다. 스트림 정렬 팀은 핵심 행동방식(core behavior)에 집중하고, 분석(analytics) 같은 특별한 행동방식은 플러그인으로 격리해 별도 팀이 맡으면 됩니다
플랫폼 팀 (공통 기반 팀)적합다른 모놀리스 아키텍처와 마찬가지로 이 아키텍처의 운영 세부 사항을 담당합니다

장단점

아키텍처 특성평가
전반적인 비용매우 낮음
분할 방식기술적 / 도메인
퀀텀 개수1
단순성★★★★☆
모듈성★★★☆☆
유지보수성★★★☆☆
테스트성★★★☆☆
배포성★★★☆☆
진화성★★★☆☆
반응성★★★☆☆
확장성★☆☆☆☆
탄력성★☆☆☆☆
내결함성★☆☆☆☆

계층형 아키텍처처럼 단순성과 전반적인 비용이 주요 장점이고, 확장성·내결함성·탄력성이 주요 약점입니다. 모놀리스 배포에서 비롯된 한계입니다. 모든 요청이 개별 플러그인에 도달하려면 먼저 코어를 거쳐야 하므로 아키텍처 퀀텀은 항상 1 입니다.

도메인 분할과 기술 분할을 모두 지원

마이크로커널은 도메인 분할과 기술적 분할 모두를 지원하는 유일한 아키텍처 스타일 이라는 점에서 독특합니다. 대부분의 마이크로커널은 기술적으로 분할되지만, 강력한 도메인-아키텍처 동형성(domain-to-architecture isomorphism) 을 통해 도메인 분할도 드러납니다. 장소·클라이언트마다 설정이 달라야 하는 문제(보험 주별 규칙, 기기별 평가, 세법 양식 등)에 특히 잘 맞습니다.

테스트성·배포성·신뢰성 ★★★☆☆

기능을 독립적 플러그인으로 격리할 수 있어 평균보다 약간 높습니다. 변경 사항의 전체 테스트 범위와 배포 위험이 줄어듭니다. 플러그인을 실행 시점에 배포 하는 구조라면 이점이 더 커집니다.

모듈성·진화성 ★★★☆☆

독립적이고 자기완결적인 플러그인으로 기능을 추가·제거·변경할 수 있어 평균보다 약간 높습니다. 세법이 바뀌면 새 세금 양식을 플러그인 컴포넌트로 구현해 아무 노력 없이 추가하고, 불필요해진 양식은 플러그인만 제거하면 됩니다. 팀이 변화에 훨씬 빠르게 대응할 수 있습니다.

반응성 ★★★☆☆

마이크로커널 애플리케이션은 일반적으로 작고 대부분의 계층형 아키텍처만큼 크게 성장하지 않습니다. 불필요한 기능성을 분리해서 간소화할 수 있다는 마이크로커널의 장점은 실행 속도 향상으로 이어집니다. 좋은 예가 WildFly(예전 JBoss Application Server)입니다. 애플리케이션 서버에서 클러스터링·캐싱·메시징 같은 불필요한 기능을 분리하면 전부 달고 있을 때보다 훨씬 빠릅니다. 제10장에서 다룬 아키텍처 싱크홀 안티패턴 으로 인한 고통도 상대적으로 덜합니다.

확장성·탄력성·내결함성 ★☆☆☆☆

모놀리스라는 근본 제약 때문에 모두 최저점입니다. 작은 한 부분에서 메모리 부족이 생기면 애플리케이션 전체가 죽습니다. REST로 플러그인을 원격화하면 어느 정도 개선되지만, 이때는 더 이상 순수 모놀리스가 아니며 단순성·비용이 희생됩니다.

적합한 상황

사용하면 좋은 경우

  • 커스터마이징이 본질인 제품 기반 애플리케이션: 이클립스, PMD, 지라, 젠킨스, 크롬/파이어폭스 같은 개발·배포 도구와 웹 브라우저
  • 맞춤 처리가 필요한 비즈니스 도메인: 미국 보험사의 주별 규칙, 국제 배송업체의 법·물류 변형, 세법 양식(1040 요약 + 추가 양식·워크시트), 보험 청구 처리(관할구역별 규칙을 규칙 엔진 플러그인으로 격리)
  • A/B 테스트나 실험으로 빠르게 기능을 교체해야 하는 상황: 활성화 팀 성격의 조직에 특히 유리
  • 시간과 예산이 제한된 상황: 모놀리스라 진입 비용이 낮음

사용하지 말아야 할 경우

  • 높은 확장성·탄력성·내결함성 이 필요한 시스템(모놀리스 한계)
  • 코어 자체가 계속 변하는 시스템: 마이크로커널 철학이 깨지므로 모듈형 모놀리스나 분산 아키텍처가 더 적절
  • 플러그인끼리 복잡하게 협업해야 하는 시스템: 전이적 의존성 충돌의 늪에 빠지기 쉬움

예시

  • 제품 기반: 이클립스 IDE, PMD, 지라(Jira), 젠킨스(Jenkins), 크롬/파이어폭스 확장 프로그램
  • 세무 준비 소프트웨어: IRS의 2쪽짜리 1040 세무 양식이 코어(드라이버) 역할을 하고, 각 추가 양식·워크시트가 플러그인 컴포넌트. 세법이 바뀌어도 독립적으로 플러그인만 교체
  • 보험 청구 처리: 각 관할구역(주)의 청구 규칙을 별도 플러그인으로 격리. 코어는 청구 접수·처리라는 표준 프로세스를 담당. 새 관할구역 추가·제거가 다른 부분에 영향을 주지 않음
  • 고잉 그린(전자제품 재활용): 기기별 평가 플러그인(assessment_iphone6s.jar, assessment_galaxy5.jar 등)을 코어가 레지스트리로 찾아 호출

비교 / 트레이드오프

스타일공통점차이점
Ch10 계층형 아키텍처모놀리스, 아키텍처 퀀텀 1, 단순성 강점계층형은 기술 분할만 가능. 마이크로커널은 도메인 분할도 가능하며 변동성 격리에 강함
Ch11 모듈형 모놀리스 아키텍처모놀리스 기반의 모듈성모듈형 모놀리스는 도메인 모듈들의 동등한 협업. 마이크로커널은 코어-플러그인의 비대칭 구조
Ch12 파이프라인 아키텍처기술적 분할, 모놀리스파이프라인은 단방향 데이터 흐름. 마이크로커널은 코어가 중심이 되는 허브-앤-스포크

내 생각

  • 실무에서 가장 흔히 보는 “은근한 마이크로커널”은 스프링의 PluginManager 스타일 코드 입니다. 결제 수단별(PaymentProcessor 인터페이스 + 구현체 여러 개)로 Map<PaymentMethod, PaymentProcessor> 레지스트리를 두고 디스패치하는 패턴이 바로 이 아키텍처의 축소판입니다. 스프링의 @QualifierApplicationContext.getBeansOfType()이 사실상 레지스트리 역할을 합니다.
  • 가장 무서운 함정은 “우리 코어는 안정적이다”는 착각 입니다. 커스터마이징은 플러그인으로 빠졌지만, 코어의 “일반 흐름” 자체가 비즈니스 요구에 따라 계속 바뀌면 리팩터링 파도가 플러그인까지 덮칩니다. 계약(contract) 변경이 N개 플러그인에 전파되는 순간이 마이크로커널이 무너지는 지점입니다. 그래서 계약 테스트코어 변경 빈도 모니터링 이 거버넌스의 최우선 과제입니다.
  • REST 원격 플러그인으로 전환하는 순간 마이크로커널은 사실상 서비스 기반 아키텍처 또는 마이크로서비스의 초기 형태 가 됩니다. “우리 시스템은 마이크로커널입니다”라고 말할 때, 플러그인이 프로세스 내부인지 프로세스 외부인지부터 구분해야 오해가 없습니다. 외부라면 실패 모드, 타임아웃, 계약 버전 관리가 모두 달라집니다.
  • 서드파티 플러그인을 받을 계획이라면 어댑터를 표준으로 박아두는 것 이 생존 전략입니다. 초기엔 과해 보여도, 외부 플러그인이 세 개째 들어올 즈음엔 코어에 기능별 분기 if가 기어들어오는 걸 어댑터가 막아줍니다.

더 알아볼 것

  • OSGi와 자바 9 Jigsaw 모듈 시스템의 차이
  • 스프링에서 플러그인 레지스트리 + 전략 패턴을 깔끔하게 구현하는 방법 (Map<K, V> DI 활용)
  • ArchUnit으로 “플러그인이 DB에 직접 접근하지 못한다” 같은 구조 규칙 강제하기
  • Drools 같은 규칙 엔진을 플러그인 컴포넌트로 감싸는 설계
  • Apache ZooKeeper / Consul을 플러그인 레지스트리로 쓰는 실제 사례

관련 개념

출처

  • 마크 리처즈, 닐 포드, 『소프트웨어 아키텍처 The Basics』, 13장 마이크로커널 아키텍처 스타일