Skip to content

Instantly share code, notes, and snippets.

@chrisstaite
Created June 22, 2016 20:05
Show Gist options
  • Select an option

  • Save chrisstaite/cea1abbd31564659c27a4211975cde3e to your computer and use it in GitHub Desktop.

Select an option

Save chrisstaite/cea1abbd31564659c27a4211975cde3e to your computer and use it in GitHub Desktop.
PHP script to load balance between Icecast servers using 302 redirect
<?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