使用 Erlang/OTP 构建容错软实时 Web 应用程序

Posted

技术标签:

【中文标题】使用 Erlang/OTP 构建容错软实时 Web 应用程序【英文标题】:Building a fault-tolerant soft real-time web application with Erlang/OTP 【发布时间】:2012-08-01 04:43:18 【问题描述】:

我想为披萨外卖店构建一个容错的软实时 Web 应用程序。它应该帮助比萨店接受客户的电话,将它们作为订单输入系统(通过 CRM 网络客户端),并帮助调度员为订单分配送货司机。

这些目标并不稀奇,但我想让服务 24/7 可用,即使其具有容错性。此外,我想让它工作得非常快并且反应灵敏。

下面是这样一个应用程序的一个非常简单的架构视图。

问题是我不知道如何利用 Erlang/OTP 的所有优点来使应用程序响应迅速且容错。

这是我的问题:

    应该复制哪些系统元素以提供容错能力,我应该如何做到这一点?我知道我可以将每辆车的状态(坐标、分配的订单等)存储在一个复制的 Mnesia 数据库中。这是正确的方法吗? 哪些数据存储服务应该是传统的基于 SQL 的(例如基于boss_db),哪些应该在 Mnesia 上完成以提供非常快速的响应?在这种容错且响应迅速的应用程序中,是否可以使用传统的 SQL 数据库来存储客户记录和历史记录? 我是否应该尝试将所有服务(客户、车辆状态等)的所有数据存储在 RAM 中,以使应用程序具有高响应性? 我是否应该将持久性车辆数据(id、容量等)存储在常规 SQL 数据库中,并将实时数据(坐标、分配的订单、后备箱中的订单等)存储在 Mnesia 数据库中以使应用程序更实时响应?

【问题讨论】:

如果您不复制所有应用程序逻辑和数据,您将如何使服务 24/7 以防万一?数据库服务器故障;) 您能否提供有关如何在具有 2 个以上处理逻辑的节点的 Erlang/OTP 系统中复制数据的参考? 进程组,发送给所有人,解决冲突或简单地使用 riak/couchdb。或者你看看失忆症。但是自己做这件事将是一项非常艰巨的任务。 【参考方案1】:

首先,这是一个很大的问题,但我会尝试将其分解。让我们先看看事实。它是一个网络服务。这意味着我们有这些层:Web ServerMiddle ware application,然后是Data Storage。在大多数高可用性应用程序中,数据存储层必须通过replication 进行冗余,并通过Distribution 进行负载管理。在大多数实际应用程序中,您不需要在 RAM 中存储任何内容,除非应用程序本质上是实时的,例如 Multi-player Game ServerA telecom Switch。所以,您的应用程序,在这种情况下,真的不需要 RAM 存储(可能是某种caching,正如我们将要看到的那样。) 现在,这种应用程序,涉及不同类型的数据,信息在任何时候都不能具有相同的形式,因此,使用 RDMS 将迫使您以相同的方式安排所有内容。我的建议是你学会使用任何document oriented databaseNoSQL DBkey-value system,因为它们针对现实世界的复杂性进行了很好的建模。在pdf 中可以找到有关任何类型存储的更多信息。我建议您使用Couch base server,您的数据将只是JSON documentsschemaless,并且可以随着您的应用程序的增长而发展。它带有分发和复制功能,就像任何应用程序都需要它一样。您可以在运行时添加服务器或删除服务器,整个系统只是不断地重新平衡自己。它还带有内置的memcached 用于缓存,因此对于您所说的IN-Memory 部分,缓存将为您完成一切。 说完Storage,再说说中间件。我想谈谈作为中间件一部分的 Web 服务器。您将需要一个非常稳定的 Web 服务器,具体取决于负载,并且您想要使用 Erlang,我建议使用 yaws web server 并学习使用 appmods 使用它来处理 RESTFUL services。在 Web 服务器集群前面使用代理 sunch 作为nginx 可能有助于负载管理。至少有几种方法可以在 Web 服务器前进行负载平衡。在此之后,您将需要一个 OTP 应用程序。 OTP 应用程序不一定必须有gen_servers。但正如您将学习的那样,您会发现,真正需要并行化的地方或需要顺序代码的地方。然而,它担心你想使用你还没有掌握的东西。请关注this web book 和Orielly book,帮助您掌握有关 Erlang 的一切。您会发现尝试 Chicago BossMochiwebMisultin Http 服务器库很有用。 关于在 Erlang 中执行此操作,我应该提到的另一件事是,您需要掌握数据结构以及与他们合作的有效方式。数据结构选择不当可能会导致问题。在每一步测试和测试一切。如果可能,请在任何地方使用records,并检查每个阶段的内存消耗。关于这个问题有很多话要说,但希望其他人也能发表他们的想法。

【讨论】:

oreilly书链接到learnyousomeerlang。会编辑它,但我不知道你指的是哪本书,至少有 2 本书;) 我已经修复了链接。对此感到抱歉 @MuzaayaJoshua 在多人游戏服务器的情况下,让数据存储将所有内容存储在 RAM 中的最佳方法/工具是什么? 也许这会对你有所帮助:jeena.net/t/GGS.pdf 但你应该首先设计你的架构。将所有内容存储在每个节点上不会扩展。而你的主要逻辑问题将是玩家的分布和节点间的通信。您应该在游戏服务器设计方面进行广泛的研究。看看其他人是如何解决他们的问题的。如果您可以最大限度地减少节点间通信,您的扩展只会非常有效。在最好的情况下,两个 erland 节点实际上不必相互通信。每个节点只需在其节点内的玩家之间进行消息传递。 也看看memcached【参考方案2】:

破解这个游戏:https://github.com/synrc/games 所有实时、低延迟、发布/订阅、数据库、架构问题都在那里,编写为最先进的软件。我建议使用 gen_fsm 来控制应用程序中的状态,就像在“好的”主管中所做的那样。 riak 与 kvs lib 集成,对社交更新也有很好的支持。 n2o 选择了牛仔服务器,在我看来,周围最好的服务器。 http://www.ostinelli.net/a-comparison-between-misultin-mochiweb-cowboy-nodejs-and-tornadoweb/

【讨论】:

以上是关于使用 Erlang/OTP 构建容错软实时 Web 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

您如何设计基于Erlang / OTP的分布式容错多核系统的架构?

使用 OTP/Erlang 作为 Web 应用程序基于组件的架构的一部分

SOA:为啥不使用 Erlang/OTP Web 服务器作为服务?

Erlang/OTP 消息可靠吗?消息可以复制吗?

1.Erlang/OTP平台

如何在Erlang / OTP中构建MQ使用者循环?