10

让我们想象一下,我们有一个比萨店要设计和构建的订单处理系统。

要求是:

R1。系统应该与客户端和用例无关,这意味着系统可以被客户端访问,这在初始设计期间没有考虑到。例如,如果披萨店决定其许多客户稍后使用三星 Bada 智能手机,则为 Bada OS 编写客户端将不需要重写系统的 API 和系统本身;或者例如,如果事实证明使用 iPad 而不是 Android 设备对送货司机来说更好,那么创建 iPad 客户端将很容易,并且不会以任何方式影响系统的 API;

R2。可重用性,这意味着如果业务流程发生变化,系统可以很容易地重新配置,而无需重写太多代码。例如,如果稍后披萨店将开始接受在线付款以及接受送货司机的现金(接受订单前付款 VS 接受货到付款),那么系统很容易适应新的业务流程;

R3。高可用性和容错性,这意味着系统应该在线并且应该 24/7 全天候接受订单。

因此,为了满足 R3,我们可以使用 Erlang/OTP 并具有以下架构: 带有一个 RESTful API 入口点的纯 Erlang/OTP 架构

这里的问题是这种架构中有很多“硬编码”的功能。例如,如果比萨店从接受货到付款转变为接受下单前的在线支付,那么重写整个系统和修改系统的 API 将需要大量的时间和精力。

此外,如果披萨店需要对其 CRM 客户端进行一些改进,那么我们将不得不再次重写 API、客户端和系统本身。

因此,以下架构旨在解决这些问题,从而帮助满足 R1、R2 和 R3: 具有多个 RESTful API 入口点的面向服务的架构

系统中的每个“服务”都是一个带有 RESTful API 的 Webmachine 网络服务器。这种方法有以下好处:

  • Erlang/OTP 的所有优点,因为每个 Web 机器都是一个 Erlang 应用程序,可以被监督并且可以放入一个 Erlang 版本中;
  • 具有 SOA 的所有优点的面向服务的架构;
  • 易于适应业务流程的变化
  • 易于向客户端(例如 CRM 客户端)添加新客户端和新功能,因为客户端可以使用系统中所有服务的 RESTful API,而不是一个“中央”API(SOA 方面的服务可组合性)。

因此,本质上,第二张图片中提出的系统架构是面向服务的架构,其中每个服务都有一个 RESTful API 而不是 WSDL 契约,每个服务都是一个 Erlang/OTP 应用程序。

这是我的问题:

  1. 图2:我想在这里重新发明轮子吗?我应该坚持使用纯 Erlang/OTP 架构吗?(“纯 Erlang”是指打包到一个版本中的 Erlang 应用程序,通过 gen_server:call 和 gen_server:cast 函数调用相互通信);
  2. 您能说出建议的方法中的任何缺点吗?(图二)
  3. 您认为维护和发展(R1 和 R2)这样的系统(图 2)比真正的 Erlang/OTP 系统更容易吗?
  4. 这样一个系统的安全性(图 2)可能是一个问题,因为有许多对 Web 开放的入口点(所有服务的 RESTful API)而不是只有一个入口点(图 1),不是吗?
  5. 在这样的系统中有几个“编排模块”是否可以,或者可能存在一些更好的做法?(“接单”、“CRM”和“派单”服务如图2);
  6. 就消息传递和协议的限制而言,纯 Erlang/OTP(图 1)是否比这种方法(图 2)有任何优势?(在我之前的类似问题gen_server:call VS HTTP RESTful 调用中进行了部分讨论)
4

2 回答 2

2

关于 SOA 需要牢记的是架构与技术无关(REST、WS*)。因此,如果/需要时,您可以获得具有多种类型端点的良好 SOA(我称之为边缘组件- 将业务逻辑与通信和协议等其他问题分开)此外,重要的是要注意服务边界是信任边界因此,当您跨过它时,您可能需要进行身份验证和授权、跨网络等。此外,分层(如数据和逻辑)不应驱动您划分服务的方式。

因此,根据我在您的问题中阅读的内容,我可能会将服务划分为更粗粒度的服务(见下文)。服务边界内的通信可以是任何东西,因为跨服务的通信使用公共 API(REST 或 Erlang 本机取决于您,但关键是它是受管理的、版本控制的、安全的等) - 再次,一个服务可能具有多种技术的端点以方便不同的用户(有时您会使用 ESB 在服务和协议之间进行调解,但是否需要取决于系统的大小和复杂性)

关于您的具体问题

  • 1 如上所述,我认为有一个地方可以公开更多公共 API,而不仅仅是一个入口点,我不确定使用 public-api 将每个功能公开为服务是否是正确的查看方式。
  • 2&3 暴露每一件小事的缺点是管理开销、性能下降(例如,您必须对这些调用进行身份验证)。你会得到纳米服务服务,其开销超过了它们的效用。
  • 关于安全性要添加的一件事是,某些服务具有 REST API 的事实不必转化为使该 API 可供公众使用。部署方面,您可以将其保留在防火墙后面,并限制对已知地址等的访问。

    • 5 拥有多个编排模块是可以的,但如果超出了几个,您可能应该考虑使用一些编排模块(以及 ESB 或编排引擎),或者您可以使用基于事件的集成并获得更灵活的基于编排的集成(但有点难以管理)

    • 6 第一个选项具有易于开发和可能更好的性能(如果这是一个问题)的优势。随着时间的推移,硬编码的集成层可能会更难维护。erlang 服务,如果你编写它们,如果你保持 API 集成和它们之间的消息传递,它们应该能够独立发展(幸运的是,Erland 通过其固有特性(例如不变性)相对容易做到这一点)

服务

于 2012-07-04T20:43:07.730 回答
1

我将介绍第三种方式,它更具成本效益且对变化反应灵敏。架构绝对应该是面向服务的,因为你有明确的服务。但是没有要求将每个服务公开为 Restful 或 WSDL 定义的服务。我不是 Erlang 开发人员,但我相信有一种方法可以通过消息传递调用本地和远程进程,从而避免内部调用的不必要的序列化/序列化活动。但是有一天你会面临新的集成问题。例如,您将整合会计或物流系统。然后,如果您在 SOA 原则方面设计得很好,那么大部分工作将与使用 RESTful 前端包装器公开现有服务相关,而无需重构与其他服务的现有连接。但问题是要保持职责范围的清洁。我的意思是每个服务都应该对其最初设计的活动负责。

您提到的安全问题是已知的。例如,您应该在所有公开的服务中使用令牌进行身份验证/授权。

于 2012-07-01T12:48:14.153 回答