Files
2nd/10_Wiki/Topics/AI_and_ML/Legacy_Modernization.md
T
koriweb d8a80f6272 chore(wiki): dangling 링크 canonical 정규화 (768파일/1200건)
이름만 다른(표기 변형) [[위키링크]]를 대상 문서의 canonical 제목으로 치환해
끊겼던 1,200개 링크를 연결. 제목/파일명 정규화 일치만 적용하고 별칭 매칭은
과병합 위험으로 제외(애매성 가드). 원본은 _link_reconcile_backup/ 에 백업.
도구: Datacollect/scripts/link_reconcile_apply.mjs

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 12:24:15 +09:00

5.4 KiB

id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
id title category status canonical_id aliases duplicate_of source_trust_level confidence_score verification_status tags raw_sources last_reinforced github_commit tech_stack
wiki-2026-0508-legacy-modernization Legacy Modernization 10_Wiki/Topics verified self
Legacy Migration
Legacy Systems
Strangler Fig
Modernization
none A 0.9 applied
legacy
modernization
strangler-fig
refactor
migration
2026-05-10 pending
language framework
any any

Legacy Modernization

매 한 줄

"매 big-bang 은 죽는다". Strangler fig 로 incremental 하게 둘러싸고 잘라낸다, parallel run 으로 검증.

매 핵심

매 5 pattern

  • Strangler Fig (Fowler): 신규 시스템이 점진적으로 legacy 를 둘러싸고 대체. 가장 안전
  • Branch by Abstraction: 인터페이스 추출 → 두 구현 공존 → 신구 전환 → 구 제거
  • Parallel Run: 신구 동시 실행, 결과 비교, 신뢰 쌓이면 cutover
  • Rewrite vs Refactor: 비즈니스 로직 명확하면 refactor, 아키 자체가 문제면 rewrite
  • Anti-corruption Layer (DDD): legacy 모델이 신규에 새지 않도록 adapter

매 응용

  1. Monolith → microservice 분해
  2. On-prem → cloud
  3. Legacy DB schema 점진적 마이그레이션
  4. COBOL → Java/Go
  5. SOAP → REST/gRPC

💻 패턴

Pattern 1: Strangler Fig with reverse proxy

# nginx routes traffic: new endpoints → new svc, rest → legacy
location /api/v2/users { proxy_pass http://new-service; }
location /api/v2/orders { proxy_pass http://new-service; }
location / { proxy_pass http://legacy-monolith; }
# 매주 endpoint 추가 → legacy 점점 축소

Pattern 2: Branch by Abstraction

# 1. 추출
class PaymentGateway(Protocol):
    def charge(self, amount: int) -> str: ...

class LegacyPayment(PaymentGateway): ...  # 기존
class NewPayment(PaymentGateway): ...     # 신규

# 2. Feature flag 로 전환
def get_payment() -> PaymentGateway:
    return NewPayment() if flag.enabled("new_payment") else LegacyPayment()

Pattern 3: Parallel run with shadow traffic

def process_order(order):
    legacy_result = legacy.process(order)
    try:
        new_result = new.process(order)
        if new_result != legacy_result:
            log_diff(order, legacy_result, new_result)
    except Exception as e:
        log_error(e)
    return legacy_result  # 아직 legacy 가 truth

Pattern 4: Anti-corruption Layer

# Legacy 의 이상한 model 을 새 domain 으로 변환
class LegacyCustomerAdapter:
    def to_domain(self, row: dict) -> Customer:
        # legacy: cust_nm, cust_dt_birth, cust_flg_act
        return Customer(
            name=row["cust_nm"],
            birthday=parse_legacy_date(row["cust_dt_birth"]),
            active=row["cust_flg_act"] == "Y",
        )

Pattern 5: Database expand-contract

-- Phase 1 expand: 새 컬럼 추가, 양쪽 쓰기
ALTER TABLE users ADD COLUMN email_v2 VARCHAR(255);
-- App: write to both email AND email_v2

-- Phase 2 backfill: 기존 데이터 복사
UPDATE users SET email_v2 = LOWER(TRIM(email)) WHERE email_v2 IS NULL;

-- Phase 3 contract: 신규 read, 구 제거
-- App: read from email_v2 only
ALTER TABLE users DROP COLUMN email;
ALTER TABLE users RENAME COLUMN email_v2 TO email;

Pattern 6: Characterization tests before refactor

# Legacy 동작을 "있는 그대로" 고정 — golden master
def test_legacy_behavior():
    for input_case in load_production_samples():
        actual = legacy.process(input_case)
        assert actual == load_golden(input_case.id)
# Refactor 후에도 통과해야 함

Pattern 7: Event interception (Strangler 변형)

# Legacy 가 발행하는 event 를 새 서비스가 구독
@on_event("OrderCreated")
def new_handler(event):
    new_service.create_order(event.payload)
# Legacy 는 그대로, 새 시스템이 옆에서 동기화

매 결정 기준

상황 Approach
비즈니스 로직 명확, 코드 더러움 Refactor (in place)
아키 자체가 잘못 Rewrite + Strangler Fig
Risk 매우 높음 Parallel run + shadow
DB schema 변경 Expand-contract
Legacy 모델이 새 시스템 오염 Anti-corruption Layer
Big bang 유혹 거의 항상 X

기본값: Strangler Fig + Branch by Abstraction + Characterization tests.

🔗 Graph

🤖 LLM 활용

언제: legacy 코드 의도 파악, characterization test 생성, COBOL → Java 변환 후 검증. 언제 X: 결정론적 schema migration (sqitch/flyway), 비즈니스 룰 단독 추출 (사람 검증 필수).

안티패턴

  • Big bang rewrite ("2년만 주세요") → 프로젝트 사망
  • Test 없이 refactor → 회귀 무한
  • Strangler 시작했는데 끝까지 안 감 → 이중 유지보수 영원
  • DB schema 한번에 변경 → 롤백 불가
  • 비즈니스 사용자 무시 → 신규 기능 deliver 정지

🧪 검증 / 중복

  • Verified (Fowler StranglerFigApplication, Feathers WELC, Evans DDD ACL). 신뢰도 A.
  • Legacy-Systems.md 가 본 문서 redirect.

🕓 Changelog

날짜 변경
2026-05-08 Phase 1
2026-05-10 Manual cleanup — canonical, 5 pattern + 7 code recipe