💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
### 使用 Heartbeat 构建高可用服务 > Even in the future, nothing works! > > — Spaceballs 一切迟早都会发生故障。高可用服务就是指当一个主机或网络线路失效时仍旧能够提供服务。 高可用性的主要技术就是冗余,另外,这个问题的解决就是以投放更多硬件设备而著称的。 虽然最终肯定会有单独的一台服务器失效,但是两台服务器同时失效的概率是不太高的, 这对大多数的应用程序提供了一个良好的冗余水平。 最简单的方法之一是建立一对冗余服务器,它们共享一个 IP 地址,并使用心跳检测。 **心跳**(**Heartbeat**)是一个守护进程,它同时运行在两台机器上并且定期彼此交换信息(heartbeats)。 其中的一台是主服务器,通常它拥有资源:在本例中是一个 IP 地址。 如果辅助服务器无法从主服务器检测到心跳信号,它就接管地址以确保服务的连续性。 在下面的处方中,我们将使用 Puppet 的配置设置两台机器,并解释如何使用它提供一个高可用服务。 #### 操作步骤 1. 创建如下的 heartbeat 模块: ``` # mkdir /etc/puppet/modules/heartbeat # mkdir /etc/puppet/modules/heartbeat/manifests # mkdir /etc/puppet/modules/heartbeat/files ``` 2. 使用如下内容创建 /etc/puppet/modules/heartbeat/manifests/init.pp 文件: ``` class heartbeat { package { "heartbeat": ensure => installed, } service { "heartbeat": ensure => running, require => Package["heartbeat"], } exec { "reload-heartbeat": command => "/usr/sbin/service heartbeat reload", refreshonly => true, } file { "/etc/ha.d/authkeys": source => "puppet:///modules/heartbeat/authkeys", mode => "600", require => Package["heartbeat"], notify => Exec["reload-heartbeat"], } file { "/etc/ha.d/haresources": source => "puppet:///modules/heartbeat/haresources", notify => Exec["reload-heartbeat"], require => Package["heartbeat"], } file { "/etc/ha.d/ha.cf": source => "puppet:///modules/heartbeat/ha.cf", notify => Exec["reload-heartbeat"], require => Package["heartbeat"], } } ``` 3. 使用如下内容创建 /etc/puppet/modules/heartbeat/files/haresources 文件。 将 cookbook 替换成你的主服务器的主机名。这可以通过在主服务器上运行 uname -n 命令获得。 将 10.0.2.100 替换成你要在两台主机上共享的 IP 地址(这应该是当前网络上还未使用的地址)。 最后列出的接口是分配给心跳检测的(本例中是 eth0:1)。 ``` cookbook IPaddr::10.0.2.100/24/eth0:1 ``` 4. 使用如下内容创建 /etc/puppet/modules/heartbeat/files/authkeys 文件 (使用你自己选择的口令替换 topsecretpassword): ``` auth 1 1 sha1 topsecretpassword ``` 5. 使用如下内容创建 /etc/puppet/modules/heartbeat/files/ha.cf 文件。 替换下面的两个 IP 地址为你自己的两台机器上 eth0 接口对应的 IP 地址。 同样需替换 cookbook 和 cookbook2 为你自己的两台机器的主机名(可以通过运行 uname -n 命令获得)。 ``` autojoin none ucast eth0 10.0.2.15 ucast eth0 10.0.2.16 keepalive 1 deadtime 10 warntime 5 udpport 694 auto_failback on node cookbook node cookbook2 use_logd yes ``` 6. 在两台冗余服务器上都运行 Puppet: ``` # puppet agent --test info: Retrieving plugin info: Caching catalog for cookbook.bitfieldconsulting.com info: Applying configuration version '1311440876' notice: /Stage[main]/Heartbeat/Package[heartbeat]/ensure: created notice: /Stage[main]/Heartbeat/File[/etc/ha.d/authkeys]/ensure: defined content as '{md5}e908c869aabe519aa69acc9e51da3399' info: /Stage[main]/Heartbeat/File[/etc/ha.d/authkeys]: Scheduling refresh of Exec[reload-heartbeat] notice: /Stage[main]/Heartbeat/File[/etc/ha.d/ha.cf]/ensure: defined content as '{md5}a8d3fdd62a1172cdff150fc1d86d8a6b' info: /Stage[main]/Heartbeat/File[/etc/ha.d/ha.cf]: Scheduling refresh of Exec[reload-heartbeat] notice: /Stage[main]/Heartbeat/File[/etc/ha.d/haresources]/ensure: defined content as '{md5}0f25aefe7f6c4c8e81b3bb6c86a42d60' info: /Stage[main]/Heartbeat/File[/etc/ha.d/haresources]: Scheduling refresh of Exec[reload-heartbeat] notice: /Stage[main]/Heartbeat/Exec[reload-heartbeat]: Triggered 'refresh' from 3 events notice: Finished catalog run in 27.01 seconds ``` 7. 在主服务器节点上,检查它的资源: ``` # cl_status rscstatus -m This node is holding all resources. ``` 8. 在辅助服务器节点上,你应该可以看到如下信息: ``` # cl_status rscstatus -m This node is holding none resources. ``` 9. 在主节点上禁用 Heartbeat 服务: ``` # service heartbeat stop ``` 10. 辅助节点现在应该接管了资源: ``` # cl_status rscstatus -m This node is holding all resources. ``` #### 工作原理 两台服务器上都运行了心跳守护进程,彼此监听心跳信号。 如果主服务器检测到辅助服务器已宕机,什么也不会发生。 而相反地,如果辅助服务器检测到主服务器已宕机,它就接管 IP 地址。 当主服务器恢复运行后,辅助服务器将再次放弃此地址,重新由主服务器接管 IP 地址 (如果 auto_failback 设置成了 on)。 在某些情况下,例如:如果你在主数据库服务器和从数据库服务器之间共享 IP 地址, 你可能不希望这种行为发生,在这种情况下应该将 auto_failback 设置成了 off。 #### 更多用法 现在你有一个共享的 IP 地址(真是名不副实,因为这个地址不是“共享”的,而是在两个服务器之间切换), 你可以用这个地址来提供高可用性的服务。例如,如果服务器是被托管的 web 站点, 你应该为 web 站点设置 DNS 记录指向这个共享的 IP 地址。 当主服务器宕机时,辅助服务器将接管 IP 地址并继续响应基于此地址的 HTTP 请求。 > ![提示](https://box.kancloud.cn/2016-05-12_5733eec6d55e1.png) > 如果你正在使用 SSL 站点,你需要配置基于共享 IP 地址的 SSL 虚拟主机, 否则将不能响应基于这个 IP 的 HTTPs 请求。 另外,如果这个 web 站点使用了 sessions,主服务器上的任何 sessions 在故障转移后将会丢失, 除非 sessions 存储在一个分离的共享数据库中。 共享 IP 地址也是实现双路冗余负载均衡器的一种好方式 (参考 [使用 HAProxy 为多个 web 服务器实现负载均衡](#ch08sec04) 一节)。 你也可以使用这种方式为 Puppetmaster 主机提供冗余服务。 在 Puppet Labs 站点给出了一个合适的模式: [http://projects.puppetlabs.com/projects/1/wiki/High_Availability_Patterns](http://projects.puppetlabs.com/projects/1/wiki/High_Availability_Patterns) 。