因语雀和CSDN MarkDown格式有区别,导入到CSDN时可能会有格式显示问题,请查看原文链接:https://www.yuque.com/dycloud/pss8ys/esxu1segbwg6kav9
一、应用架构及演进
要了解服务网格,我们需要从应用架构的演进说起,单体应用的优缺点,以及为什么需要拆分应用,拆分应用的优缺点,以及拆分应用的方式,最后引出服务网格的概念。1.1 单体应用
在软件开发早期阶段,大家都在一个应用系统上开发。各个业务模块之间耦合也比较紧密。软件发布也是整体发布,或者对软件进行打包发布和部署,比如 java 可以打包成 war 部署。测试也很容易,因为代码都在一起,基本不需要引用外部的关联服务。在软件开发早期,这种软件开发模式能适应业务的发展,软件应用也可以正常运行。如果你的业务发展良好,客户需求会变得越来越多,软件功能数也会随着客户的需求变多而变多。为了实现这些功能,你必须添加很多代码。而随着业务进一步发展,代码量势必也会越增越多。有可能 2 到 3 年后,软件代码量会变得非常巨大。那时软件就会变成一个非常庞大且复杂的单体应用。软件里面的功能多,代码错综复杂。
此时可能出现的问题:
- 打包编译会耗时很久,导致发布也很耗时。
- 代码可维护性变差,因为代码量大,逻辑复杂,只有少数老员工能全部理解。代码质量难以保证,复用性差等,代码腐化严重。
- 修改 BUG 和增加新功能会变得困难,可能牵一发而动全身。
- 软件扩展变得困难
- 软件可用性风险增加。可能一个 BUG 导致整个软件不可用。
1.2 分层架构
+ 用户界面(前端)和业务逻辑/数据服务(后端)完全分开开发、部署。 + 前端通常为SPA(单页应用),通过API(REST/GraphQL等)与后端交互。 + 前端和后端有独立的代码库、技术选型和部署生命周期。 + 前后端并行开发,提高效率。 + 前端体验提升:动态刷新、富交互成为可能。 + 扩展性和复用性更好:同一API可服务PC、App等多端。 + 方便分工合作。缺点:
- 增加了API开发和接口联调的难度。
- 一定程度增加架构复杂性(需要接口文档、API网关等)。
- 前后端需要协商数据契约。
1.3 SOA(面向服务架构)
** SOA(Service-Oriented Architecture,面向服务架构)是一种系统架构思想。它把系统的不同功能拆分为“服务”,每个服务完成特定的业务功能,并通过定义良好的接口相互通信。SOA的核心目标是实现松耦合** 、** 服务复用** ,便于不同系统集成、后续功能扩展和维护。SOA的主要特点
- 服务松耦合:各服务独立开发、部署和运维,适配不同行业和平台。
- 标准化接口:通过平台无关的标准协议(如HTTP、SOAP、REST)进行通信。
- 服务复用和组合:已有服务可被共享和组合,减少重复开发。
- 易集成:适合整合遗留系统或第三方系统。
ESB(Enterprise Service Bus,企业服务总线)是SOA架构中的核心基础设施。它是一种"中间件总线",用于连接、协调和管理各种分布式服务,实现服务间的通信、转换和治理。
esb 的详细作用如下:
- 解耦不同服务和系统
- 前后系统互不直接通信,服务升级、替换、维护更灵活。
- 解决异构系统集成难题
- 支持多种通信协议和数据格式的自动适配,方便新老系统互通。
- 集中管理和安全控制
- 统一服务注册、认证、权限、安全审计等,增强系统安全性和可运维性。
- 流程编排和服务组合
- 允许将多个基础服务组合为新的复合服务,方便扩展复杂业务场景。
- 提高服务复用率和开发效率
- 公共服务可供多个业务系统共同调用,减少重复造轮子。
SOA 架构缺点:
- ESB自身会成为单点瓶颈和性能压力点,故障风险高。
- 架构设计复杂度较高,对项目实施与管理团队要求较高。
- 可能引入额外的消息传输延迟。
- 若过度依赖ESB,系统灵活性可能下降。
1.4 微服务架构
1.4.1 微服务架构介绍
随着互联网的快速大规模增长,企业IT架构的重点从传统的记录系统转变为参与系统,这类的参与系统必须支持快速迭代和低成本试错,因而“微服务”的概念甫一出现便甚得人心。
微服务的规范定义
- 最早出现于2011年的“微服务”在2014年由Martin Fowler通过一篇著名的文章发扬光大;该文章可抽象出以 下几个关键点
- 由一些独立的服务共同组成应用系统
- 每个服务单独部署、独立运行在自己的进程中
- 每个服务都是独立的业务
- 分布式管理
- 遵循低耦合、高内聚的原则
微服务中的调用链路较之传统的分布式系统长了很多,于链路上发生故障的概率也必然随之增大,且
存在性能损耗,于是,系统规划时必须考虑如何进行雪崩预防、功能降级、超时、重试、熔断、服务
隔离等服务管理;
那么在具体的实践中,使用微服务架构有哪些优势和劣势呢?
1.4.2 微服务架构优势与劣势
** 优势**- 应用小,可快速编译部署
- 单个微服务维护性变高,修改容易,因为每个团队独立负责一块功能。新功能交付变快,可以快速开发交付
- 扩展性变高,根据业务规模可以随时缩减/增加服务器规模
- 可靠性变强,可以部署很多独立的服务
- 业务解耦,按照业务边界拆分为多个独立的服务模块
- 提升研发效率,业务拆分后,服务模块变小,在一个团队内就可以独立编写、测试、发布,加快研发效率。
拆分后,单个微服务比较小,它只专注于做好一件事情。拆分的指导原则:高内聚,低耦合。
单一微服务有点像软件设计中的单一职责原则,Martin 对单一职责有一个论述:把因相同原因而变化的东西聚合到一起,而把因不同原因而变化的东西分离开来。
虽然微服务有这么多的好处,但是也需要注意的是,微服务架构并不是银弹,它同样也带来了很多的劣势(问题)。
劣势
- 整体复杂度变高,从哪些方面来管理这种复杂度?
- 运维变得复杂:微服务变多,怎么监控所有微服务,保证服务稳定?出了问题,怎么定位问题?
- 服务管理:微服务变多,管理复杂度变高,治理变得复杂
- 测试方面的挑战:你需要结合其他的微服务来进行集成测试
- 分布式问题:分布式数据一致性、分布式事务
- 服务可用性保障:一个服务出了问题,如何才能不影响其他服务?
1.4.3 微服务架构演进
根据上面微服务定义,这些服务都是由小型独立团队负责,那团队怎么划分?公司组织架构如何调整才能适应微服务的架构发展?这也给组织管理带来了变革的挑战。还有微服务的微
,多微
才是好的微
?也就是微服务怎么划分,如何确定边界?等等这些都是微服务面临的问题和挑战。
所以我们在使用微服务架构时,需要权衡微服务的优势和劣势,任何事物都有正反面,就像一枚硬币一样,所以思考问题要多样化,不能只思考一点。当我们享受微服务给开发和产品带来好处的同时,本身也会带来一系列的问题,如何克服这些问题,才是实施好微服务的关键所在。
随着技术的发展,软件架构的不断升级调整,上面我们遇到的这些问题大部分是可以解决的。比如需要建立运维开发基础设施来加以保障才能让微服务顺利运行,比如需要建设以 CI/CD 为基础的自动化交付流水线,到最后建设成从开发、测试、预发布、上线、运维等整个研发流程自动化的 DevOps 为目标。因为随着微服务的逐步建设,服务数量增多,上线服务次数必然增多,交付频繁会带来故障次数增多,所以我们必须建设自动化的工具链,来帮助我们快速无误的交付服务,实施好微服务项目。
而为了解决其他方面的问题,比如微服务的服务发现、熔断、降级、限流等等服务治理方面的问题,也有专门的技术栈来解决,比如 Spring Cloud、Dubbo 等。
Spring Cloud 是在 Spring 基础上构建的,Spring 是一个全家桶,Spring Cloud 也是一个全家桶,它由很多技术框架组合而成,包括:
- ** 服务治理**
- 服务注册和发现:Netflix Eureka
- 当然我们也有其他的选择,比如
<font style="color:#DF2A3F;">consul</font>
、<font style="color:#DF2A3F;">etcd</font>
、<font style="color:#DF2A3F;">zookeeper</font>
等 - 断路器:
<font style="color:#DF2A3F;">Hystrix</font>
- 调用端负载均衡:
<font style="color:#DF2A3F;">Ribbon</font>
- REST 客户端:
<font style="color:#DF2A3F;">Feign</font>
- **网关 **
- API 网关:Zuul
- 当然我们也可以选择其他的,比如 Spring Cloud Gateway、kong、nginx+lua、apisix 等
- **分布式链路监控 **
- Spring Cloud Sleuth:埋点和发送数据
- 当然还有其他的比如 zipkin、pinpoint、skywalking、jaeger 等
- ** 消息组件**
- Spring Cloud Stream
- Spirng Cloud Bus
- 消息中间件的其他软件:RocketMQ、Kafka、RabbitMQ
- **配置中心 **
- Spring Cloud Config
- 配置中心可以有其他的替代,比如 Apollo、Nacos 等
- **安全控制 **
- Spring Cloud Security
Spring Cloud 是一整套微服务体系,它是一个完整的微服务解决方案,Spring Cloud 社区强大,也很活跃,这也是现在比较主流的微服务技术栈。
但是 Spring Cloud 也有一些缺点,比如它是基于 Spring 的,所以它的技术栈都是基于 Java 的,如果你的团队不是 Java 的,那么你可能需要考虑其他的技术栈。另外,Spring Cloud 的技术栈比较多,学习成本也比较高,所以你需要考虑你的团队是否有能力学习和使用 Spring Cloud。Spring Cloud 微服务体系具体还有哪些缺点呢?
- 代码侵入性强 - 业务层中需要加入治理层代码,与治理层混淆在一起
- 组件多 - 组件多,学习成本就变高
- 治理功能不全 - 比如协议转换、动态请求路由、灰度发布等功能
- 无法实现语言无关性 - 只能是一种语言或几种语言实现,无法做到与编程语言无关,这和微服务架构的初衷是相违背的
针对以上的一些问题,就出现了 服务网格(Service Mesh) 这种架构,它作为一个基础设施层,真正做到与业务解耦,与语言无关,解决复杂架构下微服务应用与微服务应用之间通信网络相关问题,做到与业务解耦,让开发者专注于业务开发,而不是服务治理相关的问题。
二、服务网格(Service Mesh)
2.1 服务网格介绍
服务网格是一种基础设施层,它由一组网络代理组成,这些代理负责管理和协调服务之间的通信。服务网格可以提供服务发现、负载均衡、故障恢复、流量控制、安全等功能,从而简化了微服务架构中的一些问题。服务网格的代理通常是以 sidecar 的形式部署在每个服务实例旁边。这些 sidecar 代理可以拦截服务之间的通信,并提供一些额外的功能,例如负载均衡、故障恢复、流量控制等。服务网格还可以提供一些高级功能,例如 A/B 测试、金丝雀发布、蓝绿部署等。
服务网格的一个重要特点是透明性。服务网格的代理可以自动处理服务之间的通信,而不需要服务本身进行任何修改。这意味着我们可以在不影响服务本身的情况下,对服务之间的通信进行管理和控制。
这里最重要的是一种思维转变,不再将代理看成孤立的组件,而是将其组成的网络视为一种有价值的实体。
TCP 协议催生了分布式系统,分布式系统催生了微服务,Service Mesh 就是下一代微服务技术的代名词,是微服务时代的 TCP 协议。Service Mesh 以 Sidecar 形式,将服务治理从业务逻辑中剥离,并拆解为独立进程,实现异构系统的统一治理和网络安全。
为了能够对这些代理进行管理和控制,服务网格演进出了统一的控制平面(control plane)和数据面板(data plane,即边车代理)。
2.2 服务网格的基本功能
+ ** 控制服务间通信** : 熔断 、 重试 、 超时 、 故障注入 、 负载均衡和故障转移 等; + ** 服务发现** :通过专用的服务总线发现服务端点; + ** 可观测** :指标数据采集、监控、分布式日志记录和分布式追踪; + ** 安全性** :TLS/SSL通信和密钥管理; + ** 身份认证和授权检查** :身份认证,以及基于黑白名单或RBAC的访问控制功能; + ** 部署** :对容器技术的原生支持,例如Docker和Kubernetes等; + ** 服务间的通信协议** :HTTP 1.1、HTTP 2.0和gRPC等; + ** 健康状态检测** :监测上游服务的健康状态;ServiceMesh 解决方案极大降低了业务逻辑与网络功能之间的耦合度,能够快捷、方便的集成到现有的业务环境中,并提供了多语言、多协议支持,运维和管理成本被大大降低,且开发人员能够将精力集中于业务逻辑本身,而无需再关注业务代码以外的其他功能。
ServiceMesh 中,服务间的通讯将遵循一下通讯逻辑:
- 微服务彼此间不会直接进行通信,而是由各服务前端的称为Service Mesh的代理程序(Sidecar)进行;
- Service Mesh内置支持服务发现、熔断、负载均衡等网络相关的用于控制服务间通信的各种高级功能
- Service Mesh与编程语言无关,开发人员可以使用任何编程语言编写微服务的业务逻辑,各服务之间也可以使用不同的编程语言开发;
- 服务间的通信的局部故障可由Service Mesh自动处理;
- Service Mesh中的各服务的代理程序由控制平面(Control Plane)集中管理;各代理程序之间的通信网络也称为数据平面(Data Plane);
- 部署于容器编排平台时,各代理程序会以微服务容器的Sidecar模式运行;
2.3 控制平面与数据平面
2.3.1 数据平面
由**整个网格内的 Sidecar 代理组成**,**这些代理以 Sidecar 的形式和应用服务一起部署**。 这些** 代理负责协调和控制应用服务之间的所有网络通信**。每一个 Sidecar 会接管进入和离开服务的流量,并配合控制平面完成流量控制等方面的功能。2.3.2 控制平面
** 控制和管理数据平面中的 Sidecar 代理,完成配置分发、服务发现、流量路由、授权鉴权等功能**,以达到对数据平面的统一管理。控制平面不会直接解析请求数据包。通常提供 API 或者命令行工具可用于配置版本化管理,便于持续集成和部署。控制平面组件 :
工作负载调度程序:借助于底层的基础设施(例如kubernetes)完成服务及其Sidecar运行位置的调度决
策;
服务发现:服务网格中的服务发现;
Sidecar代理配置API:各Sidecar代理以最终一致的方式从各种系统组件获取配置;
控制平面UI:管理人员的操作接口,用于配置全局级别的设置,例如部署、身份认证和授权、路由
及负载均衡等;
2.3 服务网格总结
总结一下,Service Mesh 具有如下优点:- 屏蔽分布式系统通信的复杂性(负载均衡、服务发现、认证授权、监控追踪、流量控制等等),服务只用关注业务逻辑
- 真正的语言无关,服务可以用任何语言编写,只需和 Service Mesh 通信即可
- 对应用透明,Service Mesh 组件可以单独升级
当然,Service Mesh 目前也面临一些挑战:
- Service Mesh 组件以代理模式计算并转发请求,一定程度上会降低通信系统性能,并增加系统资源开销
- Service Mesh 组件接管了网络流量,因此服务的整体稳定性依赖于 Service Mesh,同时额外引入的大量 Service Mesh 服务实例的运维和管理也是一个挑战
最后我们简单对比下 Spring Cloud 与服务网格的区别:
能力 | Spring Cloud 生态系统 | Service Mesh 生态系统 |
---|---|---|
服务注册与发现 | 开发简单方便,仅需一个简单的注解,支持多种注册中心。对开发人员来说,很容易在本地环境下完成编码和调试。 | 基于 K8s 的服务机制,并提供自己的注册中心。开发人员需要理解 Kubernetes,而开发环境的设置并不容易。 |
故障容忍性 | Resilience4j 的官方整合提供了完整的故障容忍机制。但服务需要与 SDK 整合。 |
通过使用 sidecar 架构,它是一个非侵入式的故障容忍机制,对服务完全透明。 |
可观察性 | Spring Cloud 内置,例如 spring micro-meter、Zipkin 等。所有服务内部的指标、追踪和日志都可以轻松收集,对开发者完全透明。 | 通过 sidecar 机制,它可以监控进出通信。没有可观察的服务内部,服务追踪可能是不完整的。 |
流量调度 | Spring Cloud 仅有非常基础的流量调度,例如,它基于 Ribbon 的负载均衡(从上一版本中删除)。 | 更多的流量调度方案,如金丝雀部署、蓝绿部署都可以轻松完成。 |
三、K8S 与服务网格
随着现在云原生技术的发展,Kubernetes 已经成为了云原生的标准,它是一个开源的容器编排平台,它可以自动化地部署、扩展和管理容器化的应用程序。Kubernetes 可以帮助我们管理微服务架构中的服务,例如自动化部署、负载均衡、故障恢复等。同样服务网格和 K8s 的结合可以提供更强大的功能,**服务网格可以提供服务发现、负载均衡、故障恢复、流量控制、安全等功能,而 K8s 可以自动化地部署、扩展和管理容器化的应用程序**。通过将服务网格和 K8s 结合起来,我们可以更轻松地管理和控制微服务架构中的服务。虽然 K8s 可以帮助我们管理微服务架构中的服务,但是它并不能解决所有的问题。K8s 主要关注的是容器编排和管理,例如自动化部署、扩展和管理容器化的应用程序。而服务网格则关注于服务之间的通信,例如服务发现、负载均衡、故障恢复、流量控制、安全等。
微服务、云原生、Kubernetes 和服务网格是现代应用开发和部署的关键概念,它们之间有着密切的关系。微服务和云原生强调应用程序的可扩展性、可维护性和可部署性,Kubernetes 可以帮助我们自动化地部署、扩展和管理容器化的应用程序,服务网格可以提供服务发现、负载均衡、故障恢复、流量控制、安全等功能,从而简化了微服务架构中的一些问题。
3.1 服务网格主流对比
在 [servicemesh.es](https://servicemesh.es/) 网站中详细的列出了主流服务网格的详细对比。在实现上,数据平面的主流解决方案有<font style="color:rgb(0,0,0);">Linkerd</font>
、<font style="color:rgb(0,0,0);">Nginx</font>
、<font style="color:rgb(0,0,0);">Envoy</font>
、<font style="color:rgb(0,0,0);">HAProxy</font>
和<font style="color:rgb(0,0,0);">Traefik</font>
等,而控制平面的实现主要有<font style="color:rgb(0,0,0);">Istio</font>
、<font style="color:rgb(0,0,0);">Nelson</font>
和<font style="color:rgb(0,0,0);">SmartStack</font>
等几种
**<font style="color:#DF2A3F;">Linkerd</font>**
- 由Buoyant公司于2016年率先创建的开源高性能网络代理程序(数据平面),是业界第一款Service Mesh产品,引领并促进了相关技术的快速发展
- Linkerd使用Namerd提供控制平面,实现中心化管理和存储路由规则、服务发现配置、支持运行时动态路由等功能
**<font style="color:#DF2A3F;">Envoy</font>**
- 核心功能在于数据平面,于2016年由Lyft公司创建并开源,目标是成为通用的数据平面
- 云原生应用,既可用作前端代理,亦可实现Service Mesh中的服务间通信
- Envoy常被用于实现API Gateway(如Ambassador)以及Kubernetes的Ingress Controller(例如Gloo等),不过,基于Envoy实现的Service Mesh产品Istio有着更广泛的用户基础
**<font style="color:#DF2A3F;">Istio</font>**
- 相比前两者来说,Istio发布时间稍晚,它于2017年5月方才面世,但却是目前最火热的Service Mesh解决方案,得到了Google、IBM、Lyft及Redhat等公司的大力推广及支持
- 目前仅支持部署在Kubernetes之上,其数据平面由Envoy实现
尽管服务网格对代码没有影响,但它们改变了操作流程,并需要熟悉新的概念和技术。因此,采用服务网格实现是一个长期决策,特别是在广泛支持服务网格之前。因此,应提前仔细比较和测试这些实现。
评估的目标是弄清楚哪些功能对你更重要,由于服务网格会影响延迟和资源消耗,这些不利因素也必须进行衡量。我们建议在决策过程中包括以下步骤:
- 作为团队,确定由服务网格解决的最重要的问题。
- 讨论你对简单性/易用性、性能和兼容性的要求。
- 根据你的功能和非功能要求,确定你的前两个或三个实现。
- 测试你的个别应用程序的延迟和资源开销。针对每个服务网格候选者,设置相同的测试环境并安装服务网格。设置一个额外的无网格环境。在所有环境中安装您的应用程序。使用 Locust 或 Fortio 等工具在所有环境中进行负载测试,并测量请求延迟、CPU 和内存消耗。
如果你没有对这些服务网格技术做详细的评估了解,那么你可以从 Istio 开始,它是一个开源的服务网格,它提供了一些强大的功能,例如流量管理、策略执行、服务间通信、可观察性等。Istio 是一个非常活跃的开源项目,它有一个非常活跃的社区,它的文档也非常丰富,可以帮助你快速上手 Istio,目前 Istio 是最好的选择。
3.2 K8S 和 ServiceMesh
除强大的服务编排能力之外,Kubernetes还基于Service提供了基础的服务互访能力,而轻量化运行的Pod,再加上服务注册、服务发现、负载均衡以及健康状态检测,天然就适合编排支持微服务只是,Kubernetes提供的这种能力大多停留在四层的互访上,无法实现微服务依赖的熔断、限流、动态路由或调用链埋点等应用层的能力,因而仍然不得不借助于微服务框架来完成
微服务框架存在侵入性强和语言锁定等方面的问题,而且会架空Kubernetes的Service机制,而Service Mesh就是解决这些侵入性问题的最好方式
- 在Kubernetes平台上,最好的方式就是基于Kubernetes的服务注册和服务发现机制提供一个Kubernetes平台原生的ServiceMesh解决方案
- 复用了Kubernetes的编排能力,同时提供微服务治理所需的可观测性、 服务韧性、灵活分流、弹性和安全等能力
Istio就是Kubernetes平台原生的ServiceMesh的实现之一
- 复用了Kubernetes Service的定义,并将其转换为Istio的服务模型
- 数据平面组件从kube-proxy转为各服务实例的Sidecar
- Sidecar的标准实现之一,是
<font style="color:#DF2A3F;">Envoy</font>
- 其它实现:
<font style="color:rgb(0,0,0);">Cilium</font>
、<font style="color:rgb(0,0,0);">Mosn</font>
、<font style="color:rgb(0,0,0);">Linked-proxy</font>
和<font style="color:rgb(0,0,0);">grpc</font>
等
- Sidecar的标准实现之一,是
核心理念:
- 非侵入式
**<font style="color:#DF2A3F;">Sidecar</font>**
注入技术,将数据面组件注入到应用所在的容器,通过劫持应用流量来进行功能实现,应用无感知 - 北向API基于K8s CRD实现,完全声明式,标准化
- 数据面与控制面通过xDSgRPC标准化协议通信,支持订阅模式
核心特性:
- 服务&流量治理:熔断,故障注入,丰富的负载均衡算法,限流,健康检查,灰度发布,蓝绿部署等
- 流量与访问可视化:提供应用级别的监控,分布式调用链,访问日志等
- 安全连接:通过mTLS、认证、鉴权等安全措 施帮助企业在零信任的网络中运行应用