微服务概念

微服务的粒度小,服务之间耦合度低,由于每个微服务都由独立的小团队负责,因此它敏捷性更高,分布式服务最后都会向微服务架构演化,这是一种趋势, 不过服务微服务化后带来的挑战也是显而易见的,例如服务粒度小,数量大,后期运维将会比较困难。所以又有容器+微服务的出现。

这里就不细说容器与微服务了,着重理清微服务的一些概念、好处。

快速开发与迭代

微服务,顾名思义,就是微小的一个服务。与传统单机架构不同,微服务的功能比较单一,专做一件事情,而单机架构需要把所有事情全部完成,可想而知,如果单机架构的应用出现了问题,那么整个项目都会下线,然后不断排查并检修,这个过程明显影响了用户体验,不应该只是因为单机架构的某一个小部分出了问题就需要停掉整个应用。因此,为了解决这个问题,微服务应运而生。微服务将原来的单机架构应用进行拆分,拆分成多个粒度更小的微服务,进行分别开发并部署,服务之间显然是RPC调用。这样做,就不会因为某种小原因而把整个应用都停掉,哪个服务出了问题,只需要将哪个服务停掉就行了。另外,进行服务拆分时,不同的服务还可以是不同编程语言进行开发,这样可以更具灵活性。

自动化部署

自动化部署的目标就是持续交付,对于微服务来说,多个服务的自动化是必不可少的。通过自动化编译,自动化测试,自动化集成和自动化部署,可以大大的减轻开发团队和运维团队的任务,提升开发效率。

独立部署

原来的单机架构只能一次性部署,而多个微服务基本上都是单独部署在不同的主机上。这样做可以减少粒度,哪个服务更新就只需要部署对应的服务即可,而不必更新所有微服务。

错误隔离

在传统单机架构下一旦应用发生故障,整个服务的可用性都会受到影响,因为所有的模块都耦合在一个大的单体进程里,这个进程的所有程序都共享进程内的资源。所以,发生故障、错误的位置很难确定,应用也很难从故障种恢复过来。所以,我们需要将单体应用拆分成功能独立、相互隔离的微服务应用,这些微服务通过定义良好的协议进行通信。这样互相隔离的微服务之间,错误、故障也被隔离起来。

负载均衡

可以将相同的服务部署到多台主机上,实现负载均衡

出错处理

在传统单机架构的应用里,调用函数时,错误只会是自己内部的错误,包括入参错误、自身设计的一些缺陷等。但是在微服务里,就显得不同了。一个微服务需要使用到另一个微服务时,中间需要RPC调用,这样出错的原因不仅是入参、自身的设计缺陷,还可能是网络延时、另一个微服务挂掉等情况。

链路追踪

在大型系统的微服务化构建中,一个系统被拆分成了许多模块。这些模块负责不同的功能,组合成系统,最终可以提供丰富的功能。在这种架构中,一次请求往往需要涉及到多个服务。互联网应用构建在不同的软件模块集上,这些软件模块,有可能是由不同的团队开发、可能使用不同的编程语言来实现、有可能布在了几千台服务器,横跨多个不同的数据中心。

微服务架构是通过业务来划分服务的,使用 REST 调用。对外暴露的一个接口,可能需要很多个服务协同才能完成这个接口功能,如果链路上任何一个服务出现问题或者网络超时,都会形成导致接口调用失败。随着业务的不断扩张,服务之间互相调用会越来越复杂。

所以,为了更好地掌握一次请求到底经历了哪些服务,需要进行链路追踪

服务发现

现代网络程序中主要分为前端和后端两部分,当前端的程序访问后端的时候,必须要知道后端服务的网络地址(即IP地址或者端口号)。以前每一个服务都被固定的部署到某一台机器上,所以说每个服务的端口号和IP地址都是固定的,可以通过配置文件进行修改。但是,在微服务体系中,由于服务的实例有可能发送失败重启、自动扩容、升级等情况,导致这些服务实例对应的网络地址是在动态变化的。如何精准、准确地使前端能够发现后端是一个难以解决的问题。

在微服务体系结构中,所谓的服务发现就是用户可以通过服务的名字,在注册中心找到可以提供正常服务的实例的网络地址(即IP地址和端口号)。这种根据服务名字发现服务的可用地址的机制就叫做服务发现。

服务发现的过程

  1. 服务提供者将实例信息注册到服务注册中心
  2. 服务调用者根据服务标识,从注册中心查询服务,获取包含网络地址的服务实例列表
  3. 与服务实现通信。

动态扩容

某个时间段里,出现一个热点事件,导致某一个服务被频繁调用,那么为了应对这个大流量的需求,显然需要将这个服务动态扩容:在高负载的时候自动扩容,低负载的时候自动缩容。

熔断、降级

熔断主要针对具体某个接口出现问题时,对这个接口采用的临时方案,它站在接口或者服务的层面来考虑问题。防止因为某个接口出现问题,导致问题蔓延,直至整个系统不可用。例如:某个接口的提供方宕机,导致接口调用方频繁超时,调用方的上游受到影响,进而也会超时,最终整个链路都会变得超时,如果超时时间很长的话,会导致客户端系统资源浪费(一些池化的资源,长时间得不到释放)。此时可以在接口的调用方进行对该接口的熔断,具体做法,可以直接返回一个默认值,防止频繁的调用超时。同时通过不断的对该接口进行可用性探测,当检测到该接口可用时,对熔断逻辑进行撤销

降级是系统应对突发流量的解决方案,它站在系统层面来考虑问题,目的是为了保证整个系统的可用性。因为受系统自身资源的限制,可以处理的流量是是有限的,不能对突发流量进行完全处理,那么此时就应该对流量进行有选择的处理,让系统只处理优先级高的流量,优先级低的流量不进行处理,直接返回默认值(或者其他处理策略),也就是对部分低优先级流量进行舍弃,例如,双十一期间,很多电商网站的评论,收藏功能变得不可用,这里就是系统为了保证网站核心功能可用,对评论和收藏功能进行了降级,将系统资源用在核心业务上,正所谓"好钢用在刀刃上"。

但是,这种方案为什么叫做"降级"呢?好像没有体现出"降级"的语义。其实降级,是站在整个系统维度来说的,举例来说:系统正常情况下,可以对外提供10个接口服务,在降级的情况下,只能对外提供5个接口服务,那么此时的系统,就是有"瑕疵"的系统,能够完整提供服务的系统,我们给系统打5星,现在系统中一部分功能不可用了,那么此时系统只能打3星,系统的"级别"有所下降了。

DDD领域驱动设计