[Camel in Action] 18-2. 실전 Camel 패턴 – 레거시 시스템 통합 전략

레거시 시스템 통합의 현실

기업의 핵심 시스템 대부분은 수십 년 된 레거시입니다. 전면 재개발은 비용과 위험이 너무 크고, 그냥 두면 현대화가 불가능합니다. Camel은 레거시 시스템을 건드리지 않고 현대적인 인터페이스로 감싸는 데 탁월합니다.

Strangler Fig 패턴

나무를 감싸며 자라는 교살자 무화과나무처럼, 레거시 시스템을 새 시스템으로 점진적으로 대체합니다. Camel이 중간에서 요청을 신구 시스템에 적절히 분배합니다.

// 기능별로 신구 시스템에 라우팅
from("servlet:api/orders")
  .choice()
    .when(header("feature-flag").isEqualTo("new-system"))
      .to("http4://new-order-service/api/orders")
    .otherwise()
      .to("http4://legacy-system:8080/OrderService")
  .end();

Feature Flag를 활용하면 특정 사용자나 트래픽 비율만 새 시스템으로 보내 안전하게 검증합니다.

레거시 API 래핑

SOAP 기반 레거시 서비스를 REST API로 감싸는 일반적인 현대화 패턴입니다.

// 레거시 SOAP를 REST로 래핑
rest("/customers/{id}")
  .get()
  .to("direct:getCustomer");

from("direct:getCustomer")
  .setHeader("customerId", header("id"))
  .to("cxf:http://legacy-system/CustomerService?serviceClass=CustomerService")
  .process(exchange -> {
    // SOAP 응답을 JSON으로 변환
    CustomerResponse soap = exchange.getIn().getBody(CustomerResponse.class);
    CustomerDto dto = mapper.toDto(soap);
    exchange.getIn().setBody(dto);
  })
  .marshal().json();

데이터 마이그레이션 파이프라인

레거시 DB에서 새 시스템 DB로 데이터를 점진적으로 마이그레이션합니다.

// 야간에 미마이그레이션 데이터를 배치로 이전
from("quartz2:migration?cron=0+0+3+*+*+?")
  .to("sql:SELECT * FROM legacy_orders WHERE migrated=0 LIMIT 1000")
  .split(body())
    .process(exchange -> {
      LegacyOrder legacy = exchange.getIn().getBody(LegacyOrder.class);
      NewOrder newOrder = legacyMapper.convert(legacy);
      exchange.getIn().setBody(newOrder);
    })
    .to("bean:newOrderRepository?method=save")
    .to("sql:UPDATE legacy_orders SET migrated=1 WHERE id=:#${body.legacyId}")
  .end()
  .log("마이그레이션 배치 완료");

이벤트 기반 레거시 통합

레거시 시스템이 이벤트를 발행하지 못한다면 DB 변경을 폴링해 이벤트를 발행합니다.

// DB 변경 감지 후 이벤트 발행 (CDC 패턴)
from("sql:SELECT * FROM orders WHERE created_at > :#${header.lastCheck} "
  + "ORDER BY created_at?delay=10000")
  .process(exchange -> {
    exchange.getIn().setHeader("lastCheck", LocalDateTime.now().toString());
  })
  .split(body())
    .marshal().json()
    .to("kafka:order-events")
  .end();

Leave a Comment