docs(lps): 2026-08-07 세션 기록 — IP 로테이션 검수·네이버 UA 규명·결과 상태 정의
다음 세션이 이어받을 수 있게 남긴다. - docs/2026-08-07-session-notes.md 신규: 세 덩어리(IP 로테이션 결함 6개, 네이버 컨테이너 차단이 실은 UA 플랫폼 토큰이었다는 규명, '못 봤다'를 '없다'고 말하던 문제의 4단계 해결)와 **되돌리기 전에 볼 근거**(예산을 IP 에 묶는 이유, 태우지 않는 판정, 임대 없이 크롤 금지, UA 는 플랫폼만 바꾸고 버전은 실값, 상태는 하나로 저장하고 표시에서 접기). - 미해결: 쿠팡 간헐 차단 — IP 에 따라 갈리므로 환경이 아니라 평판. 쿠팡만 gate(해외 IP)를 쓰는 게 유력한 원인이고, 네이버처럼 kr_host 로 바꾸는 검증이 중단된 상태. - 다음 할 일 5가지(운영 마이그레이션 → 쿠팡 KR 검증 → 예산 튜닝 → AI 매칭 정확도 → admin 잡목록). - 주의사항 5가지: **마이그레이션→코드 순서 강제**(역순이면 최저가 조회가 통째로 실패, 재현 확인), 워커 켜고 pytest 하면 test_job_queue 3개 깨짐, JS 지문 위장은 patchright 가 막아 불가, 로컬 negodata-front 는 node_modules 가 named volume 이라 재빌드로 의존성이 안 늘어남. - README 문서 표에 링크 추가. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
0c6c431f0a
commit
7dc925bcd4
@ -198,6 +198,7 @@ docker compose up -d # negosium 스택 + lps-api·lps-worker·lps
|
|||||||
| **[데이터베이스](docs/database.md)** | 개발자/기획자 | 테이블 6종 구조와 코드값(+by_mall·ip_session·proxy_port 장부) |
|
| **[데이터베이스](docs/database.md)** | 개발자/기획자 | 테이블 6종 구조와 코드값(+by_mall·ip_session·proxy_port 장부) |
|
||||||
| **[API 사용법](docs/api.md)** | 연동 개발자 | 엔드포인트·요청/응답·metrics 예시 |
|
| **[API 사용법](docs/api.md)** | 연동 개발자 | 엔드포인트·요청/응답·metrics 예시 |
|
||||||
| **[운영 가이드](docs/operations.md)** | 운영자/개발자 | 실행·병렬·관측(readyz/ops/알림)·**Docker 배포**·문제 해결 |
|
| **[운영 가이드](docs/operations.md)** | 운영자/개발자 | 실행·병렬·관측(readyz/ops/알림)·**Docker 배포**·문제 해결 |
|
||||||
|
| **[2026-08-07 세션 기록](docs/2026-08-07-session-notes.md)** | 팀 | 직전 작업 요약 — 결정 근거·미해결(쿠팡 차단)·다음 할 일·주의사항 |
|
||||||
| **[크롤러 논의](docs/decision-openmarket-crawler.md)** | 팀 | 오픈마켓 크롤러 유지 여부(ROI) 의사결정 메모 |
|
| **[크롤러 논의](docs/decision-openmarket-crawler.md)** | 팀 | 오픈마켓 크롤러 유지 여부(ROI) 의사결정 메모 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
87
lps/docs/2026-08-07-session-notes.md
Normal file
87
lps/docs/2026-08-07-session-notes.md
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
# 2026-08-07 작업 기록 — IP 로테이션 검수 · 네이버 컨테이너 차단 규명 · 결과 상태 정의
|
||||||
|
|
||||||
|
다음 세션이 이어받을 수 있도록 **무엇이 왜 바뀌었고, 무엇이 남았는지**만 적는다.
|
||||||
|
상태 정의는 `result-states.md`, 운영 절차는 `operations.md` 가 소스다.
|
||||||
|
|
||||||
|
## 1. 무슨 일이 있었나
|
||||||
|
|
||||||
|
세 덩어리다. 앞의 둘은 "고장 났다"에서 출발했고, 셋째는 그 과정에서 드러난 설계 문제다.
|
||||||
|
|
||||||
|
**① IP 로테이션이 설계대로 안 돌고 있었다.** 검수해 보니 결함이 6개였고, 그중 하나는
|
||||||
|
`bot_detection.ip_request_no` 를 항상 `1` 로 만들어 **과거 진단 결론까지 오염**시켰다.
|
||||||
|
|
||||||
|
**② 컨테이너에서 네이버만 막혔다.** 원인은 컨테이너가 아니라 **UA 의 플랫폼 토큰**이었다.
|
||||||
|
네이버는 리눅스 데스크톱 Chrome 을 HTTP 405 로 거부한다.
|
||||||
|
|
||||||
|
**③ '못 봤다'를 '없다'고 말하고 있었다.** 차단당해 확인 못 한 몰이 화면에서 '없음(–)'과
|
||||||
|
구분되지 않았다. 상태를 정의하고 4단계로 화면까지 연결했다.
|
||||||
|
|
||||||
|
## 2. 지금 상태
|
||||||
|
|
||||||
|
| 항목 | 상태 |
|
||||||
|
|---|---|
|
||||||
|
| 네이버 | 컨테이너에서 정상(UA 보정). 검색당 40건 |
|
||||||
|
| 쿠팡 | **간헐적 차단** — 해외 IP(`gate`) 사용이 원인으로 추정(아래 4번) |
|
||||||
|
| IP 로테이션 | 예산·회전·소각이 모두 의도대로. 서킷브레이커가 풀 고갈 차단 |
|
||||||
|
| 결과 상태 | 몰별 7상태 → 운영자 화면은 그대로, 사용자 화면은 3가지로 접음 |
|
||||||
|
| 잡 | 한 소스가 막혀도 정상 종료(DEAD 아님) |
|
||||||
|
| 테스트 | lps 292 · negodata 107 passed |
|
||||||
|
| 배포 | 로컬 전체 재빌드·기동 완료. **운영은 마이그레이션 미적용**(아래 5번) |
|
||||||
|
|
||||||
|
## 3. 이번에 정한 것 (되돌리려면 근거부터 볼 것)
|
||||||
|
|
||||||
|
- **예산은 브라우저가 아니라 IP 에 묶는다.** 유휴 정리(120s)는 브라우저만 닫고 같은 IP 로
|
||||||
|
돌아오는데, 브라우저 기준으로 세면 카운터가 매번 초기화돼 **예산이 영영 발화하지 않는다**
|
||||||
|
(실측: 6회 검색이 전부 같은 포트·`ip_req#1`). 시계도 하나(`_session_started_at`)로 통일했다.
|
||||||
|
- **회전해도 소용없는 차단은 IP 를 태우지 않는다.** 서로 다른 IP 3개가 연속으로 **첫 요청부터**
|
||||||
|
막히면 IP 문제가 아니다(평판이면 몇 개는 통과하고, 과사용이면 뒤쪽에서 막힌다). 임계 없이
|
||||||
|
태우면 잡 16건에 100포트가 30분 쿨다운으로 묶인다. 성공 1회로 자동 해제된다.
|
||||||
|
- **임대 없이는 크롤하지 않는다.** 풀이 마르면 예전엔 계산식으로 포트를 골라 **남이 쥔 IP 를
|
||||||
|
같이 썼다**(실측 재현). 장부가 막으려던 바로 그 문제라, 못 잡으면 실패하는 게 맞다.
|
||||||
|
- **UA 는 플랫폼 토큰만 바꾸고 버전은 실제 값을 쓴다.** 통째로 하드코딩하면 컨테이너 Chrome 이
|
||||||
|
업데이트될 때 UA 와 엔진이 어긋나 그 불일치가 새 봇 신호가 된다. 쿠팡은 잘 통과하므로 안 건드린다.
|
||||||
|
- **상태는 하나로 정의·저장하고 표시 단계에서 접는다.** 저장을 단순화하면 운영자가 원인을 못 보고,
|
||||||
|
표시를 상세화하면 사용자가 못 읽는다. `partial` 을 컬럼으로 둔 것도 같은 이유 — 소비자가
|
||||||
|
'어떤 상태가 확인된 것인가'라는 판단 규칙까지 알면 상태 정의가 두 곳으로 흩어진다.
|
||||||
|
- **부분 실패의 `not_found` 는 네거티브 캐시에 넣지 않는다.** 못 본 몰에 있었을 수 있는데
|
||||||
|
'없음'으로 굳히면 TTL 동안 재검색이 막힌다(사용자가 '다시 검색'을 눌러도 캐시 히트).
|
||||||
|
|
||||||
|
## 4. 미해결 — 쿠팡 간헐적 차단
|
||||||
|
|
||||||
|
`사용권한이 제한된`(3.4KB)·`errors.edgesuite.net`(0.4KB) 마커로 막히는데 **IP 에 따라 갈린다**
|
||||||
|
(일부는 통과 → 서킷브레이커가 자동 해제). 즉 환경이 아니라 **IP 평판** 쪽이다.
|
||||||
|
|
||||||
|
유력한 원인: **쿠팡만 `gate`(국가 무지정 = 해외 IP)를 쓴다.** 네이버는 `kr_host`(한국 IP)로
|
||||||
|
바꾼 뒤 안정됐다. 같은 처방이 통할 가능성이 높다.
|
||||||
|
|
||||||
|
> 검증하려던 스크립트가 도구 시간 제한으로 중단됐다. 컨테이너에서 `gate` vs `kr` 통과율을
|
||||||
|
> IP 3개씩 비교하면 된다(네이버 UA 검증과 같은 방식).
|
||||||
|
|
||||||
|
⚠️ 맥 컨테이너는 amd64 를 **Rosetta 로 에뮬레이션**한다. 여기서 쿠팡이 막히는 건 실서버와
|
||||||
|
다를 수 있다 — 실서버에선 쿠팡이 60건 정상이었다. 판단은 실서버 로그로 한다.
|
||||||
|
|
||||||
|
## 5. 다음에 할 일 (우선순위)
|
||||||
|
|
||||||
|
1. **운영 DB 마이그레이션 적용** — 아직 안 됐다. 순서가 중요하다(아래 6번).
|
||||||
|
`6_lps_2026-08_dbeaver.sql`(lps_db) · `2026-08-07-iilp-source-state.sql`(negosium_db)
|
||||||
|
2. **쿠팡 KR 게이트웨이 검증** — 4번. 지금 최저가 커버리지의 최대 구멍이다.
|
||||||
|
3. **예산 튜닝** — F1 수정으로 `ip_request_no` 가 **처음으로 실제 사용량을 반영**한다.
|
||||||
|
`ip_req#1` 위주면 IP 평판, `2` 이상이면 예산 하향. **2026-08-06 이전 데이터는 쓰지 말 것.**
|
||||||
|
4. **AI 매칭 정확도 측정** — 세션 초반에 접근법만 논의하고 미착수. 정답 세트 20~30개로
|
||||||
|
"몇 % 맞나"를 재야 한다. 지금도 최저가 품질의 최대 병목이다.
|
||||||
|
5. lps-admin **잡 목록**에 몰별 상태 노출(상품 화면엔 이미 있음, 우선순위 낮음).
|
||||||
|
|
||||||
|
## 6. 작업 시 주의
|
||||||
|
|
||||||
|
- **마이그레이션 → 코드 순서를 지킬 것.** negodata 가 ORM 전체 엔티티를 조회하므로
|
||||||
|
(`lps_sync_crud.py:96`), 컬럼이 없는 DB 에 새 코드가 붙으면 **최저가 조회가 통째로 실패**한다
|
||||||
|
(재현 확인). 역순(마이그레이션 후 옛 코드)은 안전하다 — 옛 컨테이너로 실증했다.
|
||||||
|
- **워커를 켜 둔 채 pytest 하면 `test_job_queue` 3개가 깨진다.** 워커가 테스트 잡을 집어가서다.
|
||||||
|
코드 문제가 아니다 — `docker compose stop lps-worker` 후 돌리면 292 passed.
|
||||||
|
- **JS 로 브라우저 지문을 덮는 방법은 이 스택에서 통하지 않는다.** patchright 가
|
||||||
|
`add_init_script`(CDP 주입)를 무력화하고, MV3 확장도 값이 안 바뀐다. 다시 시도하기 전에
|
||||||
|
`services/search/fingerprint.py` docstring 을 볼 것.
|
||||||
|
- **로컬 dev 의 `negodata-front` 는 `node_modules` 가 named volume 이다.** 의존성이 늘면
|
||||||
|
이미지를 다시 빌드해도 반영되지 않는다 — 컨테이너 안에서 `npm install` 해야 한다(prod 은
|
||||||
|
`Dockerfile.prod` 라 해당 없음).
|
||||||
|
- 테스트가 실DB를 TRUNCATE 하는 문제는 그대로다(`price_history`·`job`·`ip_session`·`bot_detection`).
|
||||||
Loading…
Reference in New Issue
Block a user