微服务

参考资料

https://www.redhat.com/zh/topics/microservices/what-are-microservices

https://cloud.google.com/learn/what-is-microservices-architecture?hl=zh-cn

https://aws.amazon.com/cn/microservices/

https://www.ruanyifeng.com/blog/2021/05/scaling-problem.html

微服务是什么

微服务(microservice)是一种软件架构,正得到越来越多的关注。

但是,它到底是什么意思?什么样的架构可以叫做微服务?

网上的文章虽然很多,但是都太复杂,初学者不容易看懂。我认为,这个概念其实非常简单,可以很通俗地说明白。

img

1.单体软件

要理解微服务,首先需要理解软件架构的演变。

早期的软件,所有功能都写在一起,这称为单体架构(monolithic software)。

整个软件就是单一的整体,彷佛一体化的机器。

可以想到,软件的功能越多,单体架构就会越复杂,很多缺点也随之暴露出来。

(1)所有功能耦合在一起,互相影响,最终难以管理。

(2)哪怕只修改一行代码,整个软件就要重新构建和部署,成本非常高。

(3)因为软件做成了一个整体,不可能每个功能单独开发和测试,只能整体开发和测试,导致必须采用瀑布式开发模型。

img

2.软件开发难处

软件开发有一个难题,叫做"扩展"(scaling),即怎样服务更多的用户。 你有10000个并发用户,跟你有10个并发用户,这是完全不同的概念,哪怕功能完全相同,背后的实现是完全不一样的。

并发用户数上升一个数量级,软件就必须重构,大量问题随之产生。

img

大项目的技术难度高,管理难度更高,而且大团队的生产率往往很低,行动缓慢。

一个典型的大型软件项目,开发过程通常是下面这样。

最开始的时候,它是一个小项目,开发人员就是两三个人,甚至可能只有一个人。

img

产品比较简单,功能很有限。

第一版发布后,拿给客户使用,反响不错。客户要求的新功能,能够很快开发出来,Bug 修补也很快,因为早期客户往往可以与开发人员直接沟通,快速反馈。

公司于是决定投入更多人员,开发这个项目。团队慢慢变大了,软件开始变得复杂,开发速度逐渐变慢了,2.0 版花费的时间比预期要长一点。Bug 的修复难度开始增加。总之,新功能的开发日程变久了。

公司的自然反应是进一步扩充团队。

但是更多的新成员其实会降低其他人的生产率,一个普遍现象是团队规模越大,每个人的平均生产率越低。

img

几年以后,代码逐渐老化,复杂性不断增加,项目开始停滞不前。某些极端的情况下,软件的维护成本变得非常高昂,并且几乎不可能进行更改。

最终,这个项目成为技术债务,等待被新项目替换。

3.为什么大项目的开发效率低?

大项目就像一头大象,让人望而生畏。可是一旦需要奔跑,大象就会步履蹒跚,被猎犬远远甩在后头。它快不起来的原因有两个。

代码复杂度

随着代码量的增长,单个开发者想要理解整个代码库,变得越来越困难。如果团队超过五个人,每个人负责一个功能,那么单个人几乎不可能追踪系统的所有工作进度。

当你中途加入团队,整个项目是一个紧密耦合的大型系统,你又不理解系统的每一个工作细节。这时,你就不太敢修改以前的代码,因为不知道随之而来的全部影响。

img

你不真正理解系统,也就不会感到自己是代码的主人。你会很犹豫要不要重构,过时的代码开始累积,技术债务就这样出现了。长此以往,开发变得越来越不愉快和令人无法满意,最终导致人才流失。后面接手的新人,更难于重构那些遗留下来的代码。

团队原因

随着团队成员的增加,交流成本开始指数式上升。如果整个团队有 n 个程序员,为了了解其他人的工作,你需要跟 n - 1 个人逐一交流(口头或者书面),那么整个团队的交流路径总数就是 n * (n - 1) / 2。

这意味着,交流成本的增长速度是人员增长速度的平方,团队人数越多,协同的难度就越大。

img

大团队保持扁平化管理,也会越来越困难,必须拆分成较小的群体。这时,对等的交流会被自上而下的交流所取代。

团队成员会感觉,自己从平等的利益相关者,转变为普通的工作人员,工作动机受到了影响,责任感和主人翁意识都会淡漠。

解决方法:代码解耦

大项目的开发效率不高,把这个问题归咎于程序员的技术水平低和管理不善,都是没用的。 根本原因是软件规模的增长,必然使得代码和团队变得笨重。 除非很早就认识到问题的根据,采取缓解对策,否则前面描述的情况,迟早都会出现。

解决这个问题,要从代码和团队两方面着手。

代码层面的解决方法是,将软件解耦,拆分成组件或者模块,防止各个部分紧密地耦合在一起。

每个组件和模块,都可以独立开发,通过公开的接口被其它部分调用。

img

这样的话,就大大减轻了开发者的负担,只需要负责自己的代码即可,不需要关心其他部分的实现。每个部分都可以单独重构,不担心影响到其他部分。

解决方法:团队解耦

除了代码解耦,团队层面也需要解耦,要把人员分开。

这可以参考互联网的架构。互联网是迄今为止最成功的大型软件解耦实例,它之所以能够扩展,是因为它由一个个独立的节点组成。为了防止节点之间互相依赖,各个节点都遵循以下规则。

  • 遵守公开的通信协议。
  • 不需要了解其它节点的内部实现,就可以与之通信。
  • 节点之间不直接共享状态,只通过通信交换数据。
  • 每个节点单独开发和部署。

大团队也应该遵循类似的原则,进行解耦。

  • 每个子团队都可以独立运作,不依赖外部人员。
  • 子团队内部的运作,不需要被外部知道。
  • 子团队之间的协调,应该按照公开的协议和规则,最好能够自动完成,避免私下协商。

4.理解SOA

于超老师第一次接触SOA,也就是在上海的外企,以Java、redhat的开发技术栈。

为了解决上面这些问题,很早就有人提出来,必须打破代码的耦合,拆分单体架构,将软件拆分成一个个独立的功能单元。

大概在20多年前,随着互联网的出现,功能单元可以用远程"服务"的形式提供,就诞生出了"面向服务架构"(service-oriented architecture,简称 SOA)。

img

通俗理解SOA

通俗理解SOA(Service-Oriented Architecture,面向服务的架构)可以用以下方式描述:

想象一家大型超市,超市中有各种商品,如食品、衣物、家居用品等。

每个商品都是一个独立的服务,可以通过它提供的功能来满足消费者的需求。

消费者可以根据自己的需求选择不同的商品进行购买。

在SOA中,类似超市中的商品,软件系统中的各个功能也被拆分成独立的服务。每个服务都具有自己的功能和接口,可以独立提供特定的业务功能。

这些服务可以通过网络进行通信,以满足不同应用之间的需求。

就像超市中的商品可以组合成购物清单,通过选购不同的商品来满足不同消费者的需求一样,在SOA中,服务也可以通过组合来满足复杂的业务需求。

通过将不同的服务组合起来,系统可以实现更高级的功能和流程。

SOA强调松耦合和可重用性。通过将功能拆分成独立的服务,可以减少系统间的耦合,使得系统更加灵活和可扩展。

此外,由于每个服务都是独立的,可以被其他应用程序或系统重复使用,提高了开发效率和系统的可维护性。

总之,SOA是一种将软件系统拆分成独立服务的架构思想,类似于超市中的商品,每个服务都是独立的、可组合的,以满足不同应用之间的需求。这种架构提供了灵活性、可扩展性和可重用性,有助于构建复杂的应用系统。

image-20230514123039257


image-20230514123147058

所谓服务(service)

就是在后台不间断运行、提供某种功能的一个程序。最常见的服务就是 Web 服务,通过80端口向外界提供网页访问。

"面向服务架构"就是把一个大型的单体程序,拆分成一个个独立服务,也就是较小的程序。

每个服务都是一个独立的功能单元,承担不同的功能,服务之间通过通信协议连在一起。

img

这种架构有很多优点。

(1)每种服务功能单一,相当于一个小型软件,便于开发和测试。

(2)各个服务独立运行,简化了架构,提高了可靠性。

(3)鼓励和支持代码重用,同一个服务可以用于多种目的。

(4)不同服务可以单独开发和部署,便于升级。

(5)扩展性好,可以容易地加机器、加功能,承受高负载。

(6)不容易出现单点故障。即使一个服务失败了,不会影响到其他服务。

跟单体架构不一样,面向服务架构是语言不敏感的,不同服务可以使用不同的语言和工具开发,可能需要部署在不同的系统和环境。

这意味着,面向服务架构默认运行在不同服务器上,每台服务器提供一种服务,多台服务器共同组成一个完整的网络应用。

5.微服务(使用容器完成SOA架构)

2014年,Docker出现了,彻底改变了软件开发的面貌。它让程序运行在容器中,每个容器可以分别设定运行环境,并且只占用很少的系统资源。

img

显而易见,可以用容器来实现"面向服务架构",每个服务不再占用一台服务器,而是占用一个容器。

这样就不需要多台服务器了,最简单的情况下,本机运行多个容器,只用一台服务器就实现了面向服务架构,这在以前是做不到的。这种实现方式就叫做微服务。

img

简单说,微服务就是采用容器技术的面向服务架构。它依然使用"服务"作为功能单元,但是变成了轻量级实现,不需要新增服务器,只需要新建容器(一个进程),所以才叫做"微服务"。

一个微服务就是一个独立进程,这个进程可以运行在本机,也可以运行在别的服务器,或者在云端(比如云服务和云函数 FaaS)。

它的特点与面向服务架构是一样的,但因为更轻量级,所以功能的解耦和服务化可以做得更彻底。而且,它可以标准化,同样的容器不管在哪里运行,结果都是一样的,所以市场上有很多 SaaS 产品,提供标准化的微服务。

正是由于微服务这些突出的优点,这几年才会变得如此流行。

它和容器技术、云服务一起,一定会在未来的软件开发中,扮演越来越重要的角色。

微服务架构演进

单体网约车APP架构

image-20230514125838508

一套git代码仓库,包含所有功能。

这种单体应用比较适合于小项目,优点是:

  • 开发简单直接,集中式管理
  • 基本不会重复开发
  • 功能都在本地,没有分布式的管理开销和调用开销

当然它的缺点也十分明显,特别对于互联网公司来说:

  • 开发效率低:所有的开发在一个项目改代码,递交代码相互等待,代码冲突不断
  • 代码维护难:代码功能耦合在一起,新人不知道何从下手
  • 部署不灵活:构建时间长,任何小修改必须重新构建整个项目,这个过程往往很长
  • 稳定性不高:一个微不足道的小问题,可以导致整个应用挂掉
  • 扩展性不够:无法满足高并发情况下的业务需求

微服务网约车架构

微服务架构的设计思路不是开发一个巨大的单体式应用,而是将应用分解为小的、互相连接的微服务。

一个微服务完成某个特定功能,比如乘客管理和下单管理等。

每个微服务都有自己的业务逻辑和适配器。一些微服务还会提供API接口给其他微服务和应用客户端使用。

比如,前面描述的系统可被分解为:

image-20230514130045151

此架构,使用pod、容器去部署应用,也方便单个服务的更新、版本控制、推进CICD的优化。

每个业务逻辑都被分解为一个微服务,微服务之间通过REST API通信。

一些微服务也会向终端用户或客户端开发API接口。

但通常情况下,这些客户端并不能直接访问后台微服务,而是通过API Gateway来传递请求。

API Gateway一般负责服务路由、负载均衡、缓存、访问控制和鉴权等任务。

微服务架构优点

  • 解决了复杂性问题。它将单体应用分解为一组服务。虽然功能总量不变,但应用程序已被分解为可管理的模块或服务
  • 体系结构使得每个服务都可以由专注于此服务的团队独立开发。只要符合服务API契约,开发人员可以自由选择开发技术。这就意味着开发人员可以采用新技术编写或重构服务,由于服务相对较小,所以这并不会对整体应用造成太大影响
  • 微服务架构可以使每个微服务独立部署。这些更改可以在测试通过后立即部署。所以微服务架构也使得CI/CD成为可能

微服务架构缺点

微服务的一个主要缺点是微服务的分布式特点带来的复杂性。

开发人员需要基于RPC或者消息实现微服务之间的调用和通信,而这就使得服务之间的发现、服务调用链的跟踪和质量问题变得的相当棘手。

微服务的一大挑战是跨多个服务的更改

  • 比如在传统单体应用中,若有A、B、C三个服务需要更改,A依赖B,B依赖C。我们只需更改相应的模块,然后一次性部署即可。

  • 在微服务架构中,我们需要仔细规划和协调每个服务的变更部署。我们需要先更新C,然后更新B,最后更新A。

部署基于微服务的应用也要复杂得多

  • 单体应用可以简单的部署在一组相同的服务器上,然后前端使用负载均衡即可。
  • 微服务由不同的大量服务构成。每种服务可能拥有自己的配置、应用实例数量以及基础服务地址。这里就需要不同的配置、部署、扩展和监控组件。此外,我们还需要服务发现机制,以便服务可以发现与其通信的其他服务的地址

学微服务是学什么

  1. API Gateway(API 网关): API Gateway是微服务架构中的入口点,负责处理所有的外部请求。它提供统一的API接口,将客户端的请求路由到相应的微服务。API Gateway可以处理请求的认证、授权、数据转换、请求转发等功能,同时还可以实施许多与安全相关的策略,如访问控制、限流、监控等。
  2. 服务发现: 在微服务架构中,由于服务的数量较多且动态变化,服务发现变得关键。服务发现机制允许服务注册自身,并向服务注册中心报告其位置和可用性。客户端或其他服务可以通过服务注册中心查询可用的服务,并进行适当的负载均衡和路由决策,以调用所需的服务。
  3. 服务容错: 服务容错是指在微服务架构中处理服务故障和异常情况的能力。由于服务之间的通信是通过网络进行的,可能会出现网络延迟、故障、服务不可用等情况。服务容错机制包括断路器(Circuit Breaker)、超时机制、重试机制等,用于处理这些异常情况,保证系统的可靠性和稳定性。
  4. 服务部署: 在微服务架构中,每个微服务都有独立的部署单元,可以独立地进行开发、测试和部署。服务部署涉及将微服务的代码、配置和依赖项部署到相应的运行环境中。部署可以使用容器技术(如Docker)进行虚拟化,也可以使用自动化部署工具(如Kubernetes)来简化和管理部署过程。
  5. 数据调用: 微服务架构中的微服务之间需要进行数据交互和通信。数据调用包括通过网络调用其他服务的API,获取所需的数据和执行相应的操作。常见的数据调用方式包括使用HTTP/REST接口、消息队列、RPC(Remote Procedure Call)等。这些调用机制允许微服务之间进行数据传递和协作。

这些概念是微服务架构中常用的关键要素,它们共同构成了一个弹性、可伸缩、可靠的分布式系统。通过合理地使用API Gateway、服务发现、服务容错、服务部署和数据调用机制,可以实现微服务架构的优势,如灵活性、独立性、可扩展性和可维护性。

微服务框架

如何应对上述挑战,出现了如下微服务领域的框架

  • Spring Cloud(各个微服务基于Spring Boot实现)
  • Dubbo
  • Service Mesh
    • Linkerd
    • Envoy
    • Conduit
    • Istio

image-20230514130837332

学习计划(重点)

学习微服务时,Spring Cloud和Kubernetes(通常简称为k8s)是两个常用的技术栈,用于构建和管理微服务架构。下面是它们之间的一些对比:

  1. 架构层级:
    • Spring Cloud:Spring Cloud是一个基于Java的开发框架,提供了一套用于构建微服务的工具和库。它在应用程序的代码层级上提供了解决方案,包括服务发现、负载均衡、断路器、配置管理等。
    • Kubernetes:Kubernetes是一个容器编排平台,用于自动化部署、扩展和管理容器化应用程序。它在基础设施层级上提供了解决方案,可以管理和编排容器、服务发现、负载均衡、自动伸缩等。
  2. 部署和管理:
    • Spring Cloud:Spring Cloud可以在各种云平台或自己的服务器上部署。它提供了一套开发框架和工具,帮助开发人员快速构建和管理微服务应用程序,但它对底层的基础设施并不直接负责。
    • Kubernetes:Kubernetes是一个跨云平台的容器编排系统,用于自动化部署、管理和扩展容器化应用程序。它可以在各种云平台上运行,并提供了强大的管理功能,如自动伸缩、故障恢复、负载均衡等。
  3. 功能覆盖:
    • Spring Cloud:Spring Cloud提供了一系列的组件和库,涵盖了微服务架构中常见的功能,如服务注册与发现(Eureka、Consul)、负载均衡(Ribbon)、服务调用(Feign)、断路器(Hystrix)、配置管理(Spring Cloud Config)等。
    • Kubernetes:Kubernetes提供了一套强大的功能,包括容器编排、服务发现与负载均衡、自动伸缩、故障恢复、存储管理等。它可以管理和编排多个容器化应用程序,并提供弹性和高可用性的部署。
  4. 生态系统和语言支持:
    • Spring Cloud:Spring Cloud是基于Java生态系统构建的,因此它与Spring框架紧密集成,并与许多其他Java库和工具协作。它提供了丰富的Java库和工具,用于构建和管理微服务应用程序。
    • Kubernetes:Kubernetes是一个通用的容器编排平台,可以与各种编程语言和容器技术一起使用。它支持多种容器运行时(如Docker),并且可以与不同的语言和框架进行集成。
  5. 复杂度和学习曲线:
    • Spring Cloud:Spring Cloud相对于Kubernetes来说,学习曲线较为平缓。它更加关注于微服务应用程序的开发和管理,并提供了一套简化的解决方案。如果您已经熟悉Spring框架,上手Spring Cloud会相对容易。
    • Kubernetes:Kubernetes作为一个容器编排平台,拥有更复杂的架构和概念,学习曲线可能相对陡峭。它需要理解容器概念、Kubernetes资源对象、Pod、Deployment、Service等,并且需要配置和管理基础设施。

总结:

  • Spring Cloud和Kubernetes是两个不同的技术栈,用于构建和管理微服务架构。
  • Spring Cloud更加注重开发者友好性和快速开发微服务应用程序,而Kubernetes更注重跨平台的容器编排和基础设施管理能力。
  • 在选择使用哪种技术栈时,可以根据具体的需求、团队的技术栈偏好和现有的基础设施来进行权衡。
  • 有些情况下,两者也可以结合使用,例如使用Spring Cloud开发微服务应用程序,并使用Kubernetes进行容器编排和部署管理。

了解Spring Cloud

https://spring.io

https://spring.io/projects

为什么java占市场开发语言比例第一,明显的,大而全,任何场景,任何模式,都有可选的成熟方案。

与Dubbo对比

做一个简单的功能对比:

核心要素 Dubbo Spring Cloud
服务注册中心 Zookeeper Spring Cloud Netflix Eureka
服务调用方式 RPC REST API
服务监控 Dubbo-monitor Spring Boot Admin
断路器 不完善 Spring Cloud Netflix Hystrix
服务网关 Spring Cloud Netflix Zuul
分布式配置 Spring Cloud Config
服务跟踪 Spring Cloud Sleuth
消息总线 Spring Cloud Bus
数据流 Spring Cloud Stream
批量任务 Spring Cloud Task
…… …… ……

从上图可以看出其实Dubbo的功能只是Spring Cloud体系的一部分。

这样对比是不够公平的,首先DubboSOA时代的产物,它的关注点主要在于服务的调用,流量分发、流量监控和熔断。

Spring Cloud诞生于微服务架构时代,考虑的是微服务治理的方方面面,另外由于依托了SpirngSpirng Boot的优势之上,两个框架在开始目标就不一致,Dubbo定位服务治理、Spirng Cloud是一个生态。

Copyright © www.yuchaoit.cn 2025 all right reserved,powered by Gitbook作者:于超 2024-03-31 19:42:38

results matching ""

    No results matching ""