我想使用HAproxy檢查我的數據庫服務器是否在線,而實際上並沒有通過HAproxy框路由請求。有什麼方法可以連接到HAproxy並讓它返回一個DB主機IP地址?如何讓HAproxy返回下一個數據庫服務器的IP地址?
例如:從web服務器#1我連接到端口3306上的HAproxy。HAproxy偵聽3306並從db主機列表中回顯數據庫主機#1(循環法)。然後從Web服務器#1直接連接到數據庫主機#1。
我想使用HAproxy檢查我的數據庫服務器是否在線,而實際上並沒有通過HAproxy框路由請求。有什麼方法可以連接到HAproxy並讓它返回一個DB主機IP地址?如何讓HAproxy返回下一個數據庫服務器的IP地址?
例如:從web服務器#1我連接到端口3306上的HAproxy。HAproxy偵聽3306並從db主機列表中回顯數據庫主機#1(循環法)。然後從Web服務器#1直接連接到數據庫主機#1。
您可以直接在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()
。
我正在閱讀stream_select()手冊...從我理解的stream_select()在所有襪子響應或超時時間之後返回。我認爲你暗示這個函數會在1個襪子響應後返回(這正是我想要的)......我在man page中看不到這個。 –
@FrancisSnipe由於'STREAM_SOCKET_ASYNC_CONNECT',這將按預期工作。 http://codepad.viper-7.com/uaVuOn < - 請注意,它不需要3秒鐘返回,只要一臺主機連接就會發生這種情況。 – DaveRandom
好的,我現在看到了。 –
你總是可以運行此查詢找出主機名:
SHOW VARIABLES WHERE Variable_name = 'hostname';
如果這是真實應用程序的一部分,那麼恕我直言,後端數據庫連接的採購應該由代理透明地處理。你做這個的理由是什麼? – rdlowrey