微服务架构详解
微服务是小型,独立且松散耦合的。一个小的开发人员小组可以编写和维护服务。
什么是微服务?
微服务是小型,独立且松散耦合的。一个小的开发人员小组可以编写和维护服务。
每个服务都是一个单独的代码库,可以由一个小的开发团队进行管理。
服务可以独立部署。团队可以更新现有服务,而无需重建和重新部署整个应用程序。
服务负责持久保存自己的数据或外部状态。这不同于传统模型,在传统模型中,一个单独的数据层处理数据持久性。
服务通过使用定义良好的API相互通信。每个服务的内部实现细节对于其他服务都是隐藏的。
服务不需要共享相同的技术堆栈,库或框架。
除了服务本身以外,其他一些组件还出现在典型的微服务体系结构中:
管理/编排。该组件负责在节点上放置服务,识别故障,在节点之间重新平衡服务等等。通常,此组件是诸如Kubernetes之类的现成技术,而不是定制的东西。
API网关。API网关是客户端的入口点。客户端不是直接调用服务,而是调用API网关,该网关将调用转发到后端的适当服务。
使用API网关的优势包括:
它使客户与服务脱钩。可以对服务进行版本控制或重构,而无需更新所有客户端。
服务可以使用非Web友好的消息传递协议,例如AMQP。
API网关可以执行其他跨领域功能,例如身份验证,日志记录,SSL终止和负载平衡。
好处
敏捷。由于微服务是独立部署的,因此更易于管理错误修复和功能发布。您可以在不重新部署整个应用程序的情况下更新服务,并在出现问题时回滚更新。在许多传统应用程序中,如果在应用程序的某个部分中发现了错误,则它可能会阻止整个发布过程。可能会保留新功能,等待集成,测试和发布错误修复。
小而专注的团队。微服务应足够小,以使单个功能团队可以构建,测试和部署它。小团队规模可提高敏捷性。大型团队的生产力通常较低,这是因为沟通速度较慢,管理开销增加并且敏捷性降低了。
小代码库。在整体应用程序中,随着时间的流逝,代码依赖关系趋于纠结。添加新功能需要在很多地方触摸代码。通过不共享代码或数据存储,微服务体系结构最大程度地减少了依赖性,从而使添加新功能更加容易。
技术融合。团队可以通过适当地混合使用各种技术来选择最适合其服务的技术。
故障隔离。如果单个微服务不可用,只要将任何上游微服务设计为正确处理故障(例如,通过实施断路),就不会破坏整个应用程序。
可扩展性。服务可以独立扩展,使您可以扩展需要更多资源的子系统,而无需扩展整个应用程序。使用Kubernetes或Service Fabric等编排器,可以将更高密度的服务打包到单个主机上,从而可以更有效地利用资源。
数据隔离。执行模式更新要容易得多,因为仅会影响单个微服务。在单片应用程序中,架构更新可能变得非常具有挑战性,因为应用程序的不同部分可能都接触相同的数据,从而使对架构的任何更改都具有风险。
挑战性
微服务的好处不是免费的。在着手微服务架构之前,需要考虑以下挑战。
复杂性。与等效的单片应用程序相比,微服务应用程序具有更多的活动部件。每种服务都比较简单,但是整个系统整体来说更复杂。
开发和测试。编写依赖于其他依赖服务的小型服务与编写传统的整体或分层应用程序所需要的方法不同。现有工具并非总是设计为与服务依赖项一起使用。跨服务边界进行重构可能很困难。测试服务依赖性也具有挑战性,尤其是在应用程序快速发展时。
缺乏治理。构建微服务的分散式方法具有优势,但也可能导致问题。您可能最终会遇到太多不同的语言和框架,从而使应用程序变得难以维护。在不过度限制团队灵活性的情况下,制定一些项目范围的标准可能很有用。这尤其适用于横切功能,例如日志记录。
网络拥塞和延迟。使用许多细粒度的服务可以导致更多的服务间通信。同样,如果服务链依赖关系太长(服务A调用B,调用C ...),则额外的延迟可能会成为问题。您将需要仔细设计API。避免使用过多的API,考虑序列化格式,并寻找使用异步通信模式的地方。
数据完整性。每个微服务负责自己的数据持久性。结果,数据一致性可能是一个挑战。尽可能采用最终的一致性。
管理。要成功使用微服务,需要成熟的DevOps文化。跨服务的相关日志记录可能具有挑战性。通常,日志记录必须将单个用户操作的多个服务调用关联起来。
版本控制。对服务的更新不得破坏依赖于该服务的服务。可以在任何给定时间更新多个服务,因此,如果不进行仔细的设计,则可能存在向后或向前兼容性的问题。
技能集。微服务是高度分布式的系统。仔细评估团队是否具有成功的技能和经验。
最佳实践
围绕业务领域对服务进行建模。
分散所有内容。各个团队负责设计和构建服务。避免共享代码或数据架构。
数据存储应该对拥有数据的服务专用。为每种服务和数据类型使用最佳存储。
服务通过精心设计的API进行通信。避免泄漏实施细节。API应该为域建模,而不是服务的内部实现。
避免服务之间的耦合。耦合的原因包括共享数据库架构和严格的通信协议。
将跨领域的问题(例如身份验证和SSL终止)卸载到网关。
将域知识置于网关之外。网关应在不了解业务规则或域逻辑的情况下处理和路由客户端请求。否则,网关将成为依赖项,并可能导致服务之间的耦合。
服务应具有松散的耦合和较高的功能凝聚力。可能会一起更改的功能应一起打包和部署。如果它们驻留在单独的服务中,则这些服务最终将紧密耦合,因为一项服务的更改将需要更新另一项服务。两个服务之间的交流过多可能是紧密耦合和低内聚性的征兆。
隔离故障。使用弹性策略可防止服务内的故障级联。请参阅弹性模式和设计可靠的应用程序。