- Create docs/ with 7 focused files: architecture, api, scoring, agent, deployment, freeswitch, development - Rewrite README.md as concise overview with links to docs/ - Remove AGENTS.md (content merged into docs/ and README)
118 lines
7.4 KiB
Markdown
118 lines
7.4 KiB
Markdown
# Architecture
|
|
|
|
## Overview
|
|
|
|
pulse-lets-go — балансировщик телефонной нагрузки на базе FreeSWITCH + NATS.
|
|
|
|
Агенты PBX отправляют метрики в NATS каждые 5 секунд. Балансировщик вычисляет weighted score готовности каждой ноды, кэширует лучшую и отдаёт её FreeSWITCH через `/api/route` для следующего звонка.
|
|
|
|
## Data Flow
|
|
|
|
```
|
|
┌─────────────────────┐ ESL/AMI ┌──────────────────────┐
|
|
│ PBX-01 │──────────▶│ pulse-lets-go-agent │
|
|
│ (FS or Asterisk) │ collect │ (on each PBX node) │
|
|
├─────────────────────┤ ├──────────────────────┤
|
|
│ PBX-02 │──────────▶│ pulse-lets-go-agent │
|
|
│ (FS or Asterisk) │ ├──────────────────────┤
|
|
├─────────────────────┤ ├──────────────────────┤
|
|
│ PBX-N │──────────▶│ pulse-lets-go-agent │
|
|
│ (FS or Asterisk) │ └─────────┬────────────┘
|
|
└─────────────────────┘ │ pulse.metrics.<id>
|
|
│ every 5s
|
|
▼
|
|
┌──────────────┐
|
|
│ NATS Server │
|
|
│ nats://:4222 │
|
|
└──────┬───────┘
|
|
│
|
|
▼
|
|
┌──────────────────────┐
|
|
│ pulse-lets-go │
|
|
│ │
|
|
│ ┌────────────────┐ │
|
|
│ │ NATS Sub │ │
|
|
│ │ (pulse.metrics)│ │
|
|
│ └────────┬───────┘ │
|
|
│ ▼ │
|
|
│ ┌────────────────┐ │
|
|
│ │ Engine │ │
|
|
│ │ (scoring) │──│──▶ /api/route
|
|
│ └────────┬───────┘ │ ↓
|
|
│ ▼ │ FreeSWITCH bridge
|
|
│ ┌────────────────┐ │ sip:pbx-03:5060
|
|
│ │ REST API │──│──▶ /api/nodes
|
|
│ │ (JWT auth) │ │ /api/trunks
|
|
│ └────────┬───────┘ │ /api/users
|
|
│ ▼ │
|
|
│ ┌────────────────┐ │
|
|
│ │ WebSocket │──│──▶ SvelteKit UI
|
|
│ └────────────────┘ │ (ws://:8080/ws/metrics)
|
|
│ ┌────────────────┐ │
|
|
│ │ ESL Client │──│──▶ FreeSWITCH ESL
|
|
│ │ (gateways) │ │ :8021
|
|
│ └────────────────┘ │
|
|
│ ┌────────────────┐ │
|
|
│ │ Monitoring │──│──▶ /api/monitoring/prometheus
|
|
│ │ (API-key) │ │ /api/monitoring/zabbix
|
|
│ └────────────────┘ │
|
|
└──────────────────────┘
|
|
```
|
|
|
|
## Components
|
|
|
|
| Component | Role |
|
|
|-----------|------|
|
|
| **pulse-lets-go** | Central balancer: NATS subscriber, scoring engine, REST API, WebSocket hub, ESL client |
|
|
| **pulse-lets-go-agent** | Per-PBX metrics collector (FreeSWITCH ESL / Asterisk AMI) |
|
|
| **NATS** | Message bus — `pulse.metrics.<node_id>` subject |
|
|
| **FreeSWITCH** | Softswitch — uses `route.lua` + `mod_curl` to query `/api/route` |
|
|
| **SvelteKit UI** | Dashboard with real-time metrics via WebSocket |
|
|
|
|
## Tech Stack
|
|
|
|
| Component | Technology |
|
|
|-----------|-----------|
|
|
| Backend | Go 1.26, stdlib `net/http` + `http.ServeMux` |
|
|
| Frontend | SvelteKit 2 + Tailwind CSS 4 + Lucide |
|
|
| Auth | JWT (golang-jwt/v5, HS256) + bcrypt |
|
|
| Message bus | NATS (nats.go) |
|
|
| Storage | JSON files (`data/`) |
|
|
| ESL | Raw TCP (no external libraries) |
|
|
| Deployment | Single binary + systemd |
|
|
|
|
## Data Flow Summary
|
|
|
|
1. **Agent** collects metrics from PBX (ESL/AMI + /proc) every 5s
|
|
2. **Agent** publishes `pulse.metrics.<node_id>` to NATS
|
|
3. **Balancer** NATS subscriber receives metrics, updates in-memory node state
|
|
4. **Scoring engine** recalculates scores, caches best node
|
|
5. **FreeSWITCH** dialplan calls `/api/route` via `mod_curl`
|
|
6. **Balancer** returns best node's `sip_gateway` (O(1) from cache)
|
|
7. **FreeSWITCH** bridges the call to the returned gateway
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
pulse-lets-go/
|
|
├── cmd/
|
|
│ ├── pulse-lets-go/ # Main entry point
|
|
│ ├── pulse-lets-go-agent/ # Metrics collector agent (FS / Asterisk)
|
|
│ ├── emulator/ # Metrics emulator for testing
|
|
│ └── siptest/ # SIP tester for e2e checks
|
|
├── internal/
|
|
│ ├── api/ # HTTP handlers (auth, nodes, trunks, users, monitoring, ws, route)
|
|
│ ├── config/ # JSON config manager (atomic save, thread-safe)
|
|
│ ├── engine/ # Scoring engine + router (sync.RWMutex, best-node cache)
|
|
│ ├── esl/ # FreeSWITCH ESL client (raw TCP)
|
|
│ ├── ami/ # Asterisk AMI client (raw TCP)
|
|
│ ├── log/ # ASCII metrics logger with rotation
|
|
│ ├── models/ # Data types (NodeMetric, NodeState, Trunk, User, ...)
|
|
│ └── nats/ # NATS subscriber
|
|
├── contrib/ # route.lua, agent configs
|
|
├── deploy/ # systemd unit
|
|
├── web/ # SvelteKit frontend
|
|
├── data/ # Runtime JSON files (gitignored)
|
|
└── docs/ # Documentation
|
|
```
|