简体   繁体   English

Erlang / OTP体系结构:SOAish服务的RESTful协议

[英]Erlang/OTP architecture: RESTful protocol for SOAish services

Let us imagine we have an orders processing system for a pizza shop to design and build. 让我们想象一下,我们有一家比萨店要设计和制造的订单处理系统。

The requirements are: 要求是:

R1. R1。 The system should be client- and use-case-agnostic, which means that the system can be accessed by a client which was not taken into account during the initial design. 该系统应该与客户端和用例无关,这意味着客户端可以访问该系统,而在初始设计期间并未考虑该系统。 For example, if the pizza shop decides that many of its customers use the Samsung Bada smartphones later, writing a client for Bada OS will not require rewriting the system's API and the system itself; 例如,如果披萨店决定以后许多客户使用Samsung Bada智能手机,则为Bada OS编写客户端将不需要重写系统的API和系统本身。 or for instance, if it turns out that using iPads instead of Android devices is somehow better for delivery drivers, then it would be easy to create an iPad client and will not affect the system's API in any way; 举例来说,如果事实证明使用iPad而不是Android设备对交付驱动程序有某种程度的优势,那么创建iPad客户端将很容易,并且不会以任何方式影响系统的API;

R2. R2 Reusability, which means that the system can be easily reconfigured without rewriting much code if the business process changes. 可重用性,这意味着如果业务流程发生变化,可以轻松地重新配置系统,而无需重写大量代码。 For example, if later the pizza shop will start accepting payments online along with accepting cash by delivery drivers (accepting a payment before taking an order VS accepting a payment on delivery), then it would be easy to adapt the system to the new business process; 例如,如果稍后披萨店将开始在线接受付款并由送货司机接受现金(在接受订单之前接受付款与接受送货上付款),那么很容易使系统适应新的业务流程;

R3. R3。 High-availability and fault-tolerance, which means that the system should be online and should accept orders 24/7. 高可用性和容错能力,这意味着系统应该在线并且应该接受24/7的订单。

So, in order to meet R3 we could use Erlang/OTP and have the following architecture: 因此,为了满足R3,我们可以使用Erlang / OTP并具有以下架构: 具有一个RESTful API入口点的纯Erlang / OTP架构

The problem here is that this kind of architecture has a lot of "hard-coded" functionality in it. 这里的问题是这种体系结构中有很多“硬编码”功能。 If, for example, the pizza shop will move from accepting cash payments on delivery to accepting online payments before the order is placed, then it will take a lot of time and effort to rewrite the whole system and modify the system's API. 例如,如果披萨店从下达订单时的接受现金付款转为接受在线付款,那么将需要大量时间和精力来重写整个系统并修改系统的API。

Moreover, if the pizza shop will need some enhancements to its CRM client, then again we would have to rewrite the API, the clients and the system itself. 而且,如果比萨店需要对其CRM客户进行一些增强,那么我们将不得不再次重写API,客户和系统本身。

So, the following architecture is aimed to solve those problems and thus to help meeting R1, R2 and R3: 因此,以下架构旨在解决这些问题,从而帮助满足R1,R2和R3: 具有多个RESTful API入口点的面向服务的体系结构

Each 'service' in the system is a Webmachine webserver with a RESTful API. 系统中的每个“服务”都是具有RESTful API的Webmachine Web服务器。 Such an approach has the following benefits: 这种方法具有以下优点:

  • all goodness of Erlang/OTP, since each Webmachine is an Erlang application, which can be supervised and can be put into an Erlang release; Erlang / OTP的所有优点,因为每个Web机都是一个Erlang应用程序,可以对其进行监控并可以将其放入Erlang版本中;
  • service oriented architecture with all the benefits of SOA; 面向服务的体系结构,具有SOA的所有优点
  • easy adaptable to changes in the business process; 易于适应业务流程的变化
  • easy to add new clients and new functions to clients (eg to the CRM client), because a client can use RESTful APIs of all the services in the system instead of one 'central' API (Service composability in terms of SOA). 易于向客户端(例如CRM客户端)添加新客户端和新功能,因为客户端可以使用系统中所有服务的RESTful API,而不是一个“中央” API(就SOA而言,服务可组合性)。

So, essentially, the system architecture proposed in the second picture is a Service Oriented Architecture where each service has a RESTful API instead of a WSDL contract and where each service is an Erlang/OTP application. 因此,从本质上讲,第二张图中提出的系统体系结构是面向服务的体系结构,其中每个服务都具有RESTful API而不是WSDL合同,并且每个服务都是Erlang / OTP应用程序。

And here are my questions: 这是我的问题:

  1. Picture 2: Am I trying to reinvent the wheel here? 图2:我在这里试图重塑车轮吗? Should I just stick with the pure Erlang/OTP architecture instead? 我应该只坚持使用纯Erlang / OTP架构吗? ("Pure Erlang" means Erlang applications packed into a release, talking to each other via gen_server:call and gen_server:cast function calls); (“纯Erlang”表示打包到发行版中的Erlang应用程序,它们通过gen_server:call和gen_server:cast函数调用相互通信);
  2. Can you name any disadvantages in suggested approach? 您能指出建议方法中的任何缺点吗? (Picture 2) (图2)
  3. Do you think it would be easier to maintain and grow (R1 and R2) a system like this (Picture 2) than a truly Erlang/OTP one? 您认为像这样的系统(图2)维护和扩展(R1和R2)系统要比真正的Erlang / OTP系统容易吗?
  4. The security of such a system (Picture 2) could be an issue, since there are many entry points open to the web (RESTful APIs of all services) instead of just one entry point (Picture 1), isn't it so? 这样的系统的安全性(图2)可能是一个问题,因为有许多入口点(不限一个入口点(图1))开放到网络上(所有服务的RESTful API),不是吗?
  5. Is it ok to have several 'orchestrating modules' in such a system or maybe some better practice exists? 在这样的系统中可以有几个“编排模块”,还是存在一些更好的做法? ("Accept orders", "CRM" and "Dispatch orders" services on Picture 2); (图2中的“接受订单”,“ CRM”和“调度订单”服务);
  6. Does pure Erlang/OTP (Picture 1) have any advantages over this approach (Picture 2) in terms of message passing and the limitations of the protocol? 就消息传递和协议限制而言,纯Erlang / OTP(图1)是否比该方法(图2)具有任何优势? (partly discussed in my previous similar question , gen_server:call VS HTTP RESTful calls) (在我之前的类似问题 gen_server:call VS HTTP RESTful调用中进行了部分讨论)

The thing to keep in mind regarding SOA is that the architecture is not about the technology (REST, WS* ). 关于SOA要记住的一点是,体系结构与技术(REST,WS *)无关。 So you can get a good SOA in place with endpoints of several types if/when needed (what I call an Edge component - separating business logic from other concerns like communications and protocols) Also it is important to note that service boundary is a trust boundary so when you cross it you may need to authenticate and authorize, cross network etc. Additionally, separation into layers (like data and logic) shouldn't drive the way you partition your services. 因此,如果需要/需要时,您可以使用几种类型的端点来获得良好的SOA(我称之为Edge组件 -将业务逻辑与其他方面的问题(如通信和协议)分开)。还要注意服务边界是一个信任边界因此,当您跨接它时,可能需要进行身份验证和授权,跨网络等。此外,分层(如数据和逻辑)不应驱动服务划分方式。

So from what I am reading in your questions, I'd probably partition the services into more coarse grained services (see below). 因此,从我在阅读您的问题时所读的内容来看,我可能会将服务划分为更粗糙的服务(请参见下文)。 communications within the boundary of the service can be whatever, where-as communications across services uses a public API (REST or Erlang native is up to you, but the point is that it is managed, versioned, secured etc.) - again, a service may have endpoints in multiple technologies to facilitate different users (sometimes you'd use an ESB to mediate between services and protocols but the need for that depends on size and complexity of your system) 服务边界内的通信可以是任何东西,因为跨服务的通信使用公共API(REST或Erlang本机由您决定,但关键是要对其进行管理,版本控制,安全保护等)-同样,服务可能具有采用多种技术的终结点,以便利不同的用户(有时您会使用ESB在服务和协议之间进行调解,但是否需要取决于系统的大小和复杂性)

Regarding your specific questions 关于您的具体问题

  • 1 As noted above, I think theres a place to expose more public APIs than just a single entry point, I am not sure that exposing each and every capability as a service with public-api is the right way to go see. 1如上所述,我认为有一个地方可以公开比单个入口点更多的公共API,我不确定公开使用public-api作为服务的每项功能是否是正确的选择。
  • 2&3 The disadvantages of exposing every little thing is management overhead, decreased performance (eg you'd have to authenticate on these calls). 2&3暴露每件事的缺点是管理开销,性能下降(例如,您必须在这些调用中进行身份验证)。 You get nano-services services whose overhead is more than their utility. 您将获得纳米服务服务,其开销远远超过其效用。
  • One thing to add about the security is that the fact that some service has a REST API does not have to translate to having that API available to the general public. 关于安全性要增加的一件事是,某些服务具有REST API的事实不必转化为让公众可以使用该API。 Deployment-wise you can keep it behind a firewall and restrict the access to it for known addresses etc. 在部署方面,您可以将其保留在防火墙后面,并限制对已知地址等的访问。

    • 5 It is ok to have several orchestrating modules, though if you get beyond a few you should probably consider some orchestration module (and ESB or an Orchestration engine) alternatively you can use event based integration and get choreography based integration which is more flexible (but somewhat less manageable ) 5可以有几个编排模块,但是如果您不打算使用几个编排模块,则可能应该考虑使用一些编排模块(以及ESB或编排引擎),或者您可以使用基于事件的集成并获得基于编排的集成,这种集成更加灵活(但是不太容易管理)

    • 6 The first option has the advantage of easy development and probably better performance (if that's an issue). 6第一种选择的优点是易于开发并且可能具有更好的性能(如果这是一个问题)。 The hard-coded integration layer can prove harder to maintain over time. 随着时间的推移,硬编码集成层可能会变得难以维护。 The erlang services, if you wrote them write should be able to evolve independently if you keep API integration and message passing between them (luckily Erland makes it relatively easy to get this right by its inherent features (eg immutability)) 如果您编写了erlang服务,那么如果您保持它们之间的API集成和消息传递,那么编写的它们应该能够独立发展(幸运的是,Erland通过其固有功能(例如,不变性)相对容易地实现了这一目标)

服务

I'd introduce the third way that is rather more cost effective and change-reactive. 我将介绍第三种方式,该方式更具成本效益并且对变更反应灵敏。 The architecture definitely should be service oriented because you have services explicitly. 该体系结构绝对应该面向服务,因为您明确拥有服务。 But there's no requirement to expose each service as Restful or WSDL-defined one. 但是不需要将每个服务公开为Restful或WSDL定义的服务。 I'm not an Erlang developer but I believe there's a way to invoke local and remote processes by messaging and thus avoid unnecessary serialisation/serialisation activities for internal calls. 我不是Erlang开发人员,但我相信有一种方法可以通过消息传递来调用本地和远程进程,从而避免内部调用的不必要的序列化/序列化活动。 But one day you will be faced with new integration issue. 但是有一天,您将面临新的集成问题。 For example you will be to integrate accounting or logistic system. 例如,您将要集成会计或物流系统。 Then if you designed architecture well regarding SOA principles the most efforts will be related to exposing existing service with RESTful front-end wrapper with no effort to refactor existing connections to other services. 然后,如果您根据SOA原则设计了良好的体系结构,则最大的努力将与使用RESTful前端包装公开现有服务有关,而无需努力重构与其他服务的现有连接。 But the issue is to keep domain of responsibilities clean. 但是问题是保持职责范围整洁。 I mean each service should be responsible to the activity it was originally designed. 我的意思是,每个服务都应对最初设计的活动负责。

The security issue you mentioned is known one. 您提到的安全问题是已知的。 You should have authentication/authorization in all exposed services using tokens for example. 例如,您应该在所有使用令牌的公开服务中进行身份验证/授权。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM