试试使用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 上部署,所以我认为实际运用中不会使用。

广告
将在 10 秒后关闭
bannerAds