Created
June 22, 2016 20:05
-
-
Save chrisstaite/cea1abbd31564659c27a4211975cde3e to your computer and use it in GitHub Desktop.
PHP script to load balance between Icecast servers using 302 redirect
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| // This is a very noddy script to do 302 redirects to load balance between servers | |
| // as listeners connect. It does no caching, supports a single stream only and requires | |
| // Icecast 2.4 or above (because it uses the status-json.xsl page). | |
| // The server, the minimum users before load balancing, the maximum users, the servers | |
| // are considered in order from top to bottom | |
| $servers = array( | |
| array("http://server1:8000/", 10, 100), | |
| array("http://server2:8000/", 5, 100) | |
| ); | |
| // This is the name of the stream that is relayed across the different servers | |
| $mount = "stream"; | |
| // You shouldn't need to change this | |
| $status_url = "status-json.xsl"; | |
| # Get the current load | |
| function get_load($server) { | |
| global $mount, $status_url; | |
| $status = file_get_contents($server . $status_url); | |
| if (!$status) | |
| return false; | |
| // Hack for bug in XSLT | |
| $status = str_replace(",}", "}}", $status); | |
| $status = json_decode($status); | |
| if (!$status || !isset($status->icestats)) | |
| return false; | |
| if (!is_array($status->icestats->source)) | |
| $sources = array($status->icestats->source); | |
| else | |
| $sources = $status->icestats->source; | |
| $source = false; | |
| for ($i = 0; $i < count($sources); $i++) | |
| { | |
| if (substr($sources[$i]->listenurl, -1 - strlen($mount)) == "/" . $mount) { | |
| $source = $sources[$i]; | |
| break; | |
| } | |
| } | |
| if (!$source) | |
| return false; | |
| return $source->listeners; | |
| } | |
| $chosen = false; | |
| $chosen_load = 999999; | |
| foreach ($servers as $server) | |
| { | |
| $load = get_load($server[0]); | |
| // Check for error | |
| if ($load === false) | |
| { | |
| continue; | |
| } | |
| // Check for under minimum load | |
| if ($load < $server[1]) | |
| { | |
| $chosen = $server[0]; | |
| break; | |
| } | |
| // Check for under maximum load and under other server load | |
| if ($load < $server[2] && $load < $chosen_load) | |
| { | |
| $chosen = $server[0]; | |
| $chosen_load = $load; | |
| } | |
| } | |
| if (!$chosen) | |
| { | |
| header("HTTP/1.0 503 Service Unavilable"); | |
| } | |
| else | |
| { | |
| header("Location: " . $chosen . $mount); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment