微服务架构的演进过程

什么是微服务架构

微服务架构(Microservice Architecture)是一种架构概念,旨在通过将功能分解到各个离散的服务中以实现对解决方案的解耦。你可以将其看作是在架构层次而非获取服务的

类上应用很多SOLID原则。微服务架构是个很有趣的概念,它的主要作用是将功能分解到离散的各个服务当中,从而降低系统的耦合性,并提供更加灵活的服务支持。

概念:把一个大型的单个应用程序和服务拆分为数个甚至数十个的支持微服务,它可扩展单个组件而不是整个的应用程序堆栈,从而满足服务等级协议。

定义:围绕业务领域组件来创建应用,这些应用可独立地进行开发、管理和迭代。在分散的组件中使用云架构和平台式部署、管理和服务功能,使产品交付变得更加简单。

本质:用一些功能比较明确、业务比较精练的服务去解决更大、更实际的问题。

传统三层服务架构

三层架构的具体内容如下(MVC):

  1. 表示层: 用户使用应用程序时,看到的、听见的、输入的或者交互的部分。
  2. 业务逻辑层: 根据用户输入的信息,进行逻辑计算或者业务处理的部分。
  3. 数据访问层: 关注有效地操作原始数据的部分,如将数据存储到存储介质(如数据库、文件系统)及从存储介质中读取数据等。

虽然现在程序被分成了三层,但只是逻辑上的分层,并不是物理上的分层。也就是说,对不同层的代码而言,经过编译、打包和部署后,所有的代码最终还是运行在同一个进程中。而这,就是所谓的单块架构。

业务拆分服务架构

为什么会进行业务拆分呢,大多数是因为,当一个程序的功能越来越臃肿的时候,发布,迭代,新人接手等问题会日益严重,这时候,我们就需要对业务进行拆分重新。

举个例子:

这是我入职的某家公司的业务架构图,我们可以很清晰的将不同业务进行理解。

从我的角度来看,后端开发的职责就是合理的将数据进行流动。数据的来源基本都是产生于DB,最后流出于API。

扩展微服务架构

首先要说一些是微服务的特性:

  • 单一职责: 微服务架构中的每个服务,都是具有业务逻辑的,符合高内聚、低耦合原则以及单一职责原则的单元,不同的服务通过“管道”的方式灵活组合,从而构建出庞大的系统。(这个点在业务架构拆分的时候基本已经完成)
  • 轻量级通信: 服务之间通过轻量级的通信机制实现互通互联,而所谓的轻量级,通常指语言无关、平台无关的交互方式。(通常在微服务迭代前期,我们都推荐用http协议进行,虽然性能比较低,但是迭代速度会比较快)
  • 独立性: 每个服务在应用交付过程中,独立地开发、测试和部署。
  • 进程隔离: 单块架构中,整个系统运行在同一个进程中,当应用进行部署时,必须停掉当前正在运行的应用,部署完成后再重启进程,无法做到独立部署。在微服务架构中,应用程序由多个服务组成,每个服务都是高度自治的独立业务实体,可以运行在独立的进程中,不同的服务能非常容易地部署到不同的主机上。

从特性,我们可以看到其本质:

  • 微服务也可以被认为是一种组件,但是跟传统组件的区别在于它可以独立部署,因此它的一个显著的优势。另外一个优点是,它在组件与组件之间定义了清晰的、语言无关、平台无关的规范接口,耦合度低,灵活性非常高。但它的不足之处是,分布式调用严重依赖于网络的可靠性和稳定性。
  • 在单块架构中,企业一般会根据技能划分团队,在这种组织架构下,即便是简单的需求变更都有可能需要跨团队协作,沟通成本很高。而在微服务架构中,它提倡以业务为核心,按照业务能力来组织团队,团队中的成员具有多样性的技能。
  • 在单块架构中,应用基本上是基于“项目模式”构建的,即项目启动时从不同技能资源池中抽取相关资源组成团队,项目结束后释放所有资源。这种情况下团队成员缺乏主人翁意识和产品成就感。
  • 微服务架构中,提倡针对不同的业务特征选择合适的技术方案,有针对性的解决具体业务问题,而不是像单块架构中采用统一的平台或技术来解决所有问题。
  • 微服务架构提供自主管理其相关的业务数据,这样可以随着业务的发展提供数据接口集成,而不是以数据库的方式同其他服务集成。另外,随着业务的发展,可以方便地选择更合的工具管理或者迁移业务数据。

同样为服务也会有缺点:

性能: 分布式系统是跨进程、跨网络的调用,受网络延迟和带宽的影响。

可靠性: 由于高度依赖于网络状况,任何一次的远程调用都有可能失败,随着服务的增多还会出现更多的潜在故障点。因此,如何提高系统的可靠性、降低因网络引起的故障率,是系统构建的一大挑战。

异步: 异步通信大大增加了功能实现的复杂度,并且伴随着定位难、调试难等问题。

数据一致性: 要保证分布式系统的数据强一致性,成本是非常高的,需要在 C(一致性)A(可用性)P(分区容错性) 三者之间做出权衡。

运维成本增高:运维主要包括配置、部署、监控与告警和日志收集四大方面。微服务架构中,每个服务都需要独立地配置、部署、监控和收集日志,成本呈指数级增长。

微服务的问题解决方案

如何访问

一般使用apigateway方式实现,这个api gateway不一定是一个转发器,可能只是一个封装好的sdk代码。

他的作用包括:

提供统一服务入口,让微服务对前台透明
聚合后台的服务,节省流量,提升性能
提供安全,过滤,流控等API管理功能

如何通信

通信的话,这里我还是保留我意见,在人力不充足和拆分前期,优先使用http协议。(同样是封装在api gateway中,这里需要进行版本控制)

异步消息调用则用(Kafka, rabiitmq)

我们在考虑同步和异步调用的时候要做一些取舍,通常根据业务类型来,如果要求数据的强一致性,我们一般选用同步调用。相对于同步的话,异步也更加复杂。但是异步系统能更好的面对大流量的冲击。

如何实现动态感知

动态感知这个通常我们会选用一个开源的高可用的KV组件进行。

如果是GO的话,常用的是ETCD。

在微服务架构中,一般每一个服务都是有多个拷贝,来做负载均衡。一个服务随时可能下线,也可能应对临时访问压力增加新的服务节点。服务之间如何相互感知?服务如何管理?

这就是服务发现的问题了。一般有两类做法,也各有优缺点。基本都是通过etcd等类似技术做服务注册信息的分布式管理。当服务上线时,服务提供者将自己的服务信息

注册到etcd(或类似框架),并通过心跳维持长链接,实时更新链接信息。服务调用者通过etcd寻址,根据可定制算法, 找到一个服务,还可以将服务信息缓存在本地以提高性能。

当服务下线时,etcd会发通知给服务客户端(pub/sub)。

当某个节点崩溃时如何处理

这个其实关注得多,但是应用得少。通常,我们在做服务的时候,会提前考虑到流量峰值的情况,而且微服务的话,水平扩容是很方便的。

但是,肯定会存在这个风险。所以如果没有特别的保障,结局肯定是噩梦。当我们的系统是由一系列的服务调用链组成的时候,我们必须确保任一环节出问题都不至于影响整体链路。相应的手段有很多:

  • 重试机制(api gateway sdk中应该具有此项功能)
  • 限流,有服务提供方提供,ip计数方案,令牌桶方案(限定桶最大值,写入,访问方先获取令牌才能继续进行,数据结构-栈)。
  • 熔断机制,当访问一次服务在特定时间内失败次数达到一定程度,首先发警报,然后停止对此服务的调用。
  • 负载均衡,通过流量分配策略(和nginx的upstream异曲同工,但是微服务还可以加上服务健康状态权重动态分配,这里就比较复杂了)
  • 服务降级,(水平缩减自己的服务,减少DB线程池等)

目前我司迭代的微服务架构如下,并加入了异步数据同步的方式:

总结

没有完美的架构,要通过不断迭代处理,找出适合自己业务的架构。

所有脱离业务的架构都是吹牛逼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章