微服务microservice

  微服务于10 年前出现,这个词应该首先由亚马逊提出,也就是著名“一个披萨”,开发一个微服务的人员正好够吃一个披萨 ,然后许多其他硅谷公司Netflix、谷歌和eBay 在大致相同的时间各自独立或多或少实现相同架构模式。

  微服务是指提供单个业务功能的服务,遵循SOLID原则的单一职责,从技术角度看就是一种小而独立的处理进程,能够自行单独启动或销毁,拥有自己独立的数据库,由独立团队开发,这个团队大小以吃一两个披萨喂饱为判断依据。

  微服务目的并非为了解决技术问题,它是为了解决组织问题:团队组织大小以业务子域或DDD有界上下文划分,或以产品边界划分,微服务划分也建议以团队认知负担能力划分,见康威定律团队拓扑

  单体架构Monolith非常适合一个小型的专门团队,在大型单体应用中执行标准非常困难:有足够多的功能时,团队每个人的认知负担增加,他们每个人已经就很难区分什么功能是什么,这就可能开始影响稳定性。 微服务(或仅仅是领域服务)不会神奇地使一切变得更好。 但如果做得好的话,它们至少可以让我们更容易适应变化。

  下面从代码层面解释一下微服务:假设您正在为一家银行或金融科技初创公司工作。您为用户提供了开设一个新的银行帐户功能,在Java代码中,这将导致一个看起来像简化的控制器类,如下所示。

@Controller
class BankController {

    @PostMapping("/users/register")
    public void register(RegistrationForm form) {
        validate(form);
        riskCheck(form);
        openBankAccount(form);
        // etc..
    }
}
您将要:

  1. 验证注册表。
  2. 对用户的地址进行风险检查,以确定是否要给他一个银行帐户。
  3. 开立银行账户
BankController类将与所有其他源代码一起打包到一个bank.jar或bank.war文件中进行部署,包含银行运行所需的所有代码。(,.jar / .war文件最初的大小为1-100MB)。然后,在服务器上,您只需运行.jar文件-这就是部署Java应用程序所需要做的全部工作。

  从本质上讲,Java单体没有错。好处:

  1. 让许多不同的程序员/团队/顾问共享代码...
  2. 在在相同的整体代码库上工作...
  3. 几年了...
  然而,当小bank.jar文件变成了一个几百兆或千兆字节大小时,每个人都开始担心部署。

  企业架构历经几十年的SOA轰轰烈烈建设以后,发现由于强调服务的共享和重用导致巨大臃肿的服务,这就是单体架构(monolith,又称为巨石、整体架构)的由来,其特点是如同炒面菜与面条混在一起,或如意大利面都搅拌在一起,不分彼此,业务逻辑与技术混合在一起,而技术发展很快,这样的系统非常难以维护,因为掌握一个大服务对于新程序员不是一件简单的事情,从容导致交付延迟,软件开发效率降低,国内最近几年推崇的中台概念其实是单体SOA的翻版,可以说是重走老路, 见:中台是一个营销概念!

  微服务的设计核心是:解耦高于复用,微服务架构是对高耦合的单体架构进行分解,根据DDD子域或有界上下文进行切分,开发团队因此也分成不同的微服务团队,团队之间不需要频繁的沟通开会,提高开发效率,微服务因为小而美,新程序员理解和维护起来非常方便,不会发生改一动百的惊心动魄的问题,更不会导致年底删库的事件发生。  

  从软件架构角度看:一个复杂软件架构是由很多这样小而独立运行(有自己的端口)微服务组成,这些独立处理组件之间通讯是通过与语言无关的API进行,简单协议有同步性质的RMI/RPC和 RESTful Web Services,异步的消息推送和Reactive方式。

  这些模块化的方式能够使得公司将项目分解分散到多个开发团队,跨不同业务部门,提供非常充分的灵活性,帮助提高项目的生命周期,加快项目开发完成效率。

  每个微服务组件都有自己分配的存储 内存和CPU资源,这就使得硬件利用更加易于优化和跟踪,特别是在基于云的Pass环境,开发团队可以使用他们喜欢的技术,任何语言都可以,只要确保微服务之间是可交互的,能够最终组合起最后的应用。

  当管理复杂性会因为采取微服务架构而降低,通常更新其中一个微服务组件不会引起连锁反应,因为微服务之间是松耦合的。

  目前使用微服务的企业有:Netflix Twitter Amazon Web Services (AWS), Google, eBay等。

  因为有很多应用和服务部署在基于云主机的环境中,微服务架构将会严重依赖容器技术,容器隔离了微服务处理过程,将一个应用切分为一个个小的实例,这些容器中的小实例有自己的端口和虚拟化环境。

  广泛使用的容器技术是Docker, 一种基于Linux的开源实现,由很多软件公司支持如 Canonical, Red Hat,和Parallels. PaaS服务支持包括Google App Engine, Red Hat Open Shift,和VMware的 Cloud Foundry,。

  微服务架构不只是传统服务变微变小。微服务两个显著特点是:微服务本身是无状态的;微服务之间很少可变共享。可以设想一下,如果微服务之间可以共享,那么带来两个问题:微服务团队之间需要合作,因为共享的是一个统一数据库,如果这种共享没有带来沟通成本,没有破坏一个团队就能搞定的宗旨,那么这种共享数据库也是可以考虑,但是这种情况很少,大部分团队因为共享问题破坏了独立性;再者,微服务如果使用Docker分别打包在一个容器中,这些容器可能是跨不同基础设施部署,部署方式很灵活,是一种cloud native应用,而共享数据库属于底层基础设施,显然提高了部署难点。

  另外,传统服务之间通讯无论是RPC/RMI或是Http/RESTful都是同步的,而微服务之间通信最好是异步的或reactive的,也就是非同步的。根据FLP不可能原理,网络默认是不可靠的,RPC在一旦发生网络堵塞会连环爆炸,事后监控并不能根本解决这个问题,需要从CAP定理角度进行平衡设计,引入事件驱动或Pub/Sub消息方式能在提高网络容错性的同时,保证数据最终一致性,柔性事务是微服务环境的主要选择。

  传统服务变成铁板一块经常是因为事务处理要求,某个服务方法的代码很多,需要塞在同一个事务边界内,虽然这带来了高一致性的,但是扩展性比较差,因为同一个事务边界内的动作无法分离到几个微服务中,因此,使用微服务必须积极拥抱最终一致性,对分布式系统以及CAP定理有一定理解。当然,这些都是必须有多个微服务调用的情况下才需要考虑,由于微服务粒度小且专一,可以通过组合替代共享继承的思路,容忍代码有一定的重复性。

  一个微服务架构需要具备以下条件:

  • 基础监视 测量和健康检查
  • 分布式日志 跟踪
  • 针对每个服务,不只是隔离代码,还需要在构建+测试+打包+提交整个环节隔离。
  • 能清晰定义每个服务的上下游、编译时间和运行依赖。
  • 掌握如何构建、暴露和维护好的API和合约。
  • 需要尊重b/w和f/w兼容性,即使你可能不同时是你生产的服务的消费者。
  • 好的单元测试和更具有可读性
  • 注意微服务与模块和库包区别,以及分布式整体型monolith, 协同版本发布,数据库驱动继承的区别。
  • 知道基础设施的自动化
  • 需要基于CI/CD持续集成/持续递交的基础设施 

  服务划分:

  • 根据业务能力界定服务的范围
  • 根据领域驱动设计中子域的概念界定服务的范围

  通讯模式:

  • 使用基于RPC的同步通讯方式
  • 使用异步消息进行服务间通讯

   外部API:

  • API 网关(API gateway) - 为每一类客户端提供一个访问服务的独特接口
  • 服务前端的后端(Backend for front-end) - 为每一类客户端都提供一个独立的 API 网关

   数据管理:

  • 每个服务都拥有它私有的数据库特接口
  • 服务之间共享同一个数据库
  • 使用事件来维护服务间的数据一致性 事件溯源/CQRS

   运维监控:

  • 服务的发现:通过第三方模块来进行服务实例信息到服务注册表的注册过程
  • 分布式追踪(Distributed tracing)new - 在服务代码中针对每一个外部访问,都分配一个唯一的服务标识符,并在跨服务访问时传递这个标识符以供追踪分布式引发
  • 断路器(Circuit Breaker) - 当远端服务返回的故障率超过一定的阀值时,客户端代理(比如 API 网关)对远程服务的调用将立刻返回失败的信息

    维护一个整体Monolith单体架构系统的样子:

    微服务模式:

 

微服务理论与实践

《复杂软件设计之道:领域驱动设计全面解析与实战》(本书介绍了微服务中设计模式:有界上下文,异步消息传递,基于编排的sagas,事件源,CQRS等)

用事件风暴分解单体设计微服务 - capital

最全面微服务教程:SpringBoot + DDD + Apache Kafka实现最终一致性的教程与源码 - itnext

微服务入门所需了解的一切

Docker微容器+微服务将颠覆传统的软件架构

分布式事务可能是个伪概念

微服务架构简介

DDD(领域驱动设计)是微服务体系结构的核心和最重要的基础

如何构建基于DDD领域驱动的微服务?

关于有界上下文和微服务的关系以及它们的划分粒度 - Alberto Brandolini

微服务实现工具概述

为什么分布式微服务很难?

如何设计最佳的微服务架构

实现微服务的唯一方法是:在系统全局和本地两个级别平衡每个服务的复杂性

微服务的最终一致性与事件流

如何将单体分解成微服务?

业务流程的新实现:微服务和事件编排

两个领域事件驱动的开源项目介绍

如何设计实现真正的响应式微服务系统?

微服务分布式事务Saga模式简介

使用SpringCloud将单体迁移到微服务

LMAX微服务级别的分布式事务实现

不使用DDD的后果:为什么我们停止了向微服务的迁移?

Spring Boot实现DDD的货运Cargo微服务案例源码

Spring Boot微服务中的十二因子方法论(12Factor) - Baeldung

可以促进微服务设计的DDD事件风暴建模技巧 - Nick Tune

向领域驱动设计前进: 如何使用DDD实现从单体到微服务迁移打造业务平台或中台?

如何微服务在实现分布式事务的变通?

DDD(领域驱动设计)是微服务体系结构的核心和最重要的基础

Redis如何简化微服务设计模式

在使用Kafka+微服务发送聚合的领域事件时如何在错误重试时保证顺序?

在微服务架构中实施分布式事务锁的几个方案比较

微服务架构中的分布式事务全面详解

 

更多#微服务专题

相关专题

分布式事务 #Spring Boot #Springcloud

#无服务器Serverless #Kubernetes    #Docker #服务网格 

#Reactive编程 #事件和EventSourcing

#事务机制 #Saga模式

#NoSQL #MongoDB

#REST #SpringBatch

#bigData #云计算

#缓存 #CQRS

#分布式系统 #CQRS

更多

云计算

云原生

技术架构

分布式系统

分布式架构

分布式CAP定理

分布式共识一致性教程

NoSQL数据库

中台数据工程教程

软件弹性工程与设计

分布式事务

分布式事务教程