✅ 발송 정상화 완료

글로벌 린다세일즈 — AI 캠페인 6/2 + 글로벌 식품 브랜드사

19개 발신 계정 라운드 로빈 분산 + 발송 stuck 완전 해소

📅 2026-06-05📦 beta production🏷 5 PR 머지

한 줄 요약

두 캠페인 모두 정상 발송 중. AI 캠페인 6/2 는 분당 30~45 건 (19계정 동시 발송), 글로벌 식품 브랜드사는 step1 발송 4,647건 완료 후 step2 대기. 이제부터 캠페인을 일시정지 → 재활성화하면 등록된 발신 메일에 자동 라운드 로빈 분산됩니다.

📊 현재 상태 — KPI

분당 발송 peak45
활성 발신 계정19
24h 발송 (두 캠페인)8,091
분배 균등성 (max/min)2.5

1. AI 캠페인 6/2 — 19계정 라운드 로빈 분배 (최근 10분)

voice
20
post
18
ask
17
share
17
sync
16
hey
16
memo
16
chat (보존)
15
letter
15
talk
15
ping
12
knock
12
say
12
brief
10
note
10
hi
9
reach
8
intro
8
meet
8
19개 계정 모두 동시 발송 중 (8~20 범위). max/min 2.5, CV ~30%. chat 보존분도 다른 18계정과 균등 (15건). 라운드 로빈 완전 정상.

2. 분당 발송 추세 (AI 캠페인 6/2)

발송비고
07:4622
07:4745peak
07:4832
07:4939
07:5028

평균 ~33/분 · peak 45/분 · 이론치 142/분 의 32% 활용

3. 글로벌 식품 브랜드사 — step1 완료, step2 대기

지표
24h 누적 발송4,647건
최근 10분 발송0 (step1 완료)
다음 step 발송3~7일 후 (sequence step interval)
분배 상태 (이전 측정)18계정 균등 (1,265~1,424/계정, CV 3%)
정상 상태. step1 발송 모두 완료 후 step2 까지 sequence step interval 대기 중. 자동으로 다음 step 시각 도래 시 재발송.

🎯 운영 가이드 — 일시정지 → 재활성화 자동 분산

오늘 머지된 코드 (PR #8182·#8187) 덕분에 캠페인을 일시정지 후 재활성화하면 등록된 발신 메일에 자동 라운드 로빈 분산됩니다.

1
발신 메일 풀 추가 — admin UI 캠페인 상세에서 발신자 풀 다중 선택 (예: 19개 SES 계정)
2
일시정지 클릭 — 기존 BullMQ delayed 잡 자동 정리 (cancelSequenceJobs)
3
재활성화 클릭 — 자동으로 reallocateSenderPool 호출:
  • 🟢 미발송 enrollment → SHA256 sticky 해시로 새 풀에 균등 재분배
  • 🔴 이미 step1 발송된 enrollment → 기존 sender 그대로 (Gmail/Outlook thread 일관성 보호)
  • ⚪ 종료 상태 (stopped/bounced/unsubscribed) → 변경 없음
4
BullMQ 자동 재enqueue — sequence-email-loader 30초 tick 으로 DB 기준 새 emailAccountId 박힌 잡 재투입
5
발송 시작 — 약 1-2분 안에 모든 계정 동시 발송 가속 (분당 ~30 + peak 45)
⚠️ 풀에 1개만 등록된 캠페인은 분산 효과 없음. 발신자 풀에 다중 등록한 후 재활성화해야 자동 분산 동작.

📦 오늘 적용한 코드 수정 (5개 PR)

#영역변경효과
#8170/8172 답장 매칭 RFC 5322 정규화 + References Tier 2 fallback (헥사고날 reply-matching 모듈) 답장 매칭률 27.3% → 95%+ 회복. 989건 백필 완료.
#8175/8176 Redis 인프라 maxmemory 4G → 8G + 컨테이너 한도 10G + swap=0 (mem_swappiness:0, memswap_limit==mem_limit) Redis OOM 해소, 배포 healthcheck 정상화.
#8182/8184 발신 계정 분산 paused → active 재활성화 시 sender pool selective 재할당. 이미 sent step1 enrollment 는 보존, 미발송만 SHA256 해시로 새 풀에 재분배. 40,799 enrollment 18계정 균등 재분배 완료 (이전 99.8% 단일 집중 해소).
#8187/8189 UNNEST drizzle fix PG array literal direct param + 5000 chunk — drizzle 의 array spread 회피 (이전 PR 의 runtime error fix). 재할당 SQL 실행 안정성 확보.
#8198/8200 429 무한 retry 차단 5-Layer Defense (헥사고날): ProviderQuotaExhaustedError + adapter throw + usecase catch + worker UnrecoverableError + status='unreachable' Hunter/Findymail 429 폭주 → sequence-email event loop 점유 해소. 발송 분당 1-3 → 30-45 (10~15배 가속).

🔧 운영 액션 — Before / After

지표Before (오늘 아침)After (현재)
Redis maxmemory4 GB (100% full, OOM)8 GB (50% 사용)
답장 매핑률27.3%95%+
AI 캠페인 6/2 발신 분배chat 99.8% 단일 집중19계정 균등 (CV 30%)
발송 stuck (BullMQ wait)86,187 잡 적체0 (drain 완료)
분당 발송 (글로벌 린다세일즈)1~3건 (stuck)30~45건
Hunter 429 무한 retry폭주UnrecoverableError 차단

🚀 다음 권장 액션 (다른 캠페인)

현재 글로벌 린다세일즈의 다른 active 캠페인 6개도 같은 fix 적용 가능 (모두 pool=1 단일 발신):

캠페인현재 enrollment분배 가능 시
글로벌 브랜드사 (6.1) -6 영업29,925throughput 19배
글로벌 제조사 AI 솔루션 제안29,879throughput 19배
글로벌 뷰티 브랜드 AI 솔루션 제안29,851throughput 19배
글로벌 브랜드사 (6.1) -13 영업19,905throughput 19배
글로벌 뷰티 브랜드 AI 솔루션 제안 #219,904throughput 19배

각 캠페인에 admin UI 에서 발신자 풀 19개 추가 → 일시정지 → 재활성화 클릭하면 자동 분산.