• 微服务设计模式


         微服务可以对你的企业产生积极的影响。因此,值得了解如何处理微服务架构(MSA)和一些微服务的设计模式,以及,微服务架构的一般目标或原则。以下是微服务架构方法中需要考虑的四个目标。

    降低成本。MSA将降低设计、实施和维护IT服务的总体成本。
    提高发布速度:MSA将提高从想法到部署服务的速度。
    提高复原力。MSA将提高我们服务网络的弹性。
    实现可视性。MSA支持对你的服务和网络有更好的可见性。
    你需要了解微服务架构建立的原则有哪些:

    可扩展性
    可用性
    弹性
    灵活性
    独立、自主
    分散的治理
    故障隔离
    自动配置


    通过DevOps持续交付
         遵循上述原则会带来一些挑战和问题,同时使你的解决方案或系统投入使用。这些问题对许多解决方案来说是很常见的。这些问题可以通过使用正确和匹配的设计模式来克服。有一些微服务的设计模式,这些模式可以分为五个模式。每种模式都包含许多模式。

    1_CKSVv4WkS8Okx572rX45HA

    分解模式
          按业务能力分解 微服务是关于使服务松散耦合和应用单一责任原则。它按业务能力进行分解。定义与业务能力相对应的服务。业务能力是业务架构建模的一个概念[2]。它是一个企业为了产生价值而做的事情。一个业务能力通常对应于一个业务对象,例如

    订单管理是对订单负责
    客户管理对客户负责

    按子域分解
           使用业务能力来分解一个应用程序可能是一个好的开始,但你会遇到所谓的 "上帝类",这并不容易分解。这些类在多个服务中是通用的。定义对应于领域驱动设计(DDD)子域的服务。DDD将应用程序的问题空间--业务--称为域。一个域是由多个子域组成的。每个子域对应于业务的不同部分。子域可以分类如下。

    核心--企业的关键差异化因素和应用中最有价值的部分
    支持性的--与企业的业务有关,但不是一个差异化的因素;可以在内部实施或外包
    通用型--与业务无关,最好是使用现成的软件来实施。
    订单管理的子域包括:

    产品目录服务
    库存管理服务
    订单管理服务
    交付管理服务

    通过事务/两阶段提交分解(2个)模式
    这种模式可以将服务分解到交易中。那么系统中就会有多个交易。分布式交易中的一个重要参与者是交易协调人[3]。分布式交易由两个步骤组成。

    准备阶段--在这一阶段,交易的所有参与者为提交做准备,并通知协调者他们已经准备好完成交易了
    提交或回滚阶段--在这个阶段,交易协调人向所有参与者发出提交或回滚命令
    2PC的问题是,与单个微服务的运行时间相比,它相当缓慢。协调微服务之间的交易,即使它们在同一个网络上,也会使系统变得很慢;所以这种方法通常不用于高负载的情况下。

    绞杀者模式
           你所经历的前三个设计模式是为Greenfield分解应用程序,但你所做的80%的工作是与brownfield应用程序,即大的、单一的应用程序(遗产代码库)。Strangler模式是一种救援或解决方案。这创造了两个独立的应用程序,它们在同一个URI空间中并肩生存。随着时间的推移,新重构的应用程序会 "扼杀 "或取代原来的应用程序,直到最后,你可以关闭这个单体应用程序。Strangler应用程序的步骤是转化、共存和消除[4]。

    转变--用现代方法创建一个平行的新站点。
    共存--让现有的网站暂时留在原地。从现有的网站重定向到新的网站,这样功能就可以逐步实现。
    消除--从现有网站上删除旧的功能。

    隔板模式
          这种模式将一个应用程序的元素隔离到池中,这样,如果其中一个发生故障,其他的将继续运行。这种模式被命名为隔板,因为它类似于船体的分段隔板。根据消费者负载和可用性要求,将服务实例分成不同的组。这种设计有助于隔离故障,并允许你为一些消费者维持服务功能,甚至在故障期间。

    Sidecar模式
          这种模式将应用程序的组件部署到一个单独的处理器容器中,以提供隔离和封装。这种模式也可以使应用程序由异构的组件和技术组成。这种模式被命名为Sidecar,因为它类似于摩托车上的副车。在该模式中,副车连接到父级应用,并为该应用提供支持功能。侧车也与父级应用共享相同的生命周期,与父级应用一起被创建和退役。sidecar模式有时被称为sidekick模式,是我们在文章中展示的最后一种分解模式。

    集成模式
          API网关模式 当一个应用程序被分解成较小的微服务时,有几个问题需要解决

    不同的渠道对多个微服务有多种调用:
    有必要处理不同类型的协议。
    不同的消费者可能需要不同格式的响应。
    API网关有助于解决由微服务实现引起的许多问题,不限于上述问题。

    API网关是任何微服务调用的单一入口点:
    它可以作为代理服务工作,将请求路由到相关的微服务。
    它可以汇总结果,并将其发回给消费者。
    这个解决方案可以为每个特定类型的客户端创建一个细粒度的API。
    它还可以转换协议请求和响应。
    它还可以卸载微服务的认证/授权责任。

    聚合器模式
    当把业务功能分解成几个较小的逻辑代码片断时,就有必要考虑如何协作处理每个服务返回的数据。这个责任不能由消费者来承担。

    Aggregator模式有助于解决这个问题。它讲述了我们如何聚合来自不同服务的数据,然后将最终的响应发送给消费者。这可以通过两种方式完成[6]。

    一个复合微服务将调用所有需要的微服务,整合数据,并在发送回之前转换数据。
    API网关也可以将请求分割给多个微服务,并在将数据发送给消费者之前将其汇总。
    如果要应用任何业务逻辑,那么建议选择一个复合微服务。否则,API网关是既定的解决方案。代理模式的API网关只是通过API网关暴露了微服务。在这个例子中,API网关有三个API模块。

    移动API,它实现了FTGO移动客户端的API。
    浏览器API,它实现了在浏览器中运行的JavaScript应用程序的API。
    公共API,为第三方开发者实现API。

    网关路由模式
         API网关负责请求的路由。一个API网关通过将请求路由到相应的服务来实现一些API操作。当它收到一个请求时,API网关会查询一个路由图,指定将请求路由到哪个服务。例如,路由图可以将HTTP方法和路径映射到服务的HTTP URL。这个功能与NGINX等Web服务器提供的反向代理功能相同。

    链式微服务模式
          单个服务或微服务会有多个依赖关系,例如:销售微服务会依赖产品微服务和订单微服务。链式微服务设计模式将帮助你为你的请求提供综合结果。

    一个微服务收到的请求:1,然后与微服务2进行通信,它可能与微服务3进行通信。所有这些服务都是同步调用。

    分支模式
          一个微服务可能需要从多个来源获得数据,包括其他微服务。Branch微服务模式是Aggregator和Chain设计模式的混合体,允许从两个或多个微服务同时进行请求/响应处理。被调用的微服务可以是微服务的链。分支模式也可用于调用不同的微服务链,或根据你的业务需求调用单一的链。

    客户端UI组成模式
         当通过分解业务能力/子域来开发服务时,负责用户体验的服务必须从几个微服务中提取数据。在单体世界中,过去只有一个从UI到后台服务的调用,以检索所有数据并刷新/提交UI页面。然而,现在情况就不一样了。有了微服务,UI必须被设计成一个具有多个部分/区域的屏幕/页面的骨架。每个部分都会调用一个单独的后台微服务来获取数据。像AngularJS和ReactJS这样的框架可以很容易地做到这一点。这些屏幕被称为单页应用程序(SPA)。每个团队开发一个客户端UI组件,如AngularJS指令,为他们的服务实现页面/屏幕的区域。一个UI团队负责实现页面骨架,通过合成多个特定服务的UI组件来构建页面/屏幕。

    数据库模式
         定义微服务的数据库架构时,我们需要考虑以下几点:

    服务必须是松散耦合的。它们可以被独立开发、部署和扩展。
    业务事务可以执行跨越多个服务的不变性。
    一些业务交易需要查询由多个服务拥有的数据。
    数据库有时必须被复制和共享,以便进行扩展。
    不同的服务有不同的数据存储要求。

    每个服务的数据库
    为了解决上述问题,必须为每个微服务设计一个数据库;它必须是只属于该服务的。它应该只被微服务的API访问。它不能被其他服务直接访问。例如,对于关系型数据库,我们可以使用private-tables-per-service,schema-per-service,或者database-server-per-service。

    每个服务共享数据库
         我们已经谈论过每个服务一个数据库是微服务的理想选择。这对微服务来说是一种反模式。但是,如果应用程序是一个单体,并试图分解成微服务,反规范化就不那么容易了。在后期阶段,我们可以转到每个服务的数据库模式。每个服务共享一个数据库并不理想,但这是上述情况下的工作方案。大多数人认为这是对微服务的反模式,但对于棕地应用来说,这是一个很好的开始,可以将应用分解成更小的逻辑片段。这不应该应用于绿地应用。

    命令查询责任隔离(CQRS)
          一旦我们实现了每个服务的数据库,就有了查询的要求,这需要从多个服务中联合获取数据,这是不可能的。CQRS建议将应用程序分成两部分--命令端和查询端。

    命令端处理创建、更新和删除请求。
    查询端通过使用物化视图来处理查询部分。
    事件源模式通常与它一起使用,为任何数据变化创建事件。物化的视图通过订阅事件流来保持更新。事件源 大多数应用程序都与数据打交道,典型的方法是让应用程序保持当前状态。例如,在传统的创建、读取、更新和删除(CRUD)模型中,一个典型的数据过程是从存储中读取数据。它包含了锁定数据的限制,经常使用事务。

    事件源模式
          事件源模式定义了一种处理数据操作的方法,该方法由一连串的事件驱动,每一个事件都记录在一个仅有的存储器中。应用程序代码发送一系列的事件,这些事件必须描述发生在数据上的每一个动作,在那里它们被持久化。每个事件代表了一组对数据的变化(如AddedItemToOrder)。这些事件被持久化在一个作为记录系统的事件存储中。事件存储所发布的事件的典型用途是维护实体的物化视图,因为应用程序中的操作改变了它们,并与外部系统集成。例如,一个系统可以维护一个所有客户订单的物化视图,用来填充用户界面的部分内容。当应用程序添加新的订单,添加或删除订单上的项目,以及添加运输信息时,描述这些变化的事件可以被处理并用于更新物化视图。图中显示了该模式的概述。

    0_iZ03fLMycI4iuQmv (1)

    Saga模式
         当每个服务都有自己的数据库,而一个业务交易跨越多个服务时,我们如何确保跨服务的数据一致性?每个请求都有一个补偿性请求,在请求失败时执行。它可以通过两种方式实现。

    编排(Choreography)--当没有中央协调时,每个服务产生并监听另一个服务的事件,并决定是否应该采取某种行动。编排是一种指定两方或多方的方式;其中没有任何一方对其他方的流程有任何控制,或者也许对这些流程有任何可见性--可以协调他们的活动和流程以分享信息和价值。当需要跨领域的控制/可见性的协调时,使用编排。在一个简单的场景中,你可以把编排想成是一个网络协议。它规定了各方之间可接受的请求和响应模式。


    1_xZ6eC77SLLdFSRBMsRWj5Q

    协调 - 一个协调者(对象)负责一个传奇的决策和排序业务逻辑。当你对一个流程中的所有角色都有控制权时,当他们都在一个控制域中,你可以控制活动的流程时。当然,这是最常见的,当你指定一个将在你所控制的一个组织内颁布的业务流程。


    1_4jFx2NZZKHs5UHpLOwdPbA

    可观察性模式
          日志聚合 考虑一个由多个服务组成的应用程序的用例。请求通常跨越多个服务实例。每个服务实例都会以标准化的格式生成一个日志文件。我们需要一个集中的日志服务,将每个服务实例的日志聚合起来。用户可以搜索和分析这些日志。他们可以配置警报,当某些消息出现在日志中时,就会触发警报。例如,PCF确实有日志聚合器,它从PCF平台的每个组件(路由器、控制器、Diego等)和应用程序中收集日志。AWS Cloud Watch也有同样的功能。性能指标 当服务组合因微服务架构而增加时,对交易进行监控变得非常关键,这样就可以监控模式,并在问题发生时发出警报。需要一个指标服务来收集关于单个操作的统计数据。它应该聚集一个应用服务的度量,提供报告和警报。有两种聚合度量的模式。

    推送--服务将指标推送给指标服务,例如NewRelic、AppDynamics。
    拉--指标服务从服务中提取指标,例如Prometheus。

    分布式跟踪
         在微服务架构中,请求通常跨越多个服务。每个服务通过在多个服务中执行一个或多个操作来处理一个请求。虽然在故障排除中,值得拥有追踪ID,但我们还是要追踪一个请求的端到端。解决方案是引入一个交易ID。可以使用以下方法:

    给每个外部请求分配一个唯一的外部请求ID。
    将外部请求ID传递给所有的服务。
    在所有的日志信息中包括外部请求ID。

    健康检查
         当微服务架构被实施后,有可能某个服务已经启动但无法处理事务。每个服务都需要有一个端点,可以用来检查应用程序的健康状况,如健康。这个API应该o检查主机的状态,与其他服务/基础设施的连接,以及任何特定的逻辑。

    跨领域的关注模式
         外部配置
    一个服务通常也会调用其他服务和数据库。对于每个环境,如开发、QA、UAT、prod,端点URL或一些配置属性可能是不同的。这些属性中的任何一个变化都可能需要重新构建和部署服务。为了避免修改代码,可以使用配置。将所有配置外部化,包括端点URL和凭证。应用程序应该在启动时或在运行中加载它们。这些可以在启动时被应用程序访问,也可以在不重启服务器的情况下被刷新。

    服务发现模式
    当微服务进入画面时,我们需要解决在调用服务方面的一些问题。通过容器技术,IP地址被动态地分配给服务实例。每次地址改变时,消费者服务就会中断,需要手动改变。每个服务的URL都必须被消费者记住,并成为紧耦合的。需要创建一个服务注册表,它将保存每个生产者服务的元数据和每个服务的规范。一个服务实例在启动时应向注册表注册,在关闭时应取消注册。有两种类型的服务发现。

    客户端:例如:Netflix Eureka。
    服务器端:例如。AWS ALB。

    0_-4rIpSgcZM0cKXzq

    断路器模式
         一个服务通常会调用其他服务来检索数据,而下游的服务有可能会出现故障。这样做有两个问题:第一,请求会一直流向停机的服务,耗尽网络资源,并降低性能。第二,用户体验会很差,无法预测。消费者应该通过代理调用一个远程服务,其行为方式类似于一个断路器。当连续失败的次数超过阈值时,断路器就会跳闸,在超时期间,所有试图调用远程服务的尝试都会立即失败。超时结束后,断路器允许有限数量的测试请求通过。如果这些请求成功,断路器就会恢复正常运行。否则,如果出现了故障,超时期又开始了。这种模式适用于防止应用程序试图调用远程服务或访问共享资源,如果这种操作很可能失败。

    0_Zx8wWPh_QHqqoV5u

    蓝绿部署模式
          通过微服务架构,一个应用程序可以有许多微服务。如果我们停止所有的服务,然后部署一个增强的版本,停机时间将是巨大的,并可能影响业务。此外,回滚将是一场噩梦。蓝绿部署模式避免了这一点。蓝绿部署策略的实施可以减少或消除停机时间。它通过运行两个相同的生产环境,即蓝色和绿色,来实现这一目标。让我们假设绿色是现有的实时实例,蓝色是应用程序的新版本。在任何时候,只有一个环境是实时的,实时环境为所有生产流量服务。所有的云平台都提供了实施蓝-绿部署的选项。

    0__WHTafxMA_0-C0V4






    今天先到这儿,希望对云原生,技术领导力, 企业管理,系统架构设计与评估,团队管理, 项目管理, 产品管管,团队建设 有参考作用 , 您可能感兴趣的文章:
    领导人怎样带领好团队
    构建创业公司突击小团队
    国际化环境下系统架构演化
    微服务架构设计
    视频直播平台的系统架构演化
    微服务与Docker介绍
    Docker与CI持续集成/CD
    互联网电商购物车架构演变案例
    互联网业务场景下消息队列架构
    互联网高效研发团队管理演进之一
    消息系统架构设计演进
    互联网电商搜索架构演化之一
    企业信息化与软件工程的迷思
    企业项目化管理介绍
    软件项目成功之要素
    人际沟通风格介绍一
    精益IT组织与分享式领导
    学习型组织与企业
    企业创新文化与等级观念
    组织目标与个人目标
    初创公司人才招聘与管理
    人才公司环境与企业文化
    企业文化、团队文化与知识共享
    高效能的团队建设
    项目管理沟通计划
    构建高效的研发与自动化运维
    某大型电商云平台实践
    互联网数据库架构设计思路
    IT基础架构规划方案一(网络系统规划)
    餐饮行业解决方案之客户分析流程
    餐饮行业解决方案之采购战略制定与实施流程
    餐饮行业解决方案之业务设计流程
    供应链需求调研CheckList
    企业应用之性能实时度量系统演变

    如有想了解更多软件设计与架构, 系统IT,企业信息化, 团队管理 资讯,请关注我的微信订阅号:

    MegadotnetMicroMsg_thumb1_thumb1_thu[2]

    作者:Petter Liu
    出处:http://www.cnblogs.com/wintersun/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 该文章也同时发布在我的独立博客中-Petter Liu Blog。

  • 相关阅读:
    Day08_固化命令、grep、sed及awk命令
    Day07_网络管理、SSH、shell及元字符
    Day06_nginx及反向代理、共享存储nfs
    安装Apache所踩的的坑
    使用JS制作小游戏贪吃蛇
    清除浮动的几种方式
    纯CSS3图片反转
    在JAVASCRIPT中,为什么document.getElementById不可以再全局(函数外)使用?
    关于钉钉开发,心得
    javascript计算两个时间差
  • 原文地址:https://www.cnblogs.com/wintersun/p/16439646.html
Copyright © 2020-2023  润新知