프로젝트 소개
# IzgoN
IzgoN은 유사한 상태를 반복적으로 보고하는 장치 플릿을 위해 설계된 델타 동기화 서버입니다. 각 노드는 매 주기마다 전체 페이로드를 업로드하는 대신 현재 상태를 POST합니다. IzgoN은 이를 마지막으로 확인한 상태와 비교하여 `NO_CHANGE`(0바이트 페이로드), 최소한의 JSON 델타, 또는 델타가 대체할 상태보다 클 경우 전체 상태를 반환합니다.
## 주요 기능
- **델타 동기화**: 변경된 필드만 장치로 다시 전송되어 응답 페이로드를 획기적으로 줄입니다.
- **조건부 동기화(v1.4.0 이상)**: 변경 사항이 없는 장치는 전체 보고서 대신 짧은 체크섬 토큰을 보낼 수 있어 보고서 자체가 네트워크로 전송되지 않습니다.
- **절감량 측정**: 대시보드와 `/api/metrics` 엔드포인트는 양방향(응답 및 업링크)의 실시간 바이트 절감량을 보여줍니다.
- **벤치마크 도구**: `benchmark.py`(표준 라이브러리만 사용)는 실제 보고서를 재생하여 데이터에 대한 절감량을 측정하며, 테스트용 합성 모드도 제공합니다.
- **적응형 폴링 제안**: 서버는 동일한 보고서가 여러 번 연속된 후 더 긴 보고 간격을 제안할 수 있으며, 명시적인 지연( staleness) 트레이드오프를 제공합니다.
- **무응답 알림**: 노드가 보고를 중단하거나 다시 보고할 때 웹훅 알림을 보냅니다.
- **배치 동기화**: 오프라인 동안 버퍼링된 장치는 한 번의 요청으로 큐를 플러시할 수 있습니다.
- **무료 티어**: 라이선스 키 없이 10,000회 동기화를 제공하여 평가에 충분합니다.
## 작동 방식
노드는 `state`(또는 변경이 없으면 `checksum`만) 내부에 상태를 보냅니다. 서버는 다음 네 가지 상태 중 하나로 응답합니다:
- `NO_CHANGE` — 변경 사항 없음, 전송된 바이트 0개.
- `SYNC_REQUIRED` — 변경된 키만 반환되며, 클라이언트가 이를 병합합니다.
- `FULL_STATE` — 전체 새 상태가 반환됩니다(델타가 더 클 때).
- `SEND_STATE` — 서버에 기준선이 없거나 체크섬을 알 수 없습니다. 클라이언트는 전체 상태를 다시 보내야 합니다.
중첩 객체는 재귀적으로 비교되며, 목록은 전체로 비교됩니다(의도된 제한 사항). 선택적 `epoch` 토큰은 서버 재시작 또는 미러 손실 후 전체 상태를 강제하여 무음 동기화 손실을 방지합니다.
## 빠른 시작
```bash
docker run -p 8000:8000 -e DATAPULSE_API_KEY=change-me ghcr.io/izgamber/izgon:latest
```
또는 Docker Compose 사용(영구 기준선을 위한 Redis 포함):
```bash
git clone https://github.com/izGamber/IZgoN.git
cd IZgoN
cp .env.example .env
docker compose up -d
```
대시보드: `http://localhost:8000`. 상태 보내기:
```bash
curl -X POST http://localhost:8000/api/nodes/sensor-01/sync \
-H "Content-Type: application/json" \
-H "X-API-Key: dev-local-key" \
-d '{"state": {"temp": 21.5, "hum": 60, "batt": 98}}'
```
동일한 상태를 반복하면 델타 바이트가 0인 `NO_CHANGE`가 반환됩니다. 한 필드를 변경하면 해당 필드만 반환됩니다.
## 자체 데이터로 벤치마크
```bash
python3 benchmark.py --payload-file my-reports.json
```
JSON 배열 또는 JSON Lines를 허용하며, 장치 ID 필드를 자동 감지하고 데이터의 변경률을 측정합니다. 합성 모드: `python3 benchmark.py --nodes 50 --rounds 100 --change-rate 0.05`.
측정된 절감량(5% 변경률): 응답 약 94%, 업링크(심당) 약 40%, 폴링 클라이언트 약 65%. 변경률 70%에서는 절감량이 약 35%로 떨어집니다 — 이것이 정직한 한계입니다.
## API 엔드포인트
| 메서드 | 경로 | 인증 | 용도 |
|---|---|---|---|
| POST | `/api/nodes/{id}/sync` | API 키 | 상태 또는 체크섬 제출, 델타/전체/NO_CHANGE 수신 |
| POST | `/api/nodes/{id}/sync/batch` | API 키 | 버퍼링된 큐를 한 번의 요청으로 재생 |
| GET | `/api/nodes` | API 키 | 노드 및 기준선 목록(페이지네이션) |
| GET | `/api/metrics` | 없음 | 실시간 바이트 절감량 합계 |
| GET | `/api/license` | 없음 | 현재 티어 및 남은 무료 동기화 수 |
| GET | `/healthz` | 없음 | Redis 연결 가능 여부, 저장소 모드 |
| GET | `/` | 없음 | 대시보드 |
## 구성
모든 설정은 환경 변수를 통해 이루어집니다(`.env.example` 참조). 주요 항목:
- `DATAPULSE_REDIS_URL` — 기준선용 Redis 연결
- `DATAPULSE_API_KEY` — 인증 키(기본값 `dev-local-key`, 변경 필요)
- `DATAPULSE_FREE_TIER_LIMIT` — 402 오류 전 무료 동기화 수(기본값 10000)
- `DATAPULSE_LICENSE_KEY` — 유료 라이선스 키(Ed25519 서명, 오프라인 검증)
- `DATAPULSE_ALERT_URL` / `DATAPULSE_ALERT_AFTER` — 무응답 알림
- `DATAPULSE_ADAPTIVE` — 폴링 간격 제안 활성화/비활성화
- `DATAPULSE_MAX_STATE_DEPTH` / `DATAPULSE_MAX_STATE_BYTES` — 페이로드 제한
## 보안 참고 사항
- API 키가 모든 쓰기를 보호하며, 일정 시간 비교를 사용합니다.
- `/api/metrics` 및 `/healthz`는 설계상 인증이 없습니다.
- CORS 기본값은 `*`입니다. 프로덕션에서는 좁혀야 합니다.
- 내장 속도 제한이 없으므로 리버스 프록시 뒤에 두십시오.
- 상태는 깊이(32)와 크기(1MB)로 제한됩니다.
## 제한 사항
- 목록은 요소별로 비교되지 않습니다. 한 항목을 변경하면 전체 목록이 전송됩니다.
- 페이로드 축소는 `FULL_STATE`를 트리거할 수 있습니다(해당 동기화에서는 절감 없음).
- 모든 노드의 첫 보고서는 항상 전체입니다.
- 기준선은 Redis에 저장됩니다. 삭제되면 노드는 한 번 재동기화합니다.
- 단일 인스턴스, 클러스터링 없음.
- 아직 클라이언트 SDK가 없습니다. 통합은 일반 HTTP POST입니다.
## 라이선스 및 가격
소스 공개(Source-available)이며 오픈소스는 아닙니다. 무료 티어: 10,000회 동기화. 상업용 라이선스: 일회성 결제, 구독 없음, 오프라인 Ed25519 서명 검증. 전화 집(phone-home) 없음.
## 상태
버전 1.4.2. 한 사람이 구축 및 유지 관리합니다. 라이브 데모: `https://izgon-api.onrender.com` (첫 요청은 20~40초 걸릴 수 있음).
Comments
0 Rating appears after 10 ratings
Sign in to join the discussion.