api网关和rpc微服务
对于有关微服务和API网关的所有嗡嗡声,发现细节可能令人惊讶地困难。 我想起了西德尼·哈里斯(Sidney Harris)的那幅漫画,该漫画提出了一个复杂的数学公式的第一步, 然后出现了奇迹 ,光辉的解决方案的突然出现促使观察者评论说,也许我们应该在第二步中更加明确。
由于这些模式解决了几乎仅在规模上出现的问题,因此,已发表的文章显然很少涉及这些实现的一些最棘手的细节。
本文假定您熟悉微服务的好处(较小的存储库,与语言无关的开发,更容易的重构等 ),并且您了解API网关作为它们前面的基础的作用。 本文的目的是对网关+微服务领域中潜在的问题或解决方案中出现的一些架构模式进行分类。
找出问题
对于那些希望将网关+微服务体系结构作为潜在的缓解单片应用程序复合问题的人来说,我们可能会遇到一些坏消息:网关+微服务解决方案的优势可能已经过分简化了其销售范围。 您可能需要克服一些重大挑战,并在“第二步”中更加明确。
七大跨领域应用关注点
即使将您的整体应用程序精心地构造为包和服务类,也很有可能应用程序的某些方面设计会使其组件难以分割成专用的微服务而无需重构。
为什么? 因为通常,应用程序的组件依赖于在应用程序范围内被视为“全局”的功能。 这就是从一开始就使其更容易开发的原因。
以下是应用程序中最常见的跨领域问题的简短列表:
- 认证方式
- 授权书
- 届会
- 饼干
- 快取
- 记录中
- 对其他服务的依赖
让我们仔细看看每个项目。
认证方式
网关+微服务生态系统中的身份验证最好由产生JSON Web令牌或一些其他auth令牌的服务来处理,这些令牌可以包含在后续请求中。 令牌(由网关( 仅由网关))评估令牌,以确定请求是否得到正确验证。
授权书
与身份验证密切相关,网关+微服务生态系统中的授权应该可以使用令牌(例如,以自定义HTTP标头发送)进行授权。 应该在将请求代理到任何微服务之前执行此任务。 将此视为单一责任原则 :每个微服务仅关心一件事,并且该事还不能包括权限检查。
届会
如前所述,此处的建议是避免使用支持令牌的会话,以便避免在微服务中查找用户特定的数据。 当需要时,网关应将会话数据(例如,来自解密的令牌)一起传递给微服务。
可以说,可以仅传递一个会话标识符,然后让每个微服务根据12因子应用程序的明智建议从附加资源(例如Redis)中查找会话数据。
在某些情况下(但并非总是如此),该方法可以简化重构过程。 例如,当网关指定会话ID时,无法在微服务中使用PHP的session_start()
和生成的$_SESSION
超全局变量。 在这种情况下,您将需要推出自己的解决方案。 而且,如果您要重新发明轮子,最好将它放在一个地方(在网关中),并从繁琐的工作中省去微服务。
饼干
像会话一样,您的微服务最好避免使用cookie,并且如果需要,它们可以更轻松,更干净地在网关中实现。 当绝对需要时,如果将网关配置为代理它们,则微服务可以发出cookie,但是尝试使用cookie域时,您可能会面临其他麻烦。
快取
没有完美的缓存解决方案,因此不要过早优化您的生态系统。 轻松进入缓存并以较短的到期时间开始。 在微服务中维护REST友好的路由将允许在更高级别(例如Varnish)进行更简单的缓存。
一些用例应考虑将缓存数据作为模型的可能性,即事实的来源。 事件处理程序和命令行服务可能有助于保持缓存更新。
记录中
最好使用Loggly之类的日志聚合服务或简单地登录到stdout然后进行自己的日志聚合来完成网关+微服务生态系统的登录。
建议使用标准化的日志记录格式(例如,带有某些必填字段的JSON)。 这将允许在所有组件之间进行一致的报告。 在您的日志格式中留出空间,以容纳可以从网关传递到每个微服务的请求ID,因此您可以轻松地在参与处理特定请求的任何服务中找到日志条目。
对其他服务的依赖
整体应用程序中的代码重用通常是一件好事,但是在微服务体系结构中重用服务可能不是一个好主意。 将代码重新视为独立服务需要花费时间,并且重构可能意味着客户需要提出更多或不同的请求。
该系统的主要目标是鲁棒性:每个微服务都应尽可能独立,并且它们不应冒险级联失败,因为一个服务中断会触发另一个服务中断。
注册免费的Codeship帐户
网关的摘要角色
涵盖了应该在网关级别处理的最常见的跨领域问题之后,我们应该对网关需要做什么有一个更清晰的认识。
它应充当门控代理,执行授权规则,以便仅将适当的请求传递到每个微服务。 请记住,这里的确切实现细节可能会严重影响微服务。
与微服务通信
要做出的最大决定之一是网关如何与其微服务接口。 它们是否将作为软件包或插件安装(诸如Seneca之类的框架所使用的方法),还是将仅通过HTTP(由Amazon API Gateway使用 )与微服务通信? 您如何回答该问题将影响微服务的结构。
构建微服务
在实现了几种微服务之后,我开始观察它们的结构中的某些趋势。 我很犹豫将它们称为“模式”,部分原因是害怕激怒纯粹主义者,而且还因为这里的许多建议都归结为其他地方已列举的最佳实践。
考虑以下各项将帮助您充分利用网关+微服务实现。
最简单的例子
出于教育目的,从一个简单的示例开始是有帮助的:让我们考虑一个微服务,该微服务在给出两个字母的代码时返回一个国家的全名。 数据可以由单个数据库表提供,而无需任何外键。
根据12 Factor App的建议,我们将数据库视为支持服务 ,并将其作为资源附加。 不需要其他任何支持服务,仅需要数据库。 我们在环境中提供数据库凭据。
这个小巧的应用程序易于安装,数据迁移非常简单,并且易于测试。 这是“应用程序模型”的简单示例,有时也称为Backends-as-frontends 。
需要2个后勤服务的示例
接下来,让我们考虑一些更重要的事情:一种返回轮渡旅行时间,但会根据当地天气情况进行检查的服务。 假设轮渡路线存储在数据库中,则可以像前面的示例中那样将其附加为资源。
天气信息是从第三方API读取的,因此我们必须通过SDK或某种HTTP调用与之交互。 该示例比第一个示例难处理,因为我们的服务依赖于另一个服务。 由于我们不控制其他服务,因此,我们最好的办法是在天气API出现故障并希望正常运行时间的情况下,优雅地失败。
更复杂的例子
迟早,您将在应用程序中找到一个用例,在该用例中,您将考虑使一种微服务依赖另一种微服务的选择。 由于服务是作为插件开发的,因此这种方法很容易,但是当通过HTTP访问微服务时,它可能会有缺点。 该HTTP请求应该直接进入服务,还是应该通过网关利用其路由,身份验证和版本控制控件?
无论如何完成,调试都会变得更加困难,并且存在级联故障的明显风险。 有哪些选择?
如何避免相互依赖
如果您发现对另一个微服务的依赖似乎很诱人,请考虑以下替代方案:
- 重构客户端以向其他微服务发出附加请求。
- 简化作为依赖项所需的微服务。 如果您要重用它,那么它可能变得太复杂了。 当微服务是如此简单以至于它们的重用并没有显着的好处时,它们可能是最有价值的。
- 您是否将服务与模型混合? 如果一个微服务由于数据而依赖于另一个微服务,则该一个微服务应该附加到与另一个微服务相同的数据模型,这样就可以避免依赖性。 如果微服务想要重用业务逻辑 ,那么您需要考虑避免重复任何这些规则的最佳方法。 也许应该将两个微服务合并为一个,以便可以重复使用业务逻辑而无需重复。
- 命令行服务或cron作业可以帮助简化吗? 明智地使用通知和后端任务可以帮助保持微服务的清洁和集中。
其他结构:在网关中聚合
由于“应用程序模型”可能会令人费解(特别是如果它们具有多个依赖性),因此某些API网关通常可以通过将代码添加到相关的路由和/或控制器中来聚合来自不同服务的数据。 我听说过在网关中聚合数据的想法,即“分散收集”方法。
在网关中聚合数据的优点在于,它使客户端不必进行繁重的工作来组装来自多个请求的数据。 同样,它使微服务免于必须处理复杂的交互。
但是,这种方法有两个主要缺点。 如果在客户端或微服务中不希望处理多个请求并应用业务逻辑,那么在网关中就更是如此。 如果网关执行聚合,它将不再是简单的代理-实际上将包含需要仔细测试的业务逻辑。
许多可用的网关不提供此功能,因此依靠它会限制您对网关的选择或迫使您编写自己的网关,这对于从其服务而不是从其自定义网关中获取价值的企业来说,这是没有吸引力的主张。
其他结构:客户端汇总
在网关中聚合数据的另一种方法是在客户端中聚合数据。 最著名的实现可能是GraphQL ,但是对JSON API服务的彻底实现可以完成类似的工作(请参阅Stormpath关于“ 设计漂亮的REST + JSON API的演示”)。 最终结果是,提出和合并多个数据请求的责任留给了客户端。 允许网关及其微服务保持简单和简化。
这种方法的优点是可以让客户端负责,因此版本控制通常更简单(因为发布客户端的新版本通常比发布服务器端API的新版本容易)。 这种方法还可以避免数据获取不足和获取过多的问题。
尽管此方法可能依赖于相对较新的技术,但其最大的潜在缺点是业务逻辑。 如果需要任何业务逻辑来解释和合并多个请求,则您可能会在多个客户端中重复这些规则,因此可能会有行为不一致的风险。
摘要
希望有关网关+微服务架构的讨论能够阐明一些经常伴随的问题和疑虑。
没有能够满足每个人需求的灵丹妙药,但是某些趋势正在加速发展。 无服务器和AWS Lambda之类的技术有望使微服务变得更加细化,并且它们的简单性和可测试性带来的好处很难争辩。
当您按照本文的准则尝试针对不同用例的不同解决方案时,请保持智慧,并提防任何可能破坏代码简单性和可测试性的解决方案。 与任何架构一样,微服务的重复和实践将帮助您确定有效的解决方案。
翻译自: https://www.javacodegeeks.com/2017/10/design-patterns-api-gateways-microservices.html
api网关和rpc微服务