试试使用Apache mod_heartbeat
由于 CentOS 7 的 Apache 2.4 中存在着一些奇怪的模块,如 mod_heartbeat 和 mod_watchdog,因此出于好奇心,我尝试使用了它们。
只是使用过而已,所以没有进行详细调查。
摘要
使用Apache的mod_proxy_balancer进行负载均衡时,似乎是根据来自真实服务器的心跳来决定平衡的目标。
使用以下三个模块进行组合使用。
mod_watchdog
他のモジュールで定期的なタスクを実行するためのモジュール
mod_heartbeat や mod_heartmonitor で定期的なタスクを実行するために必要
リバースプロキシとリアルサーバの両方で有効にする
いわゆる software watchdog のことではない
下記のページが詳しい
mod_watchdog | しんじつのなみだ
mod_heartbeat
リアルサーバからハートビートを送信するためのモジュール
リアルサーバで有効にする
ハートビートはマルチキャストで送信される
いわゆる Linux-HA の heartbeat とは関係ない
mod_heartmonitor
ハートビートを受信してバランス先を管理するためのモジュール
リバースプロキシで有効にする
流浪者
我在Vagrant上创建环境。
Vagrant.configure(2) do |config|
config.vm.box = "ngyuki/centos-7"
config.vm.define "rev" do |cfg|
cfg.vm.hostname = "rev"
cfg.vm.network "forwarded_port", guest: 80, host: 8080
cfg.vm.network "private_network", ip: "192.168.33.10", virtualbox__intnet: "apache-hb"
end
config.vm.define "sv1" do |cfg|
cfg.vm.hostname = "sv1"
cfg.vm.network "forwarded_port", guest: 80, host: 8081
cfg.vm.network "private_network", ip: "192.168.33.11", virtualbox__intnet: "apache-hb"
end
config.vm.define "sv2" do |cfg|
cfg.vm.hostname = "sv2"
cfg.vm.network "forwarded_port", guest: 80, host: 8082
cfg.vm.network "private_network", ip: "192.168.33.12", virtualbox__intnet: "apache-hb"
end
config.vm.provision "shell", inline: <<-SHELL
yum -y install httpd
uname -n > /var/www/html/index.html
SHELL
end
rev 是一种所谓的反向代理式 L7 负载均衡器,sv1 和 sv2 是真实服务器。
我正在使用的 Box 是私人 Box,所以除了我以外不能使用。我只是添加了 epel-release 和 git,所以与普通的 CentOS 7 没有特别的区别。
那么现在开始启动吧。
vagrant up
不使用mod_heartbeat进行分布式
开始启动实际服务器(sv1/sv2)上的Apache。
systemctl start httpd.service
在反向代理服务器(rev)上进行如下配置。
cat <<'EOS'> /etc/httpd/conf.d/rev.conf
<VirtualHost *:80>
ServerName localhost
<Location />
ProxyPass balancer://app/
ProxyPassReverse balancer://app/
</Location>
<Location /balancer-manager>
ProxyPass !
SetHandler balancer-manager
</Location>
<Proxy balancer://app/>
BalancerMember http://192.168.33.11
BalancerMember http://192.168.33.12
</Proxy>
</VirtualHost>
EOS
开始 Apache。
systemctl start httpd.service
当通过反向代理(rev)访问此状态时,可以看到已分散到sv1和sv2上。
我强制终止Vagrant主机上的sv2。
vagrant halt -f sv2
当我再次打开rev时,在第一或第二次尝试时,我认为会被超长时间等待。
这是因为反向代理正在向sv2发送请求并等待超时。
一旦超时发生后,之后的一段时间内,请求只会被分配给 sv1,但每60秒会向 sv2 请求一次,因此会再次等待超时时间。这是为了确认 sv2 是否恢复正常。
重新启动sv2。
vagrant up sv2
vagrant ssh sv2
启动 sv2 的 Apache。
systemctl start httpd.service
大约60秒之后,它将重新平衡到sv2上。
使用mod_heartbeat来实现负载均衡。
在所有服务器(rev/sv1/sv2)上,按照如下方式进行路由设置。
ip route add 239.0.0.0/24 dev enp0s8 proto kernel scope link
mod_heartbeat通过多播方式发送心跳信息,但是在目标地址的设置中似乎无法指定I/F,因此需要在路由中指定从哪个I/F出去(通常在这种情况下也需要指定I/F)。
如果只有一个接口,则无需指定,但由于Vagrant,存在NAT和PrivateNetwork两个接口。由于无法在NAT网络中进行宿主机和虚拟机之间的通信,因此我们需要设置路由,使其通过PrivateNetwork网络进行通信。
设置实际服务器(sv1/sv2)的配置。
在实际服务器(sv1/sv2)上启用 mod_watchdog 和 mod_heartbeat。
vim /etc/httpd/conf.modules.d/00-base.conf
解除注释如下。
#LoadModule buffer_module modules/mod_buffer.so
-#LoadModule watchdog_module modules/mod_watchdog.so
+LoadModule watchdog_module modules/mod_watchdog.so
-#LoadModule heartbeat_module modules/mod_heartbeat.so
+LoadModule heartbeat_module modules/mod_heartbeat.so
#LoadModule heartmonitor_module modules/mod_heartmonitor.so
#LoadModule usertrack_module modules/mod_usertrack.so
指定心跳多播地址(虽然也许在这里指定接口名可能会更好)。
cat <<EOS> /etc/httpd/conf.d/heartbeat.conf
HeartbeatAddress 239.0.0.1:27999
EOS
重新启动Apache。
systemctl restart httpd.service
使用tcpdump将可以发现流动的多播数据包。
tcpdump -nn -i enp0s8 port 27999
反向代理服务器(rev)的配置
使用反向代理(rev)启用 mod_watchdog 和 mod_heartmonitor。
vim /etc/httpd/conf.modules.d/00-base.conf
以下是如何解除注释的步骤。
#LoadModule buffer_module modules/mod_buffer.so
-#LoadModule watchdog_module modules/mod_watchdog.so
+LoadModule watchdog_module modules/mod_watchdog.so
#LoadModule heartbeat_module modules/mod_heartbeat.so
-#LoadModule heartmonitor_module modules/mod_heartmonitor.so
+LoadModule heartmonitor_module modules/mod_heartmonitor.so
#LoadModule usertrack_module modules/mod_usertrack.so
设置接收组播的配置并设置保存状态的文件名。
cat <<EOS> /etc/httpd/conf.d/heartbeat.conf
HeartbeatListen 239.0.0.1:27999
HeartbeatStorage /tmp/hb.dat
EOS
在代理服务器的设置中添加 lbmethod=heartbeat。
cat <<'EOS'> /etc/httpd/conf.d/rev.conf
<VirtualHost *:80>
ServerName localhost
<Location />
ProxyPass balancer://app/ lbmethod=heartbeat
ProxyPassReverse balancer://app/
</Location>
<Location /balancer-manager>
ProxyPass !
SetHandler balancer-manager
</Location>
<Proxy balancer://app/>
BalancerMember http://192.168.33.11
BalancerMember http://192.168.33.12
</Proxy>
</VirtualHost>
EOS
我要重新启动Apache。
systemctl restart httpd.service
请检查访问反向代理服务器(rev)以确认是否已将负载分散到 sv1 和 sv2。
一旦确认完成,便立即停止sv2。
vagrant halt -f sv2
稍等片刻后,重新打开反向代理,就不会再像之前一样被迫等待超时了。
因为从sv2的心跳中断了,所以被从平衡器处移除了(大概)。
请重新启动sv2一次。
vagrant up sv2
vagrant ssh sv2
设置路由并启动 Apache(理应将其自动设置)。
ip route add 239.0.0.0/24 dev enp0s8 proto kernel scope link
systemctl start httpd.service
大约10秒钟,我也能够在sv2上实现平衡。
最后
我认为没有必要在 Apache 上进行负载均衡,用 HAProxy 就够了,或者干脆用 ELB 在 AWS 上部署,所以我认为实际运用中不会使用。