上下文

您正在设计企业应用程序,该程序需要使用由其他应用程序提供的服务。该服务定义了一个合约,所有服务使用者要访问该服务都必须遵守该合约。该合约定义了与此服务通信所需的技术、通信协议和消息定义等内容。要与该服务通信,应用程序需要按合约中的详细说明履行其责任。

问题

如何将该服务所规定的履行合约责任的细节与应用程序的其余部分分隔开来?

影响因素

在设计使用由其他应用程序提供的服务的应用程序时,必须考虑下列影响因素:

  • 履行使用者的合约责任需要实现安全和通信机制,例如验证、封送、加密和消息路由。这些机制通常以不同于应用程序业务逻辑的速率和原因发生更改。
  • 该 合约指定的数据格式可能与应用程序的内部表示形式不同。如果是这样,则必须转换数据。有时这种转换非常简单,就如重命名字段或转换数据类型,但有时这种转 换涉及复杂的结构和语义转换。例如,大多数服务都会公开粗粒度的、基于类型的接口,以优化它们在分布式环境中的使用。因此,从面向对象的应用程序调用对服 务的操作时,来自多个应用程序细粒度对象的信息通常需要进行聚合,并转换为合约所指定的格式。同样,来自该操作的响应通常需要打散,然后再映射回细粒度对 象。
  • 您的组织可能无法控制由服务指定的合约。如果合约发生更改,将需要尽可能减少应用程序代码所受的影响。
  • 可以在应用程序与服务之间提供连接的通信通道通常会向该应用程序公开常规的、低级别的应用程序编程接口 (API)。此 API 可能包括 SendData 等常规函数。在大多数情况下,应用程序需要通过 ValidateCreditCard GetCustomerAddress 等方法来处理语义更加丰富的接口。
  • 某些合约可能会指定异步消息传递,即它们可能不会立即返回结果。而服务使用者必须准备接收来自该服务的单独结果消息。处理这些来自服务的传入消息所需要的事件驱动编程技术可能会极大提高应用程序的复杂程度。

解决方案

将实现合约使用者部分的代码封装到它自己的 Service Gateway 组件中。服务网关在访问服务时的作用类似于数据访问组件在访问应用程序数据库时的作用。二者都是作为其他服务的代理,封装连接源服务的细节,并执行所有必要转换。

Service Gateway 是特殊类型的 Martin Fowler 的 Gateway 模式 [Fowler03],此模式适合在面向服务的体系结构中使用,因此其主要任务是封装使用服务的应用程序对外部系统的访问。Service Gateway 通常与 Remote Facade [Fowler03] 交互,而不直接与外部系统进行交互。Remote Facade 可封装提供服务的应用程序中的复杂功能,并将该功能作为一个简单接口向使用服务的应用程序公开。Service Interface 是特殊类型的 Remote Facade,适合在面向服务的体系结构中使用。在面向服务的体系结构中,使用服务的应用程序的服务网关通常与提供服务的应用程序所公开的服务接口进行协作。下图说明了这种关系。

图 1:使用服务接口的服务的 Service Gateway

Service Gateway 组件封装了与服务进行通信的低级别细节。这些细节包括但不仅限于以下内容:

  • 通信通道。 Service Gateway 封装了与服务进行通信所需的所有低级别网络通信功能。例如,Service Gateway 隐藏了所有使用 SOAP over HTTP 与 Web Service 进行通信的细节。
  • 数据格式。 Service Gateway 可 以在应用程序中内部信息组织与服务的通信合约所规定的格式之间建立映射。例如,应用程序可能由一组相互协作的细粒度对象组成,但其所用 Web Service 可能需要将 XML 文档作为输入内容,并且提供 XML 文档作为结果。网关负责在细粒度对象接口和 XML 文档之间进行转换。
  • 服务发现。对于简单情形或不太复杂的情形,Service Gateway 应该封装发现适当服务的过程。这可能包括在配置文件中查找服务的网络地址,或使用 UDDI 等服务储存库。对于复杂的情形,例如需要根据不断变化的数据动态决定调用适当服务,服务发现功能可能会封装在它自己的服务网关组件中。
  • 进程适应器。 Service Gateway 应该适应应用程序的业务进程,以便与该服务一起工作。例如,对服务网关的单个调用可能会导致多次调用一个或多个服务操作。因此,服务网关向应用程序所提供的接口应该参照应用程序的进程,而不是参照通信和安全性协议。
  • 异步和同步调 用语义。 Service Gateway 将根据合约指定的调用语义调整使用服务的应用程序的调用语义(异步或同步)。例如,使用服务的应用程序的设计可能不支持合约中指定的异步调用语义。这时,使用服务的应用程序的服务网关必须将该应用程序的同步调用转换为合约中所指定的异步协议。

无需将 Service Gateway 实现为一个对象。实际上,将某些功能分隔到单独对象中可能更加有利。例如,如果使用单独对象,使用代码生成方法来创建网关的某些部分可能更为简单。如果服 务提供者发布了描述所需数据格式(例如,以 WSDL 或 XML 架构的形式)的元数据,用于实现内部应用程序格式与服务期望格式之间的映射数据的代码则是这种映射的理想选择。此元数据可用于生成封装这种映射的强类型 类。

测试考虑事项

Service Gateway 可以明显提高系统的可测试性。服务网关会将访问服务的所有细节封装到一个组件中,并将该组件隐藏在不直接依赖于基础通信通道的接口之后。因此可以在测试过程中将网关替换为 Service Stub [Fowler03]。Service Stub 根本不会访问外部系统,但会将用于模拟外部系统的结果直接返回给应用程序逻辑。Service Stub 还可用于模拟错误情况,例如不可用的外部服务。

结果上下文

使用服务网关组件将应用程序和与服务通信细节隔离开来,具有下列优缺点:

优点

  • 通过将服务访问逻辑与应用程序的其他部分分隔开来,可以轻松更改应用程序所访问的服务。例如,您可能希望更换为相同服务的较新版本,或使用其他供应商提供的服务级别保证更好的服务。如果可以自动生成进行数据映射的代码,则切换到其他服务更加容易。
  • Service Gateway 可隐藏从应用程序访问服务的复杂性。这样就提高了应用程序组件和服务访问组件的重用性。应用程序不直接引用服务,因此不受任何实现细节和服务位置的影响。 将服务访问逻辑封装到一个单独的层中还会提高访问逻辑的重用性,因为只要使用相同的传输和验证机制,就能为多个服务调用所使用。
  • Service Gateway 是提供公用功能(如异步调用、缓存和错误处理)的理想工具。

缺点

  • Service Gateway 增加了复杂性,这对于简单解决方案可能并无必要。特别是当您的组织将仅访问几个相对静态的服务,则可以不需要支持映射组件自动生成所需的工作和基础结构。
  • 一个特定服务网关负责与一个服务交互。如果要协调多个服务,则必须由另一个组件处理,例如 Three-Layered Services Application中指定的业务过程组件。

服 务网关通常包含在一个应用程序中。因此可能导致代码重复,前提是:如果多个应用程序访问同一服务,则两个应用程序可能重复网关功能。开发可重用服务网关组 件是一个备选方法。另一个解决方案是,将公用功能提取到在组织内本地部署的该公用功能自己的服务中。在这种情况下,还可使用前一章讨论的某些分布式计算解 决方案(例如 Remote Facade)。

第6章 服务模式 在 .NET 中实现 Service Gateway(服务网关)的更多相关文章

  1. 第6章 服务模式 在 .NET 中实现 Service Interface

    上下文 您 的应用程序部署在 Microsoft Windows? 操作系统上.您决定将应用程序的某一块功能作为 ASP.NET Web Service 公开.互操作性是一个关键问题,因此您无法使用仅 ...

  2. spring cloud微服务快速教程之(十) gateway 服务网关

    0.前言 gateway是spring的二代网关, 作为Netflix Zuul的替代者,是异步非阻塞网关 ,ZUUL2也是异步非阻塞的,但未纳入spring cloud整合计划 基于WebFlux  ...

  3. 第5章分布式系统模式 在 .NET 中使用 DataSet 实现 Data Transfer Object

    要在 .NET Framework 中实现分布式应用程序.客户端应用程序需要显示一个窗体,该窗体要求对 ASP.NET Web Service 进行多个调用以满足单个用户请求.基于性能方面的考虑,我们 ...

  4. PHP中应用Service Locator服务定位及单例模式

    单例模式将一个对象实例化后,放在静态变量中,供程序调用. 服务定位(ServiceLocator)就是对象工场Factory,调用者对象直接调用Service Locator,与被调用对象减轻了依赖关 ...

  5. 使用 Loki 微服务模式部署生产集群

    转载自:https://mp.weixin.qq.com/s?__biz=MzU4MjQ0MTU4Ng==&mid=2247500523&idx=1&sn=0994af2b50 ...

  6. Linux Systemd——在RHEL/CentOS 7中启动/停止/重启服务

    RHEL/CentOS 7.0中一个最主要的改变,就是切换到了systemd.它用于替代红帽企业版Linux前任版本中的SysV和Upstart,对系统和服务进行管理.systemd兼容SysV和Li ...

  7. 在CentOS 7中启动/停止/重启服务

    RHEL/CentOS 7.0中一个最主要的改变,就是切换到了systemd.它用于替代红帽企业版Linux前任版本中的SysV和Upstart,对系统和服务进行管理.systemd兼容SysV和Li ...

  8. Android 如何判断指定服务是否在运行中 “Service”

    如何判断一个服务是否正在运行中: /** * 判断某个服务是否正在运行的方法 * * @param mContext * @param serviceName 是包名+服务的类名 * @return ...

  9. 基于云计算的IaaS、PaaS、SaaS三种服务模式的区别

    Infrastructure-as-a-Service(IaaS) - 基础即设施服务 基础设施主要包括网络系统(networking).存储设备(storage).服务器(servers).虚拟化技 ...

随机推荐

  1. 05-- C++ 类的静态成员详细讲解

     C++ 类的静态成员详细讲解    在C++中,静态成员是属于整个类的而不是某个对象,静态成员变量只存储一份供所有对象共用.所以在所有对象中都可以共享它.使用静态成员变量实现多个对象之间的数据共享不 ...

  2. POJ_2411_Mondriaan's Dream_状态压缩dp

    Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 15407   Accepted: 888 ...

  3. 重新理解 Monad

    对于大多数刚刚入门函数式编程的同学来说,monad(单子.又叫单体)可能是这里面的一道坎.你可能对 map . flatMap 以及 filter 再熟悉不过,可是到了高阶的抽象层次上就又会变得一脸懵 ...

  4. 【剑指Offer】61、序列化二叉树

      题目描述:   请实现两个函数,分别用来序列化和反序列化二叉树.   解题思路:   序列化是指将结构化的对象转化为字节流以便在网络上传输或写到磁盘进行永久存储的过程.反序列化是指将字节流转回结构 ...

  5. CodeForces 245C-Game with Coins

    题意:给你一个n,紧接着n个正数,然后有一种操作:选择一个x满足(x*2+1<=n)一次可以把下标为  x,2*x,2*x+1的三个数同时减一: 问,最少几次操作可以使n个数字变为零(已经是0的 ...

  6. [luogu2679] 子串 (多维dp)

    传送门 Description 有两个仅包含小写英文字母的字符串 A 和 B . 现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来 ...

  7. 2018 noip 考前临死挣扎

    基础算法 倍增 贪心 分块 二分 三分 数据结构 线段树 对顶堆 数学 质数 约数 同余 组合 矩阵乘法 图论 二分图判定以及最大匹配 字符串 Tire树 KMP 最小表示法 Hash Manache ...

  8. ROA与SOA概念

    SOA:面向服务的架构,可以理解为从客户的角度,将软件设计为模块式结构,可以根据用户的需要自由添加.定制模块,偏重于向用户靠拢 ROA:面向资源的架构,从资源的角度,严格按照计算机规范设计软件,偏重科 ...

  9. [bzoj3717][PA2014]Pakowanie_动态规划_状压dp

    Pakowanie bzoj-3717 PA-2014 题目大意:给你n个物品m个包,物品有体积包有容量,问装下这些物品最少用几个包. 注释:$1\le n\le 24$,$1\le m\le 100 ...

  10. STM32的IO配置点灯

    1.led.c的详细的代码: /*----------------------------------------------------------*/ #include "led.h&q ...