개요 — 무엇을 하나
Infrastructure ▸ Connectivity & Traffic ▸ 트래픽(/infra/traffic/net)은 각 서버의 네트워크 I/O 처리량(인바운드·아웃바운드 바이트·패킷)을 서버 카드마다 하나의 ECharts 선그래프로 표시하는 읽기 전용 관제 화면입니다.
원천은 레거시 수집기 check_tx.js가 채우는 server_traffic 테이블(≈160만 행, legacy_glory 커넥션). 이 테이블에는 수집 window 별로 서버×방향(inbound/outbound)의 delta 바이트·패킷이 쌓여 있지만, 구 stats-design UI 는 server_status 의 traffic-out(아웃바운드 패킷 델타 하나)만 보여줬습니다. 이 화면은 인/아웃 양방향 × 바이트·패킷 전량을 처음으로 표면화합니다.
세 자매 화면(포트·IP·트래픽)은 같은
TrafficController와SessionQueryService를 공유하지만, 트래픽 탭만 세션 스냅샷(traffic_session_ct)이 아니라server_traffic처리량 시계열을 읽습니다. 그래서 timer(1/5/60분)가 아니라 range(1h/6h/24h) 로 창을 잡습니다.
언제 쓰나
- 특정 서버의 대역폭 스파이크·급증을 시간대별로 확인할 때(예: 야간 백업 전송, 대용량 다운로드, DDoS 유입).
- 인:아웃 비율로 서버 성격을 판단할 때(웹 서버는 out 우세, 백업 수신 노드는 in 우세).
- 아웃바운드 패킷/바이트가 갑자기 튀는 노드를 골라 Security ▸ Threats·IP 조사로 넘어가기 전 1차 스크리닝.
- 활성 서버 신선도(수집이 밀린 노드)를 KPI 로 빠르게 파악할 때.
화면 구성
Hero (상단바)
| 요소 | 설명 |
|---|---|
| 지표 토글 | 바이트 | 패킷 — 같은 데이터를 바이트/패킷 축으로 전환(서버 왕복 없이 프론트에서 재도색) |
| range 토글 | 1시간(60) | 6시간(360) | 24시간(1440) — 표시 창(분). 선택은 localStorage 영속 |
| 스탬프 | 최신 window 시각(server_traffic MAX + 표시 시간대 보정) |
| 새로고침 | 즉시 재조회(30초 자동 폴링과 별개) |
| 전체화면 | 상단 네비를 숨기고 카드 그리드만 확대(ESC 해제) |
KPI 스트립 (흐름: 인·아웃·패킷·비율 → 핫스팟 → 신선도)
| KPI | 의미 |
|---|---|
| 전체 인 | 모든 서버 최신 포인트의 인바운드 바이트 합 |
| 전체 아웃 | 모든 서버 최신 포인트의 아웃바운드 바이트 합 |
| 총 패킷 | 각 서버 마지막 (인+아웃) 패킷 합 · /윈도우 단위(누적 아님) |
| 인:아웃 | out ÷ in(소수 1자리) → 1 : x 형태. in 이 0 이면 — |
| 최다 | 최신 아웃바운드 바이트가 가장 큰 서버(핫스팟) |
| 활성 서버 | 마지막 포인트가 window 종료 15분 이내인 서버 수 / 전체. 미달이면 노랑 경고 |
규모 색상 레전드 + Y축 스케일
선·면적 색은 값의 규모를 뜻합니다(ECharts visualMap piecewise). 값이 임계를 넘으면 색이 바뀌어 스케일을 색으로 감각합니다.
| tone | 바이트 | 패킷 |
|---|---|---|
| info | < 1MB |
< 1K |
| good | 1–10MB |
1–10K |
| warn | 10–100MB |
10–100K |
| crit | > 100MB |
> 100K |
- 선 형태로 방향 구분: 아웃바운드 = 실선 + 짙은 면적, 인바운드 = 점선 + 얕은 면적. 헤더 화살표(↓ in / ↑ out)·툴팁으로도 구분.
- Y축 스케일 토글:
선형(기본, min 0 고정 → 면적 정직) |로그(KB~MB 를 한 축에 압축해 인·아웃 동시 가시). 선택은localStorage영속.
서버 트래픽 카드
각 카드 = 서버 1대. 헤더에 호스트명 + 현재 인/아웃 바이트, 본문에 200px 높이 <metric-chart>(ECharts 동적 import) 선그래프.
- 드래그 재정렬: 그립(⋮)으로 카드 순서를 바꾸면
infr:order:traffic-net로 영속. - masonry 레이아웃 + 페이지당 12장.
- 시간축 고정: 모든 카드가
win.since ~ win.until(공유 창)로 X축을 고정합니다. 수집이 밀린 서버는 왼쪽 스텁으로 정직하게 표시되어, 소수 포인트를 카드 전폭으로 늘려 가짜 곡선을 만드는 일이 없습니다.
사용법
- range 선택 — 스파이크 추적은
1시간, 하루 패턴은24시간. - 지표 전환 — 대역폭 부하는
바이트, 연결/PPS 성격은패킷. - 로그 축 — in·out 규모 차가 큰 서버(웹처럼 out ≫ in)는
로그로 두면 두 곡선이 함께 보입니다. - 카드 정렬 — 관심 서버를 위로 드래그(브라우저에 저장됨).
- 핫스팟 추적 — KPI
최다서버나 crit(빨강) 곡선을 발견하면 포트 연결·IP 연결로 넘어가 어떤 IP·포트가 유발했는지 조사합니다.
툴팁은
HH:MM헤더 + 시리즈별 값(인/아웃)을 함께 보여줍니다. 카드 폭은 좁아도 시간축이 겹치지 않게 라벨을 자동 숨김(hideOverlap)합니다.
데이터 소스
server_traffic (legacy_glory · 읽기 전용)
| 컬럼 | 용도 |
|---|---|
server_name, server_index |
서버 식별 |
time_window_start |
수집 window 시작(약 300초=5분 간격) |
direction |
inbound | outbound |
delta_bytes_count |
이 window 의 바이트 델타 |
delta_packet_count |
이 window 의 패킷 델타 |
원천 쿼리(TrafficRepository::serverTraffic)는 파라미터 바인딩으로 좁은 창만 긁습니다(하드코딩·문자열 보간 금지):
SELECT server_name, server_index, time_window_start, direction,
delta_packet_count, delta_bytes_count
FROM server_traffic
WHERE time_window_start >= :since -- (최신 window) − range
ORDER BY time_window_start
LIMIT 6000;
앵커 = MAX(time_window_start)(인덱스 MAX → 값쌉니다). since = 앵커 − range분.
분 버킷 정규화 (톱니 방지)
수집기
check_tx.js는 inbound·outbound 를 루프 안에서 각각new Date()로 stamp 하므로 같은 5분 사이클인데time_window_start가 1~2초 어긋납니다(예::02in /:03out). 정확한 timestamp 로 그룹핑하면 매 시점에 in·out 중 하나만 잡혀 나머지가 0 이 되어 톱니 차트가 됩니다.
해결: SessionQueryService::reshapeNet 이 timestamp 를 분 버킷(반올림 round(ts/60)*60) 으로 뭉쳐 in/out 을 한 포인트로 합칩니다. 윈도우 간격(300초)이 버킷(60초)보다 훨씬 커서 인접 윈도우 충돌은 없습니다.
표시 시간대 보정
레거시 DB 저장 시각과 표시 시각이 다를 수 있어(실측 ~9시간 시차) OpsPolicy::trafficTzOffsetSec() 만큼 표시값만 보정합니다(스탬프·시간축·시리즈 timestamp). SQL 경계(min/max)에는 적용하지 않습니다 — 쿼리는 레거시 시각 그대로.
캐시 · 폴링
- 서버측
Cache::remember('infr:traffic:net:v1:<range>', 30, …)— 30초 캐시. - 프론트 30초 자동 폴링(
/infra/traffic/net/live?range=<분>).
권한
- 읽기 전용 화면. 쓰기·차단 등 파괴적 작업 없음.
- Infrastructure 역할 영역이므로 최소 user_level 1(demo=1)이면 열람 가능. staff(5)·admin(10)도 물론 접근.
- 라우트는
infr.auth미들웨어로 보호(세션 인증 필수). - 원천 접속 자격은
config('database.connections.legacy_glory')(=.env)만 사용 — 컨트롤러/서비스에 크리덴셜 하드코딩 없음.
문제해결 · FAQ
Q. "트래픽 샘플이 없습니다" 만 보입니다.
server_traffic 에 최근 window 가 없다는 뜻. check_tx.js 수집기가 도는지, legacy_glory 커넥션이 유효한지 확인합니다. latestTrafficWindow()(MAX)가 null 이면 카드가 비고 KPI 는 0.
Q. 어떤 서버가 왼쪽에만 짧게 그려집니다.
정상 동작입니다. 시간축을 공유 창으로 고정하므로, 수집이 밀린 서버는 마지막 관측 지점까지만 그려지는 왼쪽 스텁으로 정직하게 표시됩니다. KPI 활성 서버 에서도 비활성으로 잡힙니다(마지막 포인트가 window 종료 15분 밖).
Q. 인·아웃 곡선이 한쪽만 톱니처럼 튑니다.
분 버킷 정규화가 대부분 잡지만, 수집 window 자체가 불규칙하면 잔여 톱니가 남을 수 있습니다. 로그 축으로 두면 완화됩니다.
Q. 값이 누적(cumulative)인가?
아니다. delta_* = window(약 5분)당 증분입니다. KPI 총 패킷 이 /윈도우 로 표기되는 이유. 누적 카운터가 아니다.
Q. 시각이 실제보다 몇 시간 어긋납니다.
OpsPolicy 의 traffic_tz_offset 설정으로 표시 시간대를 보정합니다(운영 정책 참조).
관련 항목
- 포트 연결 (Port Connections) — 포트·서버별 TCP 상태 분포 + 상위 소스 IP
- IP 연결 (IP Connections) — 서버별 원격 peer IP × 포트 강도 + IP 심층 조사 팝업
- Servers (서버 부하 시계열) — load/CPU/MEM 시계열, 같은 ECharts
<metric-chart>패턴 - Health (노드 헬스) — 노드별 CPU 링·서비스 도트
- 운영 정책 (Operations Policy) —
traffic_tz_offset·감시 포트 등 전역 설정
