Reorganize the SRS (Simple Realtime Server) repository to follow a conventional Go project structure, setting the stage for a progressive transition from a C++ project to a Go project. The proxy, which was once contained within its own `proxy/` subdirectory, will now be converted into the initial Go module located at the root of the repository, serving as a template for subsequent Go modules. - **Go module at repo root:** `go.mod` moved to repo root, module renamed from `proxy` to `srsx`. The repo is now a proper Go project with `cmd/` and `internal/` at the top level. - **Elevation of Proxy Code:** Move the proxy code from `proxy/cmd/proxy-go/` to `cmd/proxy/`, and from `proxy/internal/` to `internal/`. The proxy serves as the inaugural application; subsequent modules (for instance, `cmd/origin`) will mimic this arrangement. - **Documentation Restructured:** Transfer the documentation from `proxy/docs/` to `docs/proxy/`, revise the main README to endorse OpenClaw as the preferred AI tool, and update `proxy/README.md` to point to the new documentation locations. - **Build and config:** `Makefile` moved to root, `PROXY_STATIC_FILES` default path corrected for the new layout, `.gitignore` consolidated. - **Cleanup:** removed standalone `proxy/LICENSE` (repo-level license applies), all internal imports updated to `srsx/internal/...`. - **OpenClaw workspace:** added community bot info, git workflow conventions, and support group behavior guidance. This restructuring was performed by OpenClaw orchestrating Claude Code and Codex via ACP. --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
5.3 KiB
Load Balancer
Overview
The proxy load balancer distributes client streams across multiple backend origin servers. It provides a pluggable interface with two implementations:
- Memory Load Balancer - For single proxy deployments
- Redis Load Balancer - For multi-proxy deployments with shared state
Both implementations maintain stream-to-server mappings to ensure stream consistency - once a stream is assigned to a backend server, all subsequent requests for that stream route to the same server.
Core Responsibilities
- Server Management
Backend Server Registration:
- Origin servers register themselves with the proxy via System API
- Servers provide their endpoints for each protocol (RTMP, HTTP, WebRTC, SRT)
- Registration includes server identity (ServerID, ServiceID, PID)
- Heartbeat mechanism maintains server health status
Server Selection:
- Pick appropriate backend server for new streams
- Consider server health (last heartbeat time)
- Random selection from healthy servers for load distribution
- Maintain stream-to-server mapping for consistency
- Stream State Management
Protocol-Specific State:
-
HLS Streams: Dual-index storage for M3U8 playlists and TS segments
- Index by stream URL for initial playlist requests
- Index by SPBHID (SRS Proxy Backend HLS ID) for segment requests
-
WebRTC Connections: Dual-index for session management
- Index by stream URL for initial connection setup
- Index by ufrag (ICE username) for STUN binding requests
- Load Balancing Strategy
Stream-Level Stickiness:
- First request for a stream selects a backend server
- All subsequent requests for that stream use the same server
- Ensures session continuity and state consistency on backend
Health-Based Selection:
- Only consider servers with recent heartbeats (within 300 seconds)
- Fallback to any registered server if no healthy servers available
- Random selection among healthy servers for even distribution
Architecture
The load balancer uses a clean interface-based architecture:
Core Interface: SRSLoadBalancer
- Initialization and lifecycle management
- Server registration and updates
- Stream routing (Pick operation)
- Protocol-specific state management (HLS, WebRTC)
Data Models:
SRSServer: Backend origin server representationHLSPlayStream: Interface for HLS streaming sessionsRTCConnection: Interface for WebRTC connections
Memory Load Balancer
- Design
Storage: In-memory maps for fast access
- Server registry with thread-safe concurrent access
- Stream-to-server mappings
- Protocol-specific session state (HLS, WebRTC)
Use Case: Single proxy instance handling moderate stream counts
Characteristics:
- Lowest latency (no network operations)
- Simple deployment (no external dependencies)
- State limited to single proxy instance
- Best for deployments where proxy isn't the bottleneck
- Configuration
PROXY_LOAD_BALANCER_TYPE=memory
Redis Load Balancer
- Design
Storage: Shared Redis instance for distributed state
- All proxies read/write to same Redis
- TTL-based expiration for automatic cleanup
- JSON serialization for cross-process communication
Use Case: Multiple proxy instances sharing load
Characteristics:
- Enables horizontal scaling of proxies
- Higher latency (network + serialization overhead)
- Requires Redis infrastructure
- Best for large deployments with many streams
- Configuration
PROXY_LOAD_BALANCER_TYPE=redis
PROXY_REDIS_HOST=127.0.0.1
PROXY_REDIS_PORT=6379
PROXY_REDIS_PASSWORD=
PROXY_REDIS_DB=0
- Redis Key Design
Server Keys:
srs-proxy-server:{serverID}- Server registration (300s TTL)srs-proxy-all-servers- Server list index (no expiration)
Stream Mapping Keys:
srs-proxy-url:{streamURL}- Stream-to-server mapping (no expiration)
Session State Keys:
srs-proxy-hls:{streamURL}- HLS by URL (120s TTL)srs-proxy-spbhid:{spbhid}- HLS by SPBHID (120s TTL)srs-proxy-rtc:{streamURL}- WebRTC by URL (120s TTL)srs-proxy-ufrag:{ufrag}- WebRTC by ufrag (120s TTL)
Expiration and Cleanup
Server Heartbeat: 300 seconds
- Servers must send updates every 30 seconds (recommended)
- Considered dead if no update within 300 seconds
- Memory LB: filtered during selection
- Redis LB: automatic TTL expiration
Session State: 120 seconds
- HLS and WebRTC sessions expire after 120 seconds of inactivity
- Automatic cleanup via TTL (Redis) or garbage collection (Memory)
- Sessions renewed on each request
Stream Mappings: No expiration
- Stream-to-server mappings persist indefinitely
- Ensures consistent routing for long-running streams
- Only reset when backend server dies or mapping explicitly cleared
Comparison: Memory vs Redis
| Aspect | Memory Load Balancer | Redis Load Balancer |
|---|---|---|
| Deployment | Single proxy | Multiple proxies |
| State Storage | Local memory | Shared Redis |
| Latency | Lowest (in-process) | Network + serialization |
| Scalability | Single instance | Horizontal scaling |
| Dependencies | None | Redis required |
| Complexity | Simple | Moderate |
| Fault Tolerance | Single point of failure | Multiple proxies |
| Best For | Moderate traffic | High traffic, high availability |