Вы можете сделать это непосредственно в PHP.
попробовать что-то вроде этого:
function get_connectable_host(array $hosts, $port, $timeout = 3)
{
// Optionally randomise the order of the input array
// This should help to ensure a relatively even distribution over time
shuffle($hosts);
// Create some vars
$socks = $w = array();
$r = $e = null;
$flags = STREAM_CLIENT_CONNECT | STREAM_CLIENT_ASYNC_CONNECT;
// Loop over the list of host addresses and send connect attempts to them
// Store the host address with the created socket resource
foreach ($hosts as $host) {
$address = "tcp://$host:$port";
$sock = stream_socket_client($address, $n, $s, $timeout, $flags);
$socks[(int) $sock] = array($host, $sock);
$w[] = $sock;
}
// Wait for at least one of the sockets to connect
if (!stream_select($r, $w, $e, $timeout)) {
return false; // Nothing connected successfully after the timeout
}
// Get the ID of the first socket that connected
$result = (int) current($w);
// Loop over the sockets and disconnect them all
foreach ($socks as $sock) {
stream_set_blocking($sock[1], 0); // set non-blocking or FIN will block
stream_socket_shutdown($sock[1], STREAM_SHUT_RDWR);
fclose($sock[1]);
}
// Return the successfully connected host address
return $socks[$result][0];
}
$hosts = array(
'192.168.0.1',
'192.168.0.2',
'192.168.0.3'
);
$port = 3306;
$timeout = 3; // Max number of seconds to wait for a connection
$hostToUse = get_connectable_host($hosts, $port, $timeout);
Это должно получить IP-адрес первого хоста из прилагаемого массива, который успешно соединяет, и самое главное вернется, как только успешное соединение сделано - оно не будет дождитесь возврата всех сокетов и достигнет таймаута, если все хосты не смогут подключиться.
По существу, это именно то, что вы хотите, чтобы HAproxy сделал для вас прямо на PHP.
Действительно важными битами, которые делают эту работу, являются stream_socket_client()
с STREAM_CLIENT_ASYNC_CONNECT
и stream_select()
.
Если это часть приложения реального мира, тогда ИМХО, приобретение БД-соединения должно выполняться прозрачно с помощью прокси-сервера. Каковы ваши рассуждения для этого? – rdlowrey