마지막 업데이트 2026-07-22
removeChild NotFoundError)가 동반 출력됨.
아동: 아동004 (userId 4d5630b7-…-51368c11177a) · 환경: prod · 단말: Realtek 오디오 + Samsung HD Camera (데스크탑/노트북 추정)
useNetworkQuality 는 10초 주기로 돌고 issue 전이 시점에만 로그를 남긴다. 따라서 실제 망 단절은 08:02:51 직전 10초 구간 안에서 시작됐고, 프로브가 도는 시점까지 복구되지 않은 것이다.
removeChild 에러는 끊김으로 인한 화면 해체 중 발생한 부수 증상이지 원인이 아니다.
user-network 판정(use-network-quality.ts:124)은 서로 다른 망/IDC의 3곳이 전부 3초 타임아웃으로 실패해야만 찍히도록 의도적으로 설계돼 있다. 우리 서버만 죽으면 issue: "server" 로 분기하므로, 3곳 동시 불통은 단말이 인터넷 자체를 잃었다는 강한 신호다.
| 프로브 | 대상 | 성격 | 결과 |
|---|---|---|---|
| 외부 #1 | gstatic.com/generate_204 | Google anycast 연결성 표준 | 실패 |
| 외부 #2 | 1.1.1.1/cdn-cgi/trace | Cloudflare anycast 폴백 | 실패 |
| 서버 | /api/health | 우리 서버 (serverLatency=null) | 실패 |
Grafana PPI Socket 상세 대시보드를 끊김 윈도우(08:00–08:05 UTC / 17:00–17:05 KST)로 맞춰 확인. 끊김 순간 서버는 어떤 부하·블로킹도 없었다.
| 지표 | 값 (08:00–08:05 UTC) | 판정 |
|---|---|---|
| 이벤트 루프 지연 | 30~48 µs (마이크로초), 08:02:51 전후 스파이크 없음 | 정상 |
| Mediasoup 워커 CPU (PID 19/20) | 0 → 0.003% (사실상 유휴) | 정상 |
| Node.js 메모리 RSS | ~140 MiB → 08:02:30경 ~128 MiB 하강 (세션 정리 회수) | 정상 |
| 접속/해제 비율 | 해제(disconnect)가 ~08:03:30 첫 틱업 | 끊김 인지 |
| 로그 레벨 | 전부 INFO, WARN/ERROR 없음 | 정상 |
서버에 남은 유일한 흔적은 ① 08:03:30의 정상 disconnect 카운트 틱, ② 세션 정리에 따른 RSS 소폭 회수뿐. 클라이언트가 인터넷을 잃어도 서버는 engine.io keepalive 만료까지 수십 초 지연되어 끊김을 인지하므로, 08:02:51 단절 → 08:03:30 서버 인지의 시차는 정상이다.
removeChild 에러는 부수 증상Uncaught NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
망이 끊기며 컴포넌트·비디오 엘리먼트가 언마운트되는 과정의 React DOM teardown 레이스(이미 제거된 노드를 다시 제거)다. 코드 내 실제 removeChild 호출은 전부 다운로드/iframe 정리용이라 세션 끊김과 무관하다. 외부 확장(번역 등)이 DOM을 건드릴 때도 동일 에러가 나며, 어느 경우든 이 에러가 접속을 끊은 것이 아니라 끊김으로 인한 화면 해체 중 발생한 것이다.
issue === "user-network" 진입 시 아동/진행자 양측에 "인터넷 연결을 확인해 주세요" 안내와 자동 재연결 진행 표시issue → "none" 전이) 시 세션 자동 복귀 경로 점검 — 끊김 윈도우의 socket transport state/reconnect 로그로 실제 복구 여부 확정NETWORK_QUALITY 진단의 전신. 외부 프로브가 httpbin → gstatic/cloudflare anycast로 교체된 배경.