TL; DR::如果您要分析任何给定的微服务架构,并且要将服务 A 和 B 合并在一起,以避免 A 不起作用是因为 B 损坏了(因为它严重依赖于 B ,并且根据项目规范 A 无法完成请求 B 是否有问题),考虑到迭代次数足够,您是否不就只能以单片架构结束?
这是我们公司最近提出的一个问题,恐怕他们正在做一个短视的决定。
架构摘要:
-这是我们第一个使用微服务架构的系统
-我们有N
个微服务(具体来说,每个微服务都是在集群的kubernetes容器中运行的JAR)。
-每个JAR通过HTTP API公开单个服务(例如auth
,users
,images
...)
-我们有99%的服务需要用户授权,但不需要身份验证(在另一层上完成,我们的服务假定,如果请求到达该请求,则请求标头包含有效的 user令牌
-要将用户令牌转换为有形的内容(例如用户信息),我们向users
服务发出请求
-当前,每项服务都会执行该操作,以验证用户是否符合某些特定于服务的条件。
现在,在一次会议上,几位高级开发人员提出了他们的担忧,即如果users
由于某种原因而失败(不一定是与软件相关的,我们仅假设为这些服务分配的机器有故障),一切都会停止工作,使其(在他们看来)成为具有额外步骤的准整体架构。他们为避免这种情况的建议是将users
服务转换为静态库,并将其作为依赖项添加到需要它的所有服务中,因此每个服务本身都包含此功能,而不是依赖于远程API。
但这不只是一个规格问题,而不是体系结构问题吗?它不像没有images
的{{1}} API(从技术上来说)无法运行,只是根据当前项目规范,尚不清楚该怎么做情况下,因此就好像服务本身有故障一样失败。
之所以我个人认为这是一个短视的决定,是因为人们可能会认为微服务之间的任何形式的通信都可以视为这种风险。这种情况只是一个非常明显的潜在故障点,也是“可能破坏”分析的第一次迭代。充分考虑一下,如果未指定“计划B”,则可以以相同的方式对待由许多服务使用的任何端点(例如,如果无法从users
服务中获取图像,请使用预定义的占位符图片)
答案 0 :(得分:1)
在对所涉及的业务用例不了解的情况下,我倾向于同意您的看法。我认为可以通过以下方式缓解问题:
尝试通过将响应缓存在单个服务可访问的集中式缓存系统中来减少服务的负载。使用事件源或更改数据捕获来保持缓存更新
在适当的情况下,探索在具有实例化视图和事件源或更改数据捕获的单个服务DB中引入实例化视图的可能性
探讨在断路器中使用回退响应的可能性。请注意,如果免费用户希望在用户服务中断时观看优质视频,则企业可能希望允许免费用户观看视频,而不是限制优质用户。
答案 1 :(得分:1)
我对您的主题有2条评论:
Re:规范。您可以为特定事件失败时的情况定义“替代”行为。
示例:图像服务从用户服务请求作者信息,以显示有关上载图像的人的信息。
我的理解是,如果图像服务无法获取作者信息,则您选择了图像请求失败。您可以选择将作者姓名显示为“ N / A”,或者如果用户服务不可用,则不显示任何用户信息和图像。
您定义替代路径。现在,当然每种方法都有优点和缺点,并且确实取决于场景。
Re:体系结构。
恕我直言,我认为微服务架构的好处之一是隔离单个服务。我不知道您当前的体系结构,但是在传统的微服务中,我希望用户服务具有隔离的存储,并且仅公开HTTP(或RPC等)接口供其他服务获取该信息。
如果您开始将其用作库,那么您将跌倒,一旦更改“用户服务”库,则必须在所有服务之间进行升级,否则架构或业务逻辑上的差异会随着时间的流逝而播放。在最坏的情况下,为升级创建顺序依赖性...
我认为您只需要考虑用户服务是体系结构的关键部分,并真的要努力使其具有高可用性,即确保至少将其部署在几个不同的主机(甚至是区域)上。支持它)
答案 2 :(得分:0)
当存在一些折衷可能通过另一质量属性的成本潜在地改善某些质量属性的折衷方案时,这对于架构决策而言是非常典型的。在您的情况下,决定将用户服务转换为库将提高可靠性,但问题是,哪些质量属性会受到影响。关于此服务的信息不多,但让我们推测一下。微服务样式的良好特性之一是能够维持服务的隔离开发生命周期。那是一种微服务,除非公共合同中有一些重大更改,否则用户组件可以独立于其他组件交付。例如,内部修复或改进可以随服务的新版本一起提供,并且应在不影响其他服务发布生命周期的情况下可用于其他服务。使用库,情况会有所不同-要发布一些关键(或非关键修复)的库,您必须更新依赖于此库的所有组件。即使考虑到此过程是自动化的,它也可能会带来一些额外的操作问题,这些问题可能会频繁发生,如果此过程可确保零停机时间,当某些服务已更新时某些服务更新失败时如何处理故障情况。另一个方面是可伸缩性-作为一项服务,用户组件可以根据其所有使用者产生的典型负载进行独立扩展。对于库,假定它应该与其他组件共享资源,更糟糕的是,它应该能够处理与库所使用的组件相同的负载,而无法独立配置资源消耗。安全性也可能是一个需要额外注意的方面,假定用户服务应使用某些数据源,该数据源可与库一起存储敏感信息,应允许所有其他服务访问此数据源,从而有可能损害数据安全性。 从另一方面来说,可以通过用户服务子组件的冗余来实现可靠性,例如,通过具有服务及其数据源的多个实例。
回到初始语句,您需要权衡和做出决定,这取决于哪种质量属性对整个系统更关键。如果由于此过程的某些限制或高昂的成本而难以实现高用户服务可用性,并且在这种情况下可以独立更新,则这种情况相对罕见,则值得考虑迁移到库,或者受此过程影响的质量属性对于系统体系结构可以表明,在提高用户服务可用性而不是牺牲微服务风格实现的质量属性的策略上,值得更多关注。
作为有关规范与体系结构问题的注释。我认为按照规格,您的意思是要求。架构始终由需求驱动,它们是架构的关注点,因此无论如何都是架构问题。