如何搭建支持会话粘滞的可自动扩容nginx-rtmp集群?
Hey there! Let's walk through how to build an auto-scaling Nginx-RTMP cluster with session stickiness—so that the same stream (from a fixed camera source) always lands on the same backend server. Here's a practical breakdown tailored to your needs:
1. Core Architecture Overview
First, let's map out the setup you'll need:
- Fixed-IP Load Balancer: This acts as the single entry point for all your IP cameras. It routes push requests to your backend RTMP servers and handles session stickiness.
- Nginx-RTMP Backend Cluster: A group of servers running your existing Nginx-RTMP setup, configured to scale automatically (via cloud auto-scaling groups, for example).
- Session Stickiness Logic: Ensures that every push request from the same camera (or same stream key) gets sent to the exact same backend server every time.
2. Use Nginx as Your Load Balancer (Familiar & Flexible)
Since you're already using Nginx-RTMP, sticking with Nginx as your load balancer makes sense. Note that standard Nginx doesn't include the sticky session module by default—you'll need to compile it with --with-http_sticky_module, or use OpenResty (which comes pre-packaged with this and other useful modules).
2.1 Configure the Load Balancer Nginx
Here's a sample config that handles RTMP routing with stickiness:
http { # Define your backend RTMP server pool upstream rtmp_backends { # Enable cookie-based stickiness (expires after 1 hour) sticky name=rtmp_session expires=1h; # Add your initial backend servers server backend-rtmp-1:1935; server backend-rtmp-2:1935; # For auto-scaling: Use a service discovery tool like Consul + nginx-upsync-module # to automatically add/remove servers from this pool as your cluster scales } # Optional: Add a health check endpoint for backend servers server { listen 80; location /health { access_log off; return 200 "Healthy\n"; } } } rtmp { server { listen 1935; # Cameras push to this fixed IP:1935 application live { live on; # Forward push requests to the backend pool with stickiness push rtmp://rtmp_backends/live; # If you need stickiness based on stream key (instead of camera IP): # Use OpenResty's Lua scripting to map stream keys to fixed backends # Example Lua snippet (replace the push line above): # content_by_lua_block { # local stream_key = ngx.var.name # local backend_cache = ngx.shared.backend_cache # local backend = backend_cache:get(stream_key) # if not backend then # # Pick a backend via hash of the stream key # local backends = {"backend-rtmp-1", "backend-rtmp-2"} # local index = ngx.crc32_long(stream_key) % #backends + 1 # backend = backends[index] # backend_cache:set(stream_key, backend, 3600) # Cache for 1 hour # end # ngx.exec("rtmp://" .. backend .. "/live/" .. stream_key) # } } } }
2.2 Backend Nginx-RTMP Server Config
Your backend servers can use almost the same config you already have—just make sure they're set up to accept pushes from the load balancer:
rtmp { server { listen 1935; application live { live on; # Allow playback if needed allow play all; # Optional: Add recording or transcoding rules here # record all; # record_path /var/rtmp/recordings; } } }
3. Enable Auto-Scaling
To make your cluster auto-scale, pair your backend servers with a cloud auto-scaling group (like AWS EC2 Auto Scaling, Azure Virtual Machine Scale Sets). Then, use a service discovery tool to keep your load balancer's backend list up-to-date:
- Consul/Etcd: Backend servers register themselves with the service registry on startup. The load balancer uses
nginx-upsync-moduleto pull the latest server list automatically, no manual config edits needed. - Cloud Native LB: If you're using a cloud provider, their native load balancers (like AWS ALB) can handle TCP forwarding for RTMP with source-IP-based stickiness, and integrate directly with auto-scaling groups.
4. Choose the Right Stickiness Strategy
Pick the strategy that fits your camera setup:
- Source IP Stickiness: Perfect if each camera has a unique public IP. Use Nginx's
sticky ipdirective or your cloud LB's source-IP sticky session setting—super easy to configure. - Stream Key Stickiness: Use this if multiple cameras share an IP but use unique stream keys. The OpenResty Lua snippet above handles this by hashing the stream key to a fixed backend.
5. Add Health Checks
Don't forget to set up health checks so your load balancer can automatically remove faulty backend servers:
- For Nginx LB: Use modules like
nginx-healthcheck-moduleor configureproxy_next_upstreamto skip unresponsive servers. - For Cloud LB: Use the provider's built-in health check feature (e.g., check the backend's
/healthendpoint or 1935 port).
内容的提问来源于stack exchange,提问作者aNewbieDev

