728x90
이벤트 발행을 보장하는 방법
Event Driven Architecture 에서의 이벤트 발행을 보장하는 방법은 여러가지 있다.
MSA로 설계된 분산시스템 에서는 데이터의 일관성을 유지 하는것은 매우 중요하다.
아웃박스 패턴은 서비스 간의 데이터를 최소 한번 이상 전달하여
두 서비스 간의 데이터의 정합성을 목표로 한다.
멱등성
최소 한번 이상 전달 하더라도 데이터가 동일 해야 한다.
위 말을 들으면 멱등성 이라는 것이 떠오를 것이다.
그러므로 데이터가 중복 처리 되더라도 같은 결과를 얻을 수 있게
멱등성을 고려하는 것이 중요하다.
목표 - 데이터의 일관성
- 메시지 손실 방지: 아웃박스 패턴은 로컬 트랜잭션을 통해 작업의 원자성을 보장하고
이벤트를 데이터 베이스에 저장하여, 전송 과정에서 발생할 수 있는 메시지 손실을 방지한다. - 비동기 처리: 아웃박스 패턴은 데이터 전송을 비동기적으로 처리하여, 서비스 간 처리 속도 차이로 인한 문제를 해결한다.
ㄴ 배송(송장 만들기, 물류팀에 포장 요청) 서비스와 주문(주문 완료 데이터 저장) 서비스 비동기로 처리하여
처리 속도가 다른 두 서비스에 따로 요청하여 효율적인 요청처리가 가능하다.
구현
@Transactional
public void createOrder(Order order) {
// 주문 생성 로직
orderRepository.save(order);
// 아웃박스 테이블에 이벤트 저장
OutboxEvent outboxEvent = new OutboxEvent();
outboxEvent.setEventName("OrderCreated");
outboxEvent.setPayload(new ObjectMapper().writeValueAsString(new OrderEvent("OrderCreated", order.getId(), order.getUserId())));
outboxRepository.save(outboxEvent);
}
주문을 저장할때 아웃박스객체에 이벤트를 만들어 db에 저장한다.
위 코드는 @Transactional 에 묶였기 때문에 해당하는 로직이 모두 성공하거나, 모두 실패하게 된다.
(도메인 로직과 메시지 발행에 대한 정합성 유지)
폴링 데이터 감지
@Transactional
@Scheduled(fixedRate = 10000)
public void processOutboxEvents() {
List<OutboxEvent> events = outboxRepository.findAll();
for (OutboxEvent event : events) {
kafkaTemplate.send("order-topic", event.getPayload());
outboxRepository.delete(event);
}
}
10초에 한번 씩 아웃박스 패턴의 모든 이벤트를 불러와서 이벤트를 처리 후
아웃박스를 삭제한다.
- 이 방법은 실시간성이 보장이 안되고 이벤트가 없더라도 지속적인 요청을 보내 효율이 좋지 못하다.
Change Data Capture (CDC) 데이터 변경 감지
데이터베이스의 변경 사항을 실시간으로 감지하고, 이를 외부 시스템으로 전달하는 기술.
CDC 를 활용하여 트랜잭션 로그 테일링 패턴(Transaction log tailing Pattern)을 구현 한다
CDC를 사용하면 데이터베이스에서 발생한 INSERT, UPDATE, DELETE 등의 데이터 변경 사항을 실시간으로 캡처하여 처리할 수 있다.
• Oracle: Oracle GoldenGate, Oracle Streams 등의 CDC 솔루션을 통해 데이터 변경을 캡처하고 이를 외부 시스템에 전달할 수 있습니다.
• PostgreSQL: PostgreSQL의 pg_logical 또는 pgoutput 논리 복제 슬롯을 사용하여 변경 데이터를 캡처하고 처리할 수 있습니다.
• MySQL: MySQL의 Binlog API를 활용하여 변경 사항을 캡처하고 처리할 수 있습니다.
각 데이터 베이스는 각기 다른 CDC 기술이 있다.
CDC 를 활용하여 데이터베이스의 변경을 감지하여 타겟서비스에 해당 이벤트를 넘겨 처리하게 만든다
참고
728x90
'개-발 > Java + Spring + Kotlin' 카테고리의 다른 글
[Java] 정규표현식 regex (0) | 2024.07.29 |
---|---|
[MSA] 분산 시스템 이벤트 소싱 구현 ( Transaction OutBox Pattern ) (0) | 2024.07.26 |
[Spring] JDK Dynamic Proxy 와 CGLIB (0) | 2024.04.24 |
[Spring] Transaction 트랜잭션의 이해 (0) | 2024.04.24 |
[Spring] Jasypt 중요 정보를 암호화 하자 (0) | 2024.04.12 |