728x90
이벤트 기반 아키텍처 vs HTTP 서비스 아키텍처
1. 정의
- 이벤트 기반(Event‑driven) 아키텍처
시스템에서 발생한 ‘사건(이벤트)’을 메시지로 발행(publish)하고, 구독(subscribe)한 컴포넌트가 비동기로 처리
예시: 주문 생성 → 재고 서비스가 “재고 감소” 이벤트 처리 - HTTP 서비스(요청/응답) 아키텍처
클라이언트가 HTTP 요청을 보내면 서버가 즉시 응답하는 동기 방식
예시:GET /orders/123
요청 → 주문 정보 반환
2. 주요 차이점
구분 | 이벤트 기반 | HTTP 서비스 |
---|---|---|
통신 방식 | 비동기 (Asynchronous) | 동기 (Synchronous) |
결합도 | 느슨 결합 (loose coupling) | 상대적으로 강한 결합 |
응답 보장 | 발행만 보장, 처리 성공 불투명 | 요청‑응답으로 성공/실패 명확 |
확장성 | 수평 확장 용이 | 확장 가능하지만 덜 유연 |
장애 격리 | 한 컴포넌트 장애 시 영향 적음 | 서비스 장애 시 전체 영향 |
실시간성 | 이벤트 지연 가능성 있음 | 즉시 응답 보장 |
3. 장단점
3.1 이벤트 기반
- 장점
- 유연한 확장성
— 소비자만 추가하면 됨 - 느슨한 결합
— 발행자와 소비자가 서로 몰라도 동작 - 장애 격리
— 한 컴포넌트 문제 시 전체에 즉시 영향 적음
- 유연한 확장성
- 단점
- 추적·디버깅 어려움
- 일관성 보장 복잡
- 메시지 브로커 운영 부담
3.2 HTTP 서비스
- 장점
- 구현·테스트 용이
- 명확한 에러 핸들링 (HTTP 상태 코드)
- 호출 흐름 트레이싱 쉬움
- 단점
- 강한 결합
- 급격한 확장 한계
- 장애 전파 위험
4. 언제 선택할까?
- 이벤트 기반이 적합한 경우
느슨 결합이 중요할 때, 비동기 처리(이메일 발송·로그 수집 등), 마이크로서비스 간 대량 메시지 교환 - HTTP 서비스가 적합한 경우
즉각적 응답이 필요할 때, 명확한 트랜잭션 단위가 있을 때, 구현·테스트·디버깅 단순성을 우선할 때
Tip: 실제 시스템에서는 두 방식을 혼합하여, 동기 요청이 필요한 부분은 HTTP로 처리하고, 배치·알림 등 비동기 작업은 이벤트 기반으로 처리하는 경우가 많습니다.
5. React 예제
5.1 이벤트 기반 예제
events.js
// events.js
import { EventEmitter } from 'events';
export const eventBus = new EventEmitter();
Publisher.jsx (주문 생성 이벤트 발행)
import React from 'react';
import { eventBus } from './events';
export function Publisher() {
const handleClick = () => {
eventBus.emit('orderCreated', { orderId: 123, item: 'T-Shirt' });
};
return (
<button onClick={handleClick}>
주문 생성 이벤트 발행
</button>
);
}
Subscriber.jsx (이벤트 구독 및 처리)
import React, { useEffect, useState } from 'react';
import { eventBus } from './events';
export function Subscriber() {
const [order, setOrder] = useState(null);
useEffect(() => {
const handler = (data) => {
setOrder(data);
};
eventBus.on('orderCreated', handler);
return () => {
eventBus.off('orderCreated', handler);
};
}, []);
return (
<div>
{order
? `새 주문: #${order.orderId}, 상품명=${order.item}`
: '대기 중...'}
</div>
);
}
5.2 HTTP 서비스 예제
DataFetcher.jsx (fetch API를 사용한 요청‑응답)
import React, { useEffect, useState } from 'react';
export function DataFetcher() {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
fetch('https://api.example.com/orders/123')
.then((res) => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
})
.then((json) => {
setData(json);
})
.catch((err) => {
setError(err.message);
});
}, []);
if (error) return <div>에러 발생: {error}</div>;
if (!data) return <div>로딩 중…</div>;
return (
<div>
주문 정보<br/>
• ID: {data.orderId}<br/>
• 상품명: {data.item}<br/>
• 상태: {data.status}
</div>
);
}
728x90
'React > React 실습' 카테고리의 다른 글
[React] ResizeObserver로 이미지 주석 입력창의 위치 오류 해결하기 (0) | 2025.06.10 |
---|---|
System.Text.Json을 활용한 네이버 로그인 응답 처리 개선 (1) | 2025.04.10 |
[SSO] 네이버 소셜 로그인 연동 및 보안 고려사항, (팝업 기반 소셜 로그인 처리 방식) (0) | 2025.04.10 |
[OAuth2] 기존 시스템에 네이버 소셜 로그인 기능 연동하기 (JWT + 팝업 방식) (0) | 2025.04.02 |
[React] Material-UI Popover 위치 보정과 애니메이션 적용 시행착오 기록 (0) | 2025.03.14 |
댓글