3

如果有可能向多个客户端提供服务,如果提供此服务的服务器出现故障,另一个服务器将取代它——没有某种集中的“控制”来检测主服务器是否已出现故障并将客户端重定向到新服务器?

没有集中的接口/网关可以吗?

换句话说,这有点像问你能否设计一个节点平衡器而无需集中控制直接客户端?

4

3 回答 3

6

好吧,您没有提供有关您所询问的“服务”的太多信息,所以我将以通用的方式回答。

对于我回答的第一部分,我假设您正在谈论一个涉及 IP 地址的“集中式接口/网关”。为此,有引用自wiki的 CARP(通用地址冗余协议) :

通用地址冗余协议或 CARP 是一种允许同一本地网络上的多个主机共享一组 IP 地址的协议。它的主要目的是提供故障转移冗余,尤其是在与防火墙和路由器一起使用时。在某些配置中,CARP 还可以提供负载平衡功能。它是思科 HSRP 的免费、无专利保护的替代方案。CARP 主要在 BSD 操作系统中实现。

引用 netbsd 的“ CARP 简介”:

CARP 的工作原理是允许同一网段上的一组主机共享一个 IP 地址。这组主机称为“冗余组”。为冗余组分配了一个在组成员之间共享的 IP 地址。在该组中,一台主机被指定为“主”,其余主机被指定为“备份”。主控主机是当前“持有”共享 IP 的主机;它响应指向它的任何流量或 ARP 请求。每台主机一次可能属于多个冗余组。

这可能会在网络级别解决您的问题,让从属按顺序接管 IP 地址,而不会出现单点故障。

现在,对于答案的第二部分(应用程序级别),使用分布式 erlang,您可以拥有多个节点(一个集群),这将为您提供容错和冗余(因此您不会在这里使用 ip 地址,而是“分布式 erlang “ - 一个 erlang 节点集群 - 代替)。

启动分布式应用程序时,您将有很多节点,并且您的应用程序资源文件将包含可以运行应用程序的节点列表(有序)。

分布式 erlang将控制哪些节点是“主节点”,并在不同节点上下移动时自动启动和停止您的应用程序。

从http://www.erlang.org/doc/design_principles/distributed_applications.html引用(尽可能少):

在具有多个 Erlang 节点的分布式系统中,可能需要以分布式方式控制应用程序。如果运行某个应用程序的节点出现故障,则应在另一个节点重新启动该应用程序。

应用程序将在由分布式配置参数指定的第一个节点启动,该节点已启动并正在运行。应用程序照常启动。

为了使应用程序控制的分发正常工作,分布式应用程序可能运行的节点必须相互联系并协商从何处启动应用程序。

启动时,节点将等待由sync_nodes_mandatory 和sync_nodes_optional 指定的所有节点出现。当所有节点都启动时,或者当所有强制节点都启动并且经过了 sync_nodes_timeout 指定的时间时,将启动所有应用程序。如果不是所有强制节点都出现了,则该节点将终止。

如果运行应用程序的节点出现故障,则应用程序在第一个节点处重新启动(在指定的超时后),由分布式配置参数指定,该节点已启动并运行。这称为故障转移

分布式 = [{应用程序,[超时,] NodeDesc}]

如果启动了一个节点,根据分布式优先级高于当前运行分布式应用程序的节点,应用程序将在新节点重新启动并在旧节点停止。这称为接管。

好的,这只是一个总体概述,因为它可能是一个很长的话题:)

具体细节,强烈推荐阅读learnyousomeerlang的分布式OTP应用章节(当然还有之前的链接: http ://www.erlang.org/doc/design_principles/distributed_applications.html )

此外,您的“服务”可能依赖于其他外部系统,例如数据库,因此您也应该考虑那里的容错和冗余。整个架构需要容错和分布式,以便“服务”以这种方式工作。

希望能帮助到你!

于 2012-06-26T14:58:14.367 回答
5

这个答案是对网络应用程序高可用性的一般概述,而不是特定于 Erlang。我还不太了解 OTP 框架中可用的内容,因为我是该语言的新手。


这里有几个不同的问题:

  1. 客户端连接必须移动到备份机器
  2. 会话可能包含状态数据
  3. 如何检测崩溃

问题 1 - 移动客户端连接
这可以通过许多不同的方式在网络架构的不同层上解决。最简单的方法是将其直接编码到客户端中,这样当连接丢失时,它会重新连接到另一台机器。

如果您需要网络透明性,您可以使用一些技术在不同机器之间同步 TCP 状态,然后将所有流量重新路由到新机器,这可能对客户端完全不可见。这比第一个建议更难做到。

我敢肯定在这两者之间有很多事情要做。

问题 2 - 状态数据
您显然需要将会话状态从崩溃的机器转移到备份机器。这真的很难以可靠的方式完成,您可能会丢失最后几笔交易,因为崩溃的机器可能无法发送崩溃前的最后一个状态。您可以通过这种方式使用同步调用来确保不会丢失状态:

  1. 事务/消息从客户端进入主机。
  2. 主机更新一些状态。
  3. 新状态被发送到备份机器。
  4. 备份机确认新状态的到来。
  5. 主机向客户端确认成功。

在某些情况下,这可能会很昂贵(或至少响应不够快),因为您甚至在向客户端确认任何内容之前都依赖于备份机器及其连接,包括延迟。为了使其性能更好,您可以让客户端在连接时与备份机器检查它接收到的事务,然后重新发送丢失的事务,使客户端有责任将工作排队。

问题 3 - 检测崩溃
这是一个有趣的问题,因为崩溃并不总是明确定义的。真的有什么东西崩溃了吗?考虑一个网络程序,它关闭了客户端和服务器之间的连接,但两者仍处于启动状态并连接到网络。或者更糟糕的是,使客户端在服务器没有注意到的情况下与服务器断开连接。以下是一些需要思考的问题:

  • 客户端应该连接到备份机器吗?
  • 如果主服务器更新某些状态并将其发送到备份机器,而备份连接了真正的客户端 - 会不会出现数据竞争?
  • 主计算机和备用计算机是否可以同时启动,或者您是否需要关闭其中一台计算机并移动所有会话?
  • 在这件事上你是否需要某种权威,某种协议来决定哪个是主设备,哪个是从设备?那个权威是谁?你如何去中心化它?
  • 如果您的节点失去了它们之间的连接但两者都继续按预期工作(称为网络分区)怎么办?
于 2012-06-26T14:59:17.497 回答
1

请参阅 Google 的论文“Chubby lock server”(PDF)“Paxos made live”(PDF)来了解一下。

简而言之,该解决方案涉及使用共识协议在处理所有请求的一组服务器中选举一个主服务器。如果主节点失败,则再次使用该协议来选举下一个主节点。

此外,请参阅gen_leader以获取领导者选举中的示例,该示例可用于检测故障和转移服务所有权。

于 2012-07-10T12:51:48.563 回答