如何让HAproxy返回下一个数据库服务器的IP地址?

时间:2013-04-15 20:17:20

标签: php mysql haproxy

我想使用HAproxy检查我的数据库服务器是否在线,而不是通过HAproxy框实际路由请求。有什么方法可以连接到HAproxy并让它返回数据库主机IP地址吗?

例如:来自webserver#1我在端口3306上连接到HAproxy.HAproxy从db主机(循环)列表中侦听3306和echos DB Host#1。然后从webserver#1直接连接到数据库主机#1。

2 个答案:

答案 0 :(得分: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()

答案 1 :(得分:0)

您始终可以运行此查询来确定主机名:

SHOW VARIABLES WHERE Variable_name = 'hostname';

https://serverfault.com/a/129646/52951