백엔드 응답 최적화: 대기열, async, 역압
1) 이유: 목표와 SLO
목표는 버스트 상태에서도 안정적인 빠른 응답입니다. 비즈니스는이 SLO를 표현합니다
API (CRUD/디렉토리): p95 λ250-400 ms, 오류율 <1%.
결제/결제 (비동기식): 확인을위한 내부 SLA (2-5 분) 및 클라이언트-인스턴트 202/허용 + 상태 폴러/웹 후크.
WS/실시간: RTT p95 5%.
키: 사용자 응답에서 대기열 및로드 제한을 통해 "느린" 단계 (공급자, 데이터베이스, 외부 API) 를 해제합니다.
2) 기본 사진: 대기 시간이 촬영 된 곳
병목 현상: 데이터베이스 (풀/인덱스), 외부 제공 업체 (PSP/게임), I/O 차단, GC/스톱 월드, JSON 직렬화, "무거운" 집계.
증상: p99 성장, DB 연결 대기열, 트레이 버스트, 폭풍 재시도.
해독제: 비동기 파이프 라인 + 역압 + 타임 아웃/후퇴 + demempotency.
3) 비동기 패턴: SEDA 및 CQRS
SEDA (단계별 이벤트 중심 아키텍처): 처리를 단계로 나눕니다 (intress → 유효성 → 쓰기 → 통합 → 알림). 각각 자체 회전 및 동시성 제한이 있습니다.
CQRS: 별도의 읽기 및 쓰기. 프로젝션/캐시에서 로그/데이터베이스에 쓰기, 읽기.
편지함: 이벤트는 레코드와 함께 원자 적으로 게시됩니다 ("잃어버린" 메시지 피함).
Saga: 글로벌 거래 대신 보상 거래를 통한 장기 비즈니스 프로세스.
4) 대기열 및 스트림: 선택 및 튜닝
RabbitMQ/NATS JetStream-작업 명령 (작업 대기열), Kafka-이벤트/스트림을 재생합니다.
응답에 영향을 미치는 설정:- 프리페치/최대 기내: 데이터베이스/외부 API를 "막지" 않도록 작업자 당 동시에 처리 된 메시지 수 (예: 16-64) 를 제한합니다.
- 애커/반복: dempotent 기록 후 'ack'; 지수 지연 및 지터 반복.
- DLQ/주차장: 끝없는 휴양지가 없습니다. N 시도 후 Dead Letter Queue로갑니다.
- 파티셔닝 (Kafka): 주문을위한 본질 별 키 (userID/txnID); 당사자 수를 통한 병렬 처리.
5) 역압-익사하지 않는 방법
아이디어: SLO 대기 시간 내에 처리 할 수있는 한 많이 가져 가십시오.
기술자:- 입학 제어: 데이터베이스, PSP, 게임 제공 업체와 같은 각 외부 종속성에 대한 제한 경쟁 (세마포어/작업자 풀).
- 트래픽 성형: 서비스 입구 및 중요한 경로에서 토큰 버킷/누출 버킷.
- 상단 테두리가있는 대기열: 가득 차면 꼬리를 자르거나 (429/503 + 재시도 후) asap-batch로 이동하십시오.
- 적응 형 동시성 (AIMD): 성공에 대한 병렬 처리 증가, 타임 아웃에 대한 감소.
- 서킷 브레이커: 외부 API의 오류/타임 아웃에 의한 '폐쇄 → 개방 → 하프 오픈'; 열릴 때 - 열림 (캐시/스터브).
go sem: = made (chan strt {}, 64 )//DB/PSP와의 경쟁 제한
func handle (req) {
{선택
case sem <- strue {} {}:
(PHP 3 = 3.0.6, PHP 4)
ctx, 취소: = 컨텍스트. 시간 초과 (req. ctx, 300 시간. 밀리 초)
취소를 연기합니다 ()
res, err: = db. (ctx, req)
실수 = = 컨텍스트 인 경우. 데드 라인 익스프레스 {메트릭. 타임 아웃. Inc (); (PHP 3 = 3.0.6, PHP 4)
Ok 반환 (res)
기본값:
메트릭. 역압. Inc ()
TooBusy를 반환합니다 (429, "재시도 후: 0. 2")
}
}
6) 타임 아웃, 퇴각 및 지터: "3 개의 생존 고래"
SLO보다 짧은 타임 아웃: SLO 400ms 인 경우 DB/provider 250-300ms 로의 타임 아웃; 총 요청 시간 초과 <400-600 ms.
Retrai 제한 및 스마트: 1-2 최대 시도, 지수 및 지터가있는 안전한 작업 (dempotent) 에만 적용됩니다.
Coalessing: 집계는 단일 키로 재생됩니다.
의사 코드 (지수 + 지터):범위 내 시도를위한 파이썬 (0, 2):
시도:
반환 호출 (dep, 타임 아웃 = 0. 3)
시간 초과 제외:
백오프 = (0. 05 (2 회 시도) + 무작위. 균일 (0, 0. 05)
수면 (백오프)
UpstreamUnaisable을 올리십시오
7) 정체성과 중복 제거
데이터베이스의 이데올로기-키 (예금, 지불), 데이터베이스의 'operation _ id' (고유 인덱스).
받은 편지함/편지함: 들어오는 웹 후크-항상 '이벤트 _ id' 로 dedupe가있는 변경할 수없는받은 편지함 테이블을 통해; 트랜잭션별로 아웃 박스에서 아웃 바운드.
정확히 한 번 "의미": 우리는 반복적 인 전달/실행을 허용하지만 한 가지 효과 만 있습니다.
8) 느린 작동을위한 빠른 API
동기식 응답: 201/202 + 상태 IM ('/상태/{ id} '), ETA 및 레트로 힌트.
웹 후크/서버 전송 이벤트/WS-준비가되면 상태를 푸시하십시오.
클라이언트 분야: '재생 후', dempotence, 폴링 한계.
응답 예:json
HTT/1. 1202 허용
위치 :/v1/reprowals/req _ 9f2/상태
재시도 후: 2
{
"요청 _ id": "req _ 9f2", "상태": "처리", "다음 _ 확인 _ sec": 2
}
9) 뜨거운 작업 최소화
변형, 집계, 알림, DWH 작성 등 무거운 것들을 배경에 두십시오.
캐시 및 프로젝션: 일반적으로 읽기-짧은 TTL 및 이벤트 장애가있는 캐시 제외.
배치 패턴: 그룹 외부 통화 (예: 요청 공급자는 Nms에서 한 번 제한됩니다).
직렬화: 서비스 대 서비스 통신을위한 빠른 코덱( 프로토콜/msgpack); 가장자리에만 JSON.
10) 통제중인 DB
연결 풀: 상한 (코어/IO 기준), 풀 대기열 활성화.
색인 및 계획: p95는 계획의 회귀 자동화를 설명합니다.
요청 시간 초과: 짧은 '문 _ 타임 아웃' (Postgres).
핫 행/잠금 장치: "모 놀리 식" 트랜잭션 대신 키 샤딩, 낙관적 잠금 장치 (밸런스 버전), 사가.
11) 웹 소켓/실시간
뉴스 레터 리미터: 배치 된 브로드 캐스트, 연결 당 최대 msgs/sec.
내부 역압: 캡이있는 아웃 바운드 메시지 대기열; 오버플로시-우선 순위가 낮습니다.
다시 연결되는 폭풍을 일으키지 않도록 릴리스 중에 끈적 끈적한 라우팅 및 PDB.
12) 추측하지 않는 관찰 가능성
메트릭 (RED/USE + 후압):- '요청 _ rate', '오류 _ ratio', '대기 시간 _ p95/p99' on 경로.
- 'queu _ deep', 'lag _ seconds', 'saver _ inflight', 'retries _ total', 'dlq _ rate'.
- 'backpressure _ drops', 'entrient _ demost', 'circuit _ Open'.
- 자리: '연결 _ in _ use/max', '잠금', 'slow _ queries'.
- 추적: '큐 → 작업자 → db/psp' 는 태그 'operation _ id', 'partition', 'repost' 입니다.
- 로그: PII가없는 'trace _ id' 가있는 구조; 개별 "개방/폐쇄 회로" 이벤트.
13) 로드 테스트
버스트에 대한 오픈 모델 (도착/초); 세션에 대한 폐쇄 모델 (VU).
프로필: 간단한 버스트 60-120 초 및 1-4 시간 흡수
주입 실패: 외부 API를 + 200-500ms 느리게하고 p99/retrai/큐를보십시오.
녹색 영역 기준: 성장 '큐 _ lag', 안정적인 p95, 'dlq _ rate λ0' 이 없습니다.
14) 안전과 신뢰성
TLS/mSL 대기열, 메시지 서명, 스키마 모니터링 (Avro/Proto + Schema Registry).
정당한 곳에서 정확히 한 번 tx 인 Idempotent Producer (Kafka).
혼돈 모드: 중독을 주기적으로 "드롭" 하고 열화 (회로, 대체) 를보십시오.
15) 구성의 "조각" 의 예
Nginx/특허 입력 성형:nginx limate _ req _ zone $ ginial _ ellant _ addr zone = api: 10m rate = 20r/s;
서버 {
위치/api/{
한계 _ req zone = api burst = 40 nodelay;
(PHP 3 = 3.0.6, PHP 4) 6s; # 은 SLO 프록시 _ 연결 _ 타임 아웃 0보다 짧습니다. 2s;
}
}
RabbitMQ (프리 페치):
기본. qos (prefetch _ count = 32) # CPU/IO 밸런스
카프카 소비자 (자바 조각):
자바 소품. 넣기 (소비자 설정) MAX _ POLL _ RECORDS _ CONFIG, 200);
소품. 넣기 (소비자 설정) FETCH _ MAX _ BYTES _ CONFIG, 5 _ 000 _ 000);
소품. 넣기 (소비자 설정) MAX _ POLL _ INTERVAL _ MS _ CONFIG, 60 _ 000);
16) 구현 점검표 (prod-ready)
- 중요한 경로는 동기 응답과 비동기 처리 (SEDA) 로 나뉩니다.
- 외부 종속성에 대한 입학 통제 및 경쟁 제한.
- 타임 아웃은 SLO보다 짧습니다. 지수와 지터가있는 retrai 소 2; 합동.
- 회로 차단기 + 저하 (캐시/스터브), 반 개방 정책.
- 대기열/스트림: 프리 페치/기내, DLQ, 키 배치.
- Idempotency (operation _ id/Idempotency-Key), 전송/받은 편지함, 중복 제거.
- 캐시: 캐시 제외, 짧은 TTL + 이벤트 장애.
- DB: 풀 한계, 문장 _ 타임 아웃, 색인, 잠금 방지 전략.
- WS: 메시지 제한, 버칭, 끈적 끈적한 라우팅, PDB.
- 관찰 가능성: 역압/대기열/재 시도 지표, 엔드 투 엔드 트레일, 대시 보드.
- 로드 및 고장 테스트 (열기 + 닫기, 버스트 + 담그기), 녹색 영역 기준.
요약 다시 시작
빠른 백엔드는 "다른 캐시 만들기" 가 아니라 제어 된 스트림입니다. 백그라운드에서 입력이 제한적이고 무겁습니다. 백그라운드에서 각 단계마다 큐와 한계가 있으며 배상은 드물고 스마트하며 체인은 회로 차단기 및 demotency로 보호됩니다. 타임 아웃 분야, 관찰 가능성 및 정기적 인 스트레스 테스트를 추가하면 p95/p99는 외부 제공 업체의 파열과 변덕에도 녹색으로 유지됩니다.