docs(lps): 운영 가이드 — 관측(readyz/ops/알림)·라이브 스모크·Docker 배포
P4/P5 반영: /readyz·/v1/lps/ops·워커 하트비트·임계 알림 env, LPS_LIVE 라이브 스모크, docker compose 배포(헤드풀 Chromium+Xvfb·시크릿 env·프로필 볼륨·HEALTHCHECK). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
eb1ff8fee1
commit
97e566f844
@ -101,15 +101,32 @@ SELECT avg(ip_request_no), count(*) FROM bot_detection;
|
||||
SELECT key, until, reason FROM search_negative ORDER BY created_at DESC;
|
||||
```
|
||||
|
||||
## 4-1. 관측·알림 (모니터링)
|
||||
|
||||
| 엔드포인트/신호 | 용도 |
|
||||
|------|------|
|
||||
| `GET /healthz` | liveness — 프로세스 살아있는지(DB 무관) |
|
||||
| `GET /readyz` | readiness — DB 도달성까지 확인(실패 503). LB/오케스트레이터용 |
|
||||
| `GET /v1/lps/ops` | 운영 스냅샷: 큐 카운트 + `oldest_pending_sec`(큐 지연) + `dead_1h` + `stuck_running` + `blocks_1h`(최근 차단). 외부 모니터가 스크랩·알림 |
|
||||
| 워커 하트비트 | `/tmp/lps_worker_heartbeat`(mtime) — 컨테이너 HEALTHCHECK 가 신선도<120s 로 행/좀비 워커 감지 |
|
||||
|
||||
**임계 알림**(워커 ops-monitor): 초과 시 WARN 로그 + (env 있으면) Slack 호환 웹훅.
|
||||
```
|
||||
LPS_ALERT_WEBHOOK=https://hooks.slack.com/... # 있으면 알림 전송
|
||||
LPS_ALERT_DEAD_1H=20 LPS_ALERT_BLOCKS_1H=80 LPS_ALERT_QUEUE_LAG_SEC=300
|
||||
```
|
||||
|
||||
## 5. 테스트
|
||||
|
||||
```bash
|
||||
python -m pytest
|
||||
python -m pytest # 단위·통합(96) — 브라우저/네트워크 불필요
|
||||
LPS_LIVE=1 python -m pytest tests/test_browser_base.py::test_live_smoke # 라이브 스모크(셀렉터·안티봇 드리프트 감지)
|
||||
```
|
||||
> ⚠️ **워커가 실행 중이면 테스트가 깨집니다** — 워커가 같은 `lps_db`의 테스트 작업을 가로채기 때문. 테스트 전 워커를 멈추세요:
|
||||
> ```bash
|
||||
> pkill -f worker_main.py
|
||||
> ```
|
||||
> 라이브 스모크는 IP 의존·느려서 기본 skip. 배포 후 셀렉터가 깨졌는지 수동/야간 점검용.
|
||||
|
||||
## 6. 문제 해결
|
||||
|
||||
@ -125,10 +142,20 @@ python -m pytest
|
||||
| 검색이 너무 느림/비쌈 | `result.metrics`로 소스별 시간·DECODO 바이트 확인. 대역폭이 대부분(오픈마켓 크롤) |
|
||||
| `result.desc = LPS_JOB_NOT_FOUND` | 존재하지 않거나 잘못된 job_id |
|
||||
|
||||
## 7. 배포 시 유의 (예정)
|
||||
- Chrome을 **headless**로(서버엔 화면 없음) — 단 Cloudflare Turnstile은 headful이 더 잘 통과, 튜닝 필요
|
||||
- Docker 이미지에 **chromium 설치** 필요
|
||||
- **프록시(residential)** 사실상 필수 — 클라우드 IP는 쉽게 차단됨. 포트(IP) 풀은 넉넉히(회전 여유)
|
||||
- 워커 여러 개는 **워커별 Chrome 프로필 분리 + 다른 프록시 IP**(이미 `WORKER_CONCURRENCY`로 자동 처리)
|
||||
- 시크릿(config.local.toml)은 이미지에 굽지 말고 **마운트** 권장
|
||||
- **비용**: 대역폭이 원가의 대부분(오픈마켓 크롤) — 같은 상품 재크롤을 줄이는 TTL 캐시가 다음 절감 후보
|
||||
## 7. Docker 배포
|
||||
|
||||
```bash
|
||||
# 루트에서 (DB 는 외부 PostgreSQL, host.docker.internal 로 연결)
|
||||
docker compose build lps-api lps-worker
|
||||
docker compose up -d lps-api lps-worker
|
||||
docker logs -f lps-worker # 웜업·검색 로그
|
||||
docker ps # lps-worker "(healthy)" 확인
|
||||
```
|
||||
- **워커 = 헤드풀 Chromium + Xvfb**(`Dockerfile.worker`): **headless 는 Akamai·Cloudflare Turnstile 에 탐지됨**(실측). Xvfb 가상 디스플레이로 headful 실행.
|
||||
- **API = lean**(`Dockerfile`, 브라우저 불필요).
|
||||
- **시크릿은 이미지에 안 굽고 env 주입**: `OPENAI_API_KEY`·`DECODO_*`·`NAVER_KEYS` (compose 주석 참고). 로컬은 config.local.toml.
|
||||
- **Chrome 프로필 영속 볼륨**(`lps-profiles:/profiles`, `LPS_PROFILE_DIR`): 재시작해도 cf_clearance 유지 → 재웜업 회피.
|
||||
- **워커 헬스**: HEALTHCHECK(하트비트<120s)로 행 워커 감지. k8s 는 liveness probe 로 자동 재시작 연결.
|
||||
|
||||
**남은 배포 과제**: API 인증·레이트리밋(비용 남용 방지), 다중 레플리카 시 분산 레이트리밋/프록시 IP 조정.
|
||||
**비용**: 대역폭이 원가의 대부분(오픈마켓 크롤) — 같은 상품 재크롤을 줄이는 **TTL 캐시**가 다음 절감 후보.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user