服务网络基础
目录
前言
从今天开始我们将进入服务网格的学习,服务网格是微服务架构中的一种重要的技术,它可以解决微服务架构中的一些问题,比如服务发现、服务治理、服务监控等等,我们将从服务网格的基础开始,逐步深入,希望能够帮助大家理解服务网格。
1、应用架构的演进
要了解服务网格,我们需要从应用架构的演进说起。应用架构的演进过程就需要从单体应用开始说起,单体应用的优缺点,以及为什么需要拆分应用,拆分应用的优缺点,以及拆分应用的方式,最后引出服务网格的概念。
1.单体应用
在软件开发早期阶段,大家都在一个应用系统上开发。各个业务模块之间耦合也比较紧密。软件发布也是整体发布,或者对软件进行打包发布和部署,比如 java 可以打包成 war 部署。测试也很容易,因为代码都在一起,基本不需要引用外部的关联服务。
在软件开发早期,这种软件开发模式能适应业务的发展,软件应用也可以正常运行。如果你的业务发展良好,客户需求会变得越来越多,软件功能数也会随着客户的需求变多而变多。为了实现这些功能,你必须添加很多代码。而随着业务进一步发展,代码量势必也会越增越多。有可能 2 到 3 年后,软件代码量会变得非常巨大。那时软件就会变成一个非常庞大且复杂的单体应用。软件里面的功能多,代码错综复杂。
此时可能出现的问题:
- 打包编译会耗时很久,导致发布也很耗时。
- 代码可维护性变差,因为代码量大,逻辑复杂,只有少数老员工能全部理解。代码质量难以保证,复用性差等,代码腐化严重。
- 修改 BUG 和增加新功能会变得困难,可能牵一发而动全身。
- 软件扩展变得困难
- 软件可用性风险增加。可能一个 BUG 导致整个软件不可用。
那么应该如何解决上面的这些问题呢,俗话说:大事化小 - 拆字诀。
第一步可能想到的就是拆分应用。把一个大型的单体应用按照业务功能进行拆分。比如电商应用,可能拆分为商品应用、订单应用、用户应用、商铺应用等等相对比较小的应用功能。
当随着业务规模进一步的发展,我们可能还要继续把上面的应用做进一步拆分,变成更小的应用,以服务的形式对外提供应用服务。应用慢慢的拆分为了比较小的服务 - 微服务。
2.微服务应用
这样应用就变成了微服务应用,每个微服务都是一个独立的应用,它们之间通过**网络(restful api或者grpc)**进行通信。那么微服务的具体定义是什么呢?
grpc:进程间通信协议。
- 维基百科定义:微服务 (Microservices) 是一种软件架构风格,它是以专注于单一责任与功能的小型功能区块 (Small Building Blocks) 为基础,利用模块化的方式组合出复杂的大型应用程序,各功能区块使用与语言无关 (Language-Independent/Language agnostic) 的 API 集相互通信。
- AWS 的定义:微服务是一种开发软件的架构和组织方法,其中软件由通过明确定义的 API 进行通信的小型独立服务组成。这些服务由各个小型独立团队负责。微服务架构使应用程序更易于扩展和更快地开发,从而加速创新并缩短新功能的上市时间。
- Thoughtworks 首席科学家的定义:微服务架构是一种架构模式,它提倡将单一应用程序划分为一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在其独立进程中,服务与服务之间通常采用轻量级的通信机制相互沟通。每个服务都围绕具体的业务进行构建,并且能独立部署到生产环境中。
resilience n.回弹性;恢复力;
可观测性也是微服务里一个很重要的方面。
虽然不同的组织对微服务的定义不是完全一致的,但是它们的核心能力是一致的,即将单体应用拆分为多个小型服务,每个服务都是一个独立的应用,它们之间通过网络进行通信,每个微服务都有自己的代码库、数据库和运行环境。
那么在具体的实践中,使用微服务架构有哪些优势和劣势呢?
优势
- 应用小,可快速编译部署
- 单个微服务维护性变高,修改容易,因为每个团队独立负责一块功能。新功能交付变快,可以快速开发交付
- 扩展性变高,根据业务规模可以随时缩减/增加服务器规模
- 可靠性变强,可以部署很多独立的服务
- 业务解耦,按照业务边界拆分为多个独立的服务模块
- 提升研发效率,业务拆分后,服务模块变小,在一个团队内就可以独立编写、测试、发布,加快研发效率。
拆分后,单个微服务比较小,它只专注于做好一件事情。拆分的指导原则:高内聚,低耦合。
单一微服务有点像软件设计中的单一职责原则,Martin 对单一职责有一个论述:把因相同原因而变化的东西聚合到一起,而把因不同原因而变化的东西分离开来。
虽然微服务有这么多的好处,但是也需要注意的是,微服务架构并不是银弹,它同样也带来了很多的劣势(问题)。
劣势
- 整体复杂度变高,从哪些方面来管理这种复杂度?
- 运维变得复杂:微服务变多,怎么监控所有微服务,保证服务稳定?出了问题,怎么定位问题?
- 服务管理:微服务变多,管理复杂度变高,治理变得复杂
- 测试方面的挑战:你需要结合其他的微服务来进行集成测试
- 分布式问题:分布式数据一致性、分布式事务 (尤其在做支付领域,这方面更加重要。)
- 服务可用性保障:一个服务出了问题,如何才能不影响其他服务?
根据上面微服务定义,这些服务都是由小型独立团队负责,那团队怎么划分?公司组织架构如何调整才能适应微服务的架构发展?这也给组织管理带来了变革的挑战。
例如:ddd:做微服务的划分。
还有微服务的微
,多微
才是好的微
?也就是微服务怎么划分,如何确定边界?等等这些都是微服务面临的问题和挑战。
所以我们在使用微服务架构时,需要权衡微服务的优势和劣势,任何事物都有正反面,就像一枚硬币一样,所以思考问题要多样化,不能只思考一点。当我们享受微服务给开发和产品带来好处的同时,本身也会带来一系列的问题,如何克服这些问题,才是实施好微服务的关键所在。
随着技术的发展,软件架构的不断升级调整,上面我们遇到的这些问题大部分是可以解决的。比如需要建立运维开发基础设施来加以保障才能让微服务顺利运行,比如需要建设以 CI/CD 为基础的自动化交付流水线,到最后建设成从开发、测试、预发布、上线、运维等整个研发流程自动化的 DevOps 为目标。因为随着微服务的逐步建设,服务数量增多,上线服务次数必然增多,交付频繁会带来故障次数增多,所以我们必须建设自动化的工具链,来帮助我们快速无误的交付服务,实施好微服务项目。
而为了解决其他方面的问题,比如微服务的服务发现、熔断、降级、限流等等服务治理方面的问题,也有专门的技术栈来解决,比如 Spring Cloud、Dubbo(阿里的) 等。
Spring Cloud 是在 Spring 基础上构建的,Spring 是一个全家桶,Spring Cloud 也是一个全家桶,它由很多技术框架组合而成,包括:
Circuit Breakers
断路器。
-
服务治理
-
服务注册和发现:Netflix Eureka
-
当然我们也有其他的选择,比如 consul、etcd、zookeeper 等
-
断路器:Hystrix
-
调用端负载均衡:Ribbon
-
REST 客户端:Feign
-
网关
-
API 网关:Zuul
-
当然我们也可以选择其他的,比如 Spring Cloud Gateway、kong、nginx+lua、apisix 等
-
分布式链路监控
-
Spring Cloud Sleuth:埋点和发送数据
-
当然还有其他的比如 zipkin、pinpoint、skywalking(java里面最流行的)、jaeger(golang开发的) 等
-
消息组件
-
Spring Cloud Stream
-
Spirng Cloud Bus
-
消息中间件的其他软件:RocketMQ、Kafka、RabbitMQ
-
配置中心
-
Spring Cloud Config
-
配置中心可以有其他的替代,比如 Apollo、Nacos (国内比较流行的2种方式) 等
-
安全控制
-
Spring Cloud Security
Spring Cloud 是一整套微服务体系,它是一个完整的微服务解决方案,Spring Cloud 社区强大,也很活跃,这也是现在比较主流的微服务技术栈。
但是 Spring Cloud 也有一些缺点,比如它是基于 Spring 的,所以它的技术栈都是基于 Java 的,如果你的团队不是 Java 的,那么你可能需要考虑其他的技术栈。另外,Spring Cloud 的技术栈比较多,学习成本也比较高,所以你需要考虑你的团队是否有能力学习和使用 Spring Cloud。Spring Cloud 微服务体系具体还有哪些缺点呢?
- 代码侵入性强 - 业务层中需要加入治理层代码,与治理层混淆在一起 (很多都是通过注释的方式加入)
- 组件多 - 组件多,学习成本就变高
- 治理功能不全 - 比如协议转换、动态请求路由、灰度发布等功能 (如果想做的话,可以把spring cloud部署到k8s里,k8s来做灰度等功能)
- 无法实现语言无关性 - 只能是一种语言或几种语言实现,无法做到与编程语言无关,这和微服务架构的初衷是相违背的
针对以上的一些问题,就出现了 服务网格(Service Mesh) 这种架构,它作为一个基础设施层,真正做到与业务解耦,与语言无关,解决复杂架构下微服务应用与微服务应用之间通信网络相关问题,做到与业务解耦,让开发者专注于业务开发,而不是服务治理相关的问题。
3.服务网格
服务网格是一种基础设施层,它由一组网络代理组成,这些代理负责管理和协调服务之间的通信。服务网格可以提供服务发现、负载均衡、故障恢复、流量控制、安全等功能,从而简化了微服务架构中的一些问题。
服务网格的代理通常是以 sidecar 的形式部署在每个服务实例旁边。这些 sidecar 代理可以拦截服务之间的通信,并提供一些额外的功能,例如负载均衡、故障恢复、流量控制等。服务网格还可以提供一些高级功能,例如 A/B 测试、金丝雀发 布、蓝绿部署等。
服务网格的一个重要特点是透明性。服务网格的代理可以自动处理服务之间的通信,而不需要服务本身进行任何修改。这意味着我们可以在不影响服务本身的情况下,对服务之间的通信进行管理和控制。
这里最重要的是一种思维转变,不再将代理看成孤立的组件,而是将其组成的网络视为一种有价值的实体。
TCP 协议催生了分布式系统,分布式系统催生了微服务,Service Mesh 就是下一代微服务技术的代名词,是微服务时代的 TCP 协议。Service Mesh 以 Sidecar 形式,将服务治理从业务逻辑中剥离,并拆解为独立进程,实现异构系统的统一治理和网络安全。
为了能够对这些代理进行管理和控制,服务网格演进出了统一的控制平面(control plane)和数据面板(data plane,即边车代理)。
控制平面
控制和管理数据平面中的 Sidecar 代理,完成配置分发、服务发现、流量路由、授权鉴权等功能,以达到对数据平面的统一管理。控制平面不会直接解析请求数据包,通常提供 API 或者命令行工具可用于配置版本化管理,便于持续集成和部署。
数据平面
由整个网格内的 Sidecar 代理组成,这些代理以 Sidecar 的形式和应用服务一起部署。 这些代理负责协调和控制应用服务之间的所有网络通信。每一个 Sidecar 会接管进入和离开服务的流量,并配合控制平面完成流量控制等方面的功能。
总结一下,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里,pod里多个容器是共享网络命名空间的。
2、微服务、Kubernetes 与服务网格
随着现在云原生技术的发展,Kubernetes 已经成为了云原生的标准,它是一个开源的容器编排平台,它可以自动化地部署、扩展和管理容器化的应用程序。Kubernetes 可以帮助我们管理微服务架构中的服务,例如自动化部署、负载均衡、故障恢复等。同样服务网格和 K8s 的结合可以提供更强大的功能,服务网格可以提供服务发现、负载均衡、故障恢复、流量控制、安全等功能,而 K8s 可以自动化地部署、扩展和管理容器化的应用程序。通过将服务网格和 K8s 结合起来,我们可以更轻松地管理和控制微服务架构中的服务。
虽然 K8s 可以帮助我们管理微服务架构中的服务,但是它并不能解决所有的问题。K8s 主要关注的是容器编排和管理,例如自动化部署、扩展和管理容器化的应用程序。而服务网格则关注于服务之间的通信,例如服务发现、负载均衡、故障恢复、流量控制、安全等。
微服务、云原生、Kubernetes 和服务网格是现代应用开发和部署的关键概念,它们之间有着密切的关系。微服务和云原生强调应用程序的可扩展性、可维护性和可部署性,Kubernetes 可以帮助我们自动化地部署、扩展和管理容器化的应用程序,服务网格可以提供服务发现、负载均衡、故障恢复、流量控制、安全等功能,从而简化了微服务架构中的一些问题。
3、服务网格主流对比
在 servicemesh.es 网站中详细的列出了主流服务网格的详细对比。
那么我们应该如何选择服务网格呢?
尽管服务网格对代码没有影响,但它们改变了操作流程,并需要熟悉新的概念和技术。因此,采用服务网格实现是一个长期决策,特别是在广泛支持服务网格之前。因此,应提前仔细比较和测试这些实现。
评估的目标是弄清楚哪些功能对你更重要,由于服务网格会影响延迟和资源消耗,这些不利因素也必须进行衡量。我们建议在决策过程中包括以下步骤:
- 作为团队,确定由服务网格解决的最重要的问题。
- 讨论你对简单性/易用性、性能和兼容性的要求。
- 根据你的功能和非功能要求,确定你的前两个或三个实现。
- 测试你的个别应用程序的延迟和资源开销。针对每个服务网格候选者,设置相同的测试环境并安装服务网格。设置一个额外的无网格环境。在所有环境中安装您的应用程序。使用 Locust 或 Fortio 等工具在所有环境中进行负载测试,并测量请求延迟、CPU 和内存消耗。
如果你没有对这些服务网格技术做详细的评估了解,那么你可以从 Istio 开始,它是一个开源的服务网格,它提供了一些强大的功能,例如流量管理、策略执行、服务间通信、可观察性等。Istio 是一个非常活跃的开源项目,它有一个非常活跃的社区,它的文档也非常丰富,可以帮助你快速上手 Istio,目前 Istio 是最好的选择。
4、Istio 基础架构
- isio官网
https://istio.io/
中文官网:
https://istio.io/latest/zh/
凭借 Kubernetes 良好的架构设计及其强大的扩展性,Google 围绕 Kubernetes 打造一个生态系统。Kubernetes 用于微服务的编排(描述一组微服务之间的关联关系,并负责微服务的部署、终止、升级、缩扩容等)。Istio 补充了 Kubernetes 生态圈的重要一环,是 Google 的微服务版图里一个里程碑式的扩张。
Istio 是一个开源服务网格,可以透明地分层到现有的分布式应用程序上。 Istio 的强大功能提供了一种统一且更有效的方式来保护、连接和监控服务。 Istio 是实现负载均衡、服务间身份验证和监控的途径 - 只需很少或无需更改服务代码。其强大的控制平面带来了重要的功能,包括:
- 通过 TLS 加密、基于身份的强大身份验证和授权,确保集群中服务间通信的安全
- HTTP、gRPC、WebSocket 和 TCP 流量的自动负载均衡
- 通过丰富的路由规则、重试、故障转移和故障注入对流量行为进行细粒度控制
- 支持访问控制、速率限制和配额的可插入策略层和配置 API集群内所有流量的自动指标、日志和跟踪,包括集群入口和出口Istio 专为可扩展性而设计,可以满足各种部署需求。
Istio 的控制平面在 Kubernetes 上运行,您可以将部署在该集群中的应用程序添加到网格中,将网格扩展到其他集群,甚至连接在 Kubernetes 外部运行的虚拟机或其他端点。
但 Istio 在 1.5 版本之后架构发生了较大的变化,控制平面将之前版本中的多个组件整合为了一个单体结构的 istiod
组件,同时废弃了被诟病已久的 Mixer
组件,但是我们在理解架构的时候还是可以按照微服务的模式去理解,现在最新的版本已经是 1.19.x
版本了,所以这里我们直接为大家介绍最新的架构图,下图是 1.5 版本之后的架构图:
从图上可以看出整体上 Istio 同样也是包括数据面和控制面两个部分。
- 数据面由一组 Envoy 代理,代理部署为 sidecar,控制微服务之间所有的网络通信。
- 控制面负责管理和配置代理来路由流量,以及在运行时执行策略。
1.Envoy
数据平面核心的组件是 Envoy,它是一个用 C++ 开发的高性能代理,用于协调服务网格中所有服务的所有入站和出站流量。Envoy 代理是唯一与数据平面流量交互的 Istio 组件。
Envoy 代理作为服务的 sidecar 进行部署,从逻辑上通过 Envoy 的许多内置功能增强服务,例如:
- 动态服务发现
- 负载均衡
- TLS 终止
- HTTP/2 和 gRPC 代理
- 断路器
- 健康检查
- 基于百分比的分阶段部署
- 故障注入
- 丰富的指标
这种 sidecar 部署允许 Istio 执行策略决策并提取丰富的遥测数据,这些遥测数据可以发送到监控系统以提供有关整个网格行为的信息。
遥测数据一般是指链路追踪里的tracing,metrics,日志。
sidecar 代理模型还允许您将 Istio 功能添加到现有部署服务中,而无需重新架构或重写代码。
Envoy 代理启用的一些 Istio 功能和任务包括:
- 流量控制功能:通过丰富的 HTTP、gRPC、WebSocket 和 TCP 流量路由规则实施细粒度的流量控制。
- 网络弹性功能:设置重试、故障转移、断路器和故障注入。
- 安全和身份验证功能:强制执行安全策略并强制执行通过配置 API 定义的访问控制和速率限制。
- 基于
WebAssembly
的可插拔扩展模型,允许针对网格流量执行自定义策略和遥测生成。
2.istiod
控制平面由一个核心的 istiod
组件提供服务,用于 Istiod 提供服务发现、配置和证书管理。我们可以将 istiod
做进一步的细分,包括了 Pilot
、Citadel
和 Galley
,它们在 1.5 版本之前是属于独立的微服务组件,它们的各自功能如下:
Pilot
:为 Envoy 提供了服务发现,流量管理和智能路由(比如 A/B 测试、金丝雀发布等),以及错误处理(超时、重试、熔断)功能。Citadel
:为服务之间提供认证和证书管理,可以让服务自动升级成 TLS 协议。Galley
:Galley 是 Istio 的配置验证、提取、处理和分发组件。它负责将其余的 Istio 组件与从底层平台(例如 Kubernetes)获取用户配置的细节隔离开来。
整体上 Istiod
将控制流量行为的高级路由规则转换为特定的 Envoy 配置,并在运行时将它们传播到 sidecar。Pilot
抽象了特定于平台的服务发现机制,并将其合成为任何符合 Envoy API 的 sidecar 都可以使用的标准格式。因为 Istio 可以支持多种环境(例如 Kubernetes 或 VM)的发现。
我们可以使用 Istio 的流量管理 API 来指示 Istiod
优化 Envoy 配置,以对服务网格中的流量进行更精细的控制。
Istiod
安全性通过内置身份和凭证管理实现强大的服务到服务和最终用户身份验证。你可以使用 Istio 升级服务网格中的未加密流量。使用 Istio,运维人员可以根据服务身份而不是相对不稳定的第 3 层或第 4 层网络标识符来实施策略。此外,还可以使用 Istio 的授权功能来控制谁可以访问你的服务。
此外 Istiod
还充当证书颁发机构 (CA) 并生成证书以允许数据平面中的安全 mTLS 通信(双向通信)。
所以在正式开始学习 Istio 之前,我们非常有必要学习下 Envoy 的相关知识,Envoy 代理是唯一的数据面组件,当我们遇到相关问题的时候可以通过分析 Envoy 来定位问题,所以我们需要学习下 Envoy 的相关知识。
文章来源
【优点知识】istio实战训练营
https://youdianzhishi.com/web/course/1047
关于我
我的博客主旨:
- 排版美观,语言精炼;
- 文档即手册,步骤明细,拒绝埋坑,提供源码;
- 本人实战文档都是亲测成功的,各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人帮您解决问题,让我们一起进步!
🍀 微信二维码
x2675263825 (舍得), qq:2675263825。
🍀 微信公众号
《云原生架构师实战》
🍀 个人博客站点
http://onedayxyy.cn/
🍀 csdn
https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421
🍀 知乎
https://www.zhihu.com/people/foryouone
最后
好了,关于本次就到这里了,感谢大家阅读,最后祝大家生活快乐,每天都过的有意义哦,我们下期见!