2013-04-15 17 views
0

我想使用HAproxy檢查我的數據庫服務器是否在線,而實際上並沒有通過HAproxy框路由請求。有什麼方法可以連接到HAproxy並讓它返回一個DB主機IP地址?如何讓HAproxy返回下一個數據庫服務器的IP地址?

例如:從web服務器#1我連接到端口3306上的HAproxy。HAproxy偵聽3306並從db主機列表中回顯數據庫主機#1(循環法)。然後從Web服務器#1直接連接到數據庫主機#1。

+0

如果這是真實應用程序的一部分,那麼恕我直言,後端數據庫連接的採購應該由代理透明地處理。你做這個的理由是什麼? – rdlowrey

回答

2

您可以直接在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_CONNECTstream_select()

+0

我正在閱讀stream_select()手冊...從我理解的stream_select()在所有襪子響應或超時時間之後返回。我認爲你暗示這個函數會在1個襪子響應後返回(這正是我想要的)......我在man page中看不到這個。 –

+0

@FrancisSnipe由於'STREAM_SOCKET_ASYNC_CONNECT',這將按預期工作。 http://codepad.viper-7.com/uaVuOn < - 請注意,它不需要3秒鐘返回,只要一臺主機連接就會發生這種情況。 – DaveRandom

+0

好的,我現在看到了。 –