一起玩转微服务(1)——概念

一、什么是微服务

随着各行各业公司的快速发展,业务规模的不断扩大,不可避免的造成原有架构不能够适应快速的增长和变化。这时,微服务就进入大家的视野,其实在微服务之前,很多的公司已经做过服务化的改造,并且取得了一定的成果,但是对于整体流程的标准化还有一定有差距。那么,什么是微服务呢?
准确的说,微服务是一种软件架构模式,将大型系统或者复杂的应用分割成多个服务的架构,服务之间互相协调、互相配合,为用户提供最终价值。每个服务都有独立的生命周期,可以单独的维护和部署,各个业务模块之间是松耦合的,比传统的应用程序更有效地利用计算资源,应用的扩展更加灵活,能够通过扩展组件来处理功能瓶颈问题。这样一来,开发人员只需要为额外的组件部署计算资源,而不需要部署一个完整的应用程序的全新迭代。
一个微服务的架构如图所示,单体应用被拆分成多个微小的服务:

也有人将微服务的开发比喻成搭积木,每个服务都是一个零件,使用这些不同的服务可以搭建出不同的形状。简单的说,微服务架构就是把一个大系统按业务功能分解成多个职责单一的小系统,并利用简单的方法使多个小系统相互协作,组合成一个大系统。
其实这里蕴含着自古以来的真理,就是分而治之,当一件事情大到不能处理的时候,就使用一定的切分方法,将其变成很多微小的类,然后分门别类的进行处理,以达到最好的效果,最终实现1+1>2的功效。
微服务的优点和缺点(或者说挑战)一样明显。
优点

  • 开发简单,每个服务完成独立的功能

  • 技术栈灵活,可以选择不同的语言完成不同的服务,发挥各种语言的最大优势

  • 服务独立无依赖,每个服务都可以单独部署,一个服务出现问题不会导致整个系统瘫痪

  • 独立按需扩展,以应对高并发以及大流量

  • 可用性高,当其中一个点出现问题时,能够及时切换,不影响业务正常运行

  • 复杂应用解耦为小而众的服务,拆分可以基于一定的原则,将耗时的应用解耦

  • 各服务精而专,也就是我们常说的专人干专事,映射到微服务中就是专服务干专事

  • 服务间通信通过API完成,选择轻量的API通信

    缺点(挑战)

  • 多服务运维难度,服务的增加意味着运维的困难,如何有效的管理是一个挑战

  • 系统部署依赖,当业务复杂是,系统之间的耦合关系高度耦合,如何高效部署是一个挑战

  • 服务间通信成本,包括网络延迟,接口不可用性等,保证服务的高可用性是一个挑战

  • 数据一致性,再各个服务间如何有效的共享数据,确保相应服务的数据需求一致性是一个挑战

  • 系统集成测试,拆分后,原本需要测试的内容成倍的增加,如何高效的降低测试成本是一个挑战

  • 重复工作,服务拆分之后,由于信息的不对称导致的重复性工作,如何有效抽象是一个挑战

  • 性能监控,原本只需要一个监控的部分,现在需要分开监控,如何快速定位问题是一个挑战

  • 沟通成本的成倍增加,服务拆分后,各个服务由单独的人来维护,如何高效的沟通是一个挑战

二、为什么微服务

从一般的平台遇到的问题说起,平台的问题包括:

  • 服务配置复杂。基础服务多,服务的资源配置复杂。传统方式管理服务复杂。
  • 服务之间调用复杂。检索服务、用户中心服务等,服务之间的调用复杂,依赖多。
  • 服务监控难度大。服务比较多,机器部署复杂,服务存活监控、业务是否正常监控尤为重要。
  • 服务化测试问题。服务依赖性比较大,测试一个小的功能,周边服务也需要启动。

那么微服务的架构有什么优势,大家为什么都怀着极高的热情来应对微服务呢。

1. 区别

首先看一下两者的区别,单体应用和分布式应用都有哪些优点和缺点呢,通过下面的表格来做一下分析和对比?

 

 

从上面的表格我们可以看到,分布式系统虽然有一些优势,但也存在一些问题。

  • 架构设计变得复杂(尤其是其中的分布式事务)。
  • 部署单个服务会比较快,但是如果一次部署需要多个服务,部署会变得复杂。
  • 系统的吞吐量会变大,但是响应时间会变长。
  • 运维复杂度会因为服务变多而变得很复杂。
  • 架构复杂导致学习曲线变大。
  • 测试和查错的复杂度增大。
  • 技术可以很多样,这会带来维护和运维的复杂度。
  • 管理分布式系统中的服务和调度变得困难和复杂。

也就是说,分布式系统架构的难点在于系统设计,以及管理和运维。

接下来我们就一起来看一下架构的演变过程。

2. 从单体应用说起

下图是我们非常熟悉的单体应用,或者说是非常传统的应用架构。
从图中可以看到,应用通过浏览器进行访问,当访问到订单服务的时候,分单服务提供相应的功能,然后去访问应用的数据层,数据层负责对数据的解析,这是一个极其典型的单体应用结构,这种结构所带来的问题显而易见,数据库存在单点,所有服务都耦合在一个应用中,当其中一个服务出现问题的时候,整个工程都需要重新发布,从而导致整体业务不能提供响应。这种结构在小项目中是没有什么问题的,而且操作起来非常灵活,但当业务量爆增的时候,就无法灵活应对了。

 

 

3. 第一步切分

为了应对单体应对无法满足业务增涨,需要对数据库进行进一步的切分,以提高扩展性,下图就是一个切分后的架构图。

业务之间通过进程间的服务进行相互调用,数据库之间没有耦合性,不会存在单点故障。前端只需要调用相应的服务,返回自身需要的数据,然后与用户进行交互。可以看到,这种方式比传统的单体应用已经前进了一步,但是数据库层面仍然存在着问题,根据数据量需要评估是否使用读写分离的设计,服务层面也增加了相应的复杂性。前端调用随着调用接口数量的增加也急需治理。

4. 服务化所带来的问题

随着服务的拆分,新的问题应运而生。客户端如何访问这些服务?这些服务的调用情况,切分是否合理,安全问题,如果受到攻击应该如何应对,是否可以使用限流或者降级的方式来及时解决。
应对这些问题,API网关是一个不错的解决方案。当有新的设备需要调用这些接口时,可以复用原有接口,不需要进行二次开发。接口的维护也会更有条理性,对于访问次数,安全等问题,都可以在这一层进行解决。

解决了应用前端访问的问题后,服务之间的相互调用也是一个问题,如果整个系统内部调用关系混乱,就会带来非常多的不必要的问题。所以约定好服务之间的通信方式是非常有必要的。不管是开源还是公司内部研发,都有非常多的解决方案。最简单的方式,是通过rpc的调用,传输json或者XML,双方定义好协议格式,通过报文的方式进行数据传输。
当多种服务需要互相调用的时候,服务的数量会急剧的增加。服务的治理就成为新的问题。不同的服务的版本问题。如果不能通过一个单独的注册地址,像书的目录一样来管理整个服务结构,服务的调用就侍显示非常混乱。
一般的分布式服务,都有一个注册中心,例如dubbo是基于zookeeper进行的二次开发,自身提供管理控制台,可以对服务进行注册和查找,Spring Cloud有Eureka,还有etcd,consul等可供选择。
经过上面的处理,整体上来看应用已经达到了一个非常好的状态,但是每个应用服务仍然存在着单点问题,当一个服务出现问题的时候,有可能导致连锁的反应,使用整个系统瘫痪。这时候需要除了监控告警之外的一种容错机制保障整体服务的可运行性。
通过网关层的反向代理来实现高可用是一个不错的解决方案,访问层无需要了解整个体系有多少应用提供,只需要关心服务是否能够提供服务,并且对必要的接口进行监测,当发现接口无法正常提供服务时,提供相应的告警机制,以微信、短信或者邮件的方式通知相关人及时进行处理。
随着服务的切分,业务的扩展,数据量的激增也是一个非常大的问题,如果采用传统的方案来应对,各种关系型数据库都有瓶颈,把运算量比较大,比较耗资源的运算,跨库统计查询的需求。
再下一步随着数据量的不断增涨,需要业务和统计分离。
统计一般都是比较耗时的应用,比如计算用户的留存情况,需要分析一周甚至是更长周期内的用户数据,如果使用在线的方式分析显然不太现实,所以,对于大数据量的分析和数据挖掘,需要从业务中抽取数据进行离线分析,然后将分析的结果进行展现。

5. 微服务的可扩展性

针对以上的分析,可以看到,微服务需要具备极强的可扩展性,这些扩展性包含以下几个方面:
• 性能可扩展:性能无法完全实现线性扩展,但要尽量使用具有并发性和异步性的组件。具备完成通知功能的工作队列要优于同步连接到数据库。
• 可用性可扩展:CAP理论表明,分布式系统无法同时提供一致性、可用性和分区容错性保证。许多大规模Web应用程序都为了可用性和分区容错性而牺牲了强一致性,而后者则有赖于最终一致性来保证。
• 维护可扩展:软件和服务器都需要维护。在使用平台的工具监控和更新应用程序时,要尽可能地自动化。
• 成本可扩展:总成本包括开发、维护和运营支出。在设计一个系统时,要在重用现有组件和完全新开发组件之间进行权衡。现有组件很少能完全满足需求,但修改现有组件的成本还是可能低于开发一个完全不同的方案。另外,使用符合行业标准的技术使组织更容易聘到专家,而发布独有的开源方案则可能帮助组织从社区中挖掘人才。

6. 微服务与SOA的区别

面向服务的架构(SOA)是一个组件模型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构建在各种各样的系统中的服务可以以一种统一和通用的方式进行交互。
都是做服务化,那么微服务与SOA的异同有哪些呢?
相同点:

  • 需要Registry,实现动态的服务注册发现机制;
  • 需要考虑分布式下面的事务一致性,CAP原则下,两段式提交不能保证性能,事务补偿机制需要考虑;
  • 同步调用还是异步消息传递,如何保证消息可靠性?SOA由ESB来集成所有的消息;
  • 都需要统一的Gateway来汇聚、编排接口,实现统一认证机制,对外提供APP使用的RESTful接口;
  • 同样的要关注如何再分布式下定位系统问题,如何做日志跟踪,就像我们电信领域做了十几年的信令跟踪的功能;

差异点:

  • 是持续集成、持续部署?对于CI、CD(持续集成、持续部署),这本身和敏捷、DevOps是交织在一起的,所以这更倾向于软件工程的领域而不是微服务技术本身;
  • 使用不同的通讯协议是不是区别?微服务的标杆通讯协议是RESTful,而传统的SOA一般是SOAP,不过目前来说采用轻量级的RPC框架Dubbo、Thrift、gRPC非常多,在Spring Cloud中也有Feign框架将标准RESTful转为代码的API这种仿RPC的行为,这些通讯协议不应该是区分微服务架构和SOA的核心差别;
  • 是流行的基于容器框架还是虚拟机为主?Docker和虚拟机还是物理机都是架构实现的一种方式,不是核心区别;

SOA和微服务的一个主要不同点就是自动化程度上的不同。大部分的SOA实现只达到服务级别的抽象,而微服务走的更远,它达到了对实现和运行环境的抽象级别。
而在一个规范的微服务中,每个微服务应该被构建成胖jar(fat Jar)其中内置了所有的依赖,然后作为一个单独的java进程存在。

三、常见的微服务组件

既然谈到了微服务架构,就说一下通用的微服务都包括哪些组件:

  • 服务注册

服务注册是一个记录当前可用的微服务实例的网络信息数据库,是服务发现机制的主要核心,服务注册表查询api、管理api,使用查询api获得可用服务的实例,使用管理api实现注册、注销。

  • 服务发现

服务调用方从服务注册中心找到自己需要调用的服务的地址。可以选择客户端服务发现,也可以选择服务端服务发现。

  • 负载均衡

服务提供方一般以多实例的形式提供服务,负载均衡功能能够让服务调用方连接到合适的服务节点。并且,节点选择的工作对服务调用方来说是透明的。可以选择服务端的负载均衡也可以选择客户端的负载均衡。

  • 服务网关

服务网关是服务调用的唯一入口,可以在这个组件是实现用户鉴权、动态路由、灰度发布、A/B测试、负载限流等功能。根据公司流量规模的大小网关可以是一个,也可以是多个。

  • 配置中心

将本地化的配置信息(properties, XML, yaml等)注册到配置中心,实现程序包在开发、测试、生产环境的无差别性,方便程序包的迁移。配置部分可以单独使用高可用的分布式配置中心,确保一个配置服务出现问题是,其它服务也能够提供配置服务。

  • API管理

以方便的形式编写及更新API文档,并以方便的形式供调用者查看和测试。通常需要加入版本控制的概念,以确保服务的不同版本在升级过程中都能够提供服务。

  • 集成框架

微服务组件都以职责单一的程序包对外提供服务,集成框架以配置的形式将所有微服务组件集成到统一的界面框架下,让用户能够在统一的界面中使用系统。

  • 分布式事务

对于重要的业务,需要通过分布式事务技术(TCC、高可用消息服务、最大努力通知)保证数据的一致性。根据业务的不同适当的需要牺牲一些数据的一致性要求,确保数据的最终一致性。

  • 调用链

记录完成一个业务逻辑时调用到的微服务,并将这种串行或并行的调用关系展示出来。在系统出错时,可以方便地找到出错点。同时统计各个服务的调用次数,确保比较热的服务能够分配更多的资源。

  • 支撑平台

系统微服务化后,系统变得更加碎片化,系统的部署、运维、监控等都比单体架构更加复杂,那么,就需要将大部分的工作自动化。现在,可以通过Docker等工具来中和这些微服务架构带来的弊端。 例如持续集成、蓝绿发布、健康检查、性能健康等等。可以这么说,如果没有合适的支撑平台或工具,就不要使用微服务架构。

posted @ 2020-06-15 13:02  skyme  阅读(1111)  评论(2编辑  收藏  举报