在主從架構中,從庫複制延遲會導致讀取舊資料。HAProxy 1.5+ 引入 Agent Check,可根據 `Seconds_Behind_Master` 動態調整後端伺服器權重,實現延遲感知負載均衡。
<?php
$port = $argv[1]; $mysql_port = $argv[2];
$mysql = "/usr/bin/mysql"; $user = 'haproxy'; $pass = 'haproxy_pwd';
$query = "SHOW SLAVE STATUS";
function set_weight($lag) {
if ($lag === 'NULL') return "down";
if ($lag < 10) return "up 100%";
if ($lag >= 10 && $lag < 60) return "up 50%";
return "up 5%";
}
$socket = stream_socket_server("tcp://127.0.0.1:$port", $errno, $errstr);
while ($conn = stream_socket_accept($socket)) {
$cmd = "$mysql -h127.0.0.1 -u$user -p$pass -P$mysql_port -Ee \"$query\" | grep Seconds_Behind_Master | cut -d ':' -f2 | tr -d ' '";
exec($cmd, $lag);
fputs($conn, set_weight($lag[0]));
fclose($conn);
}
fclose($socket);
?>
GRANT REPLICATION CLIENT ON *.* TO 'haproxy'@'127.0.0.1' IDENTIFIED BY 'haproxy_pwd';
frontend read_only_front bind *:3307 mode tcp default_backend read_only_back backend read_only_back mode tcp balance leastconn server slave1 192.168.10.2:3306 weight 100 check agent-check agent-port 6789 inter 1000 rise 1 fall 1 on-marked-down shutdown-sessions server slave2 192.168.10.3:3306 weight 100 check agent-check agent-port 6789 inter 1000 rise 1 fall 1 on-marked-down shutdown-sessions
透過 `socat stdio /run/haproxy/admin.sock` 查看 `show stat`,可觀察到權重隨延遲動態變化:延遲 0 秒 → 100%,25 秒 → 50%,NULL(複制中斷) → DOWN。