0

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

例如:从 webserver #1 我连接到端口 3306 上的 HAproxy。HAproxy 在 3306 上侦听并从 db 主机列表(循环)中回显 DB Host #1。然后从 webserver#1 我直接连接到 DB 主机#1。

4

2 回答 2

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()

于 2013-04-15T21:24:29.870 回答
0

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

SHOW VARIABLES WHERE Variable_name = 'hostname';

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

于 2013-04-15T20:21:28.050 回答