쿠팡 크롤 IP 를 '막힐 때까지' 쓰던 방식을 '막히기 전에 교체'로 전환한다. - 요청 예산(LPS_IP_REQUEST_BUDGET, 기본 3): IP당 요청 수가 예산에 닿으면 차단 전에 선제 회전. 실측상 5회 부근 차단 이력이 있어 보수적으로 3회. 선제 교체된 포트는 평판이 깨끗해 로테이션 복귀 시 재사용된다. - 포트 쿨다운(LPS_PORT_COOLDOWN_SEC, 기본 max(sticky,30분)): 차단 감지· 전송오류 포트는 격리하고 _port() 가 건너뛴다. 전 포트 쿨다운이면 만료 임박 포트 사용(가용성 우선). 포트 수는 config 범위에서 동적 산출. - 차단 재시도 소진 시에도 회전 예약 — 불탄 포트로 다음 검색을 하지 않음. - ip_session 테이블 신설: 세션마다 요청 수·성공/차단·종료 사유(budget/ block/proxy_error/window/idle/shutdown)를 기록. bot_detection 과 달리 무사 종료도 남아 예산 상한 튜닝의 원천 데이터가 된다(쿼리 database.md). models.py·migrations·init.sql(lps_db 섹션) 동행 갱신, dev DB 적용 완료. - 테스트 17건 추가(쿨다운·예산 판정·세션 기록·CRUD), 전체 126 passed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
18 lines
1.5 KiB
SQL
18 lines
1.5 KiB
SQL
-- IP(프록시 포트) 세션 종료 이력 — 요청 예산(LPS_IP_REQUEST_BUDGET) 상한 튜닝의 원천 데이터.
|
|
-- bot_detection 은 차단된 세션만 남지만, 여기엔 무사 종료(budget/window 등)도 남는다.
|
|
-- 적용: psql -h <host> -U <user> -d lps_db -f migrations/2026-07-13-ip_session.sql
|
|
-- (postgres-init/init-data/init.sql 의 lps_db 섹션에도 동일 DDL 반영됨 — 신규 설치는 그쪽이 소스)
|
|
|
|
CREATE TABLE IF NOT EXISTS ip_session (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
source VARCHAR(20) NOT NULL, -- coupang 등
|
|
proxy_port INTEGER NULL, -- 사용 포트(=IP 세션), 프록시 미사용이면 NULL
|
|
requests INTEGER NOT NULL, -- 이 IP 로 보낸 요청 수
|
|
ok_count INTEGER NOT NULL DEFAULT 0, -- 성공 검색 수
|
|
blocked_count INTEGER NOT NULL DEFAULT 0, -- 차단 감지 수
|
|
elapsed_sec INTEGER NULL, -- 세션 지속 시간(초)
|
|
end_reason VARCHAR(20) NOT NULL, -- budget/block/proxy_error/window/idle/shutdown/rotate
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now() -- 세션 종료 시각
|
|
);
|
|
CREATE INDEX IF NOT EXISTS ix_ip_session_source ON ip_session (source, created_at);
|