1 spring cloud 概述
Spring Cloud基于Spring Boot 风格的封装,提供一套完整的微服务解决方案
Spring Cloud 屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、容易部署的分布式系统开发工具包
Spring Cloud包含了:服务注册与发现、配置中心、服务网关、智能路由、负载均衡、断路器、监控跟踪、分布式消息队列等
JAVA技术栈的同学,做微服务架构基本都会选择Spring Cloud
Spring Cloud微服务框架面临的挑战:
1、过于绑定特定技术栈
2、代码侵入度过高
3、多语言支持受限
2 Spring Cloud 架构分析
一个典型的Spring Cloud架构体系,如图所示:
从上图经过分析,我们可以汇总得知它主要由以下几部分组成:
1)代理 &网关: 提供统一对外或对内的访问入口,包括路由、鉴权、限流、熔断、降级等统一处理
2)注册中心: 提供服务的注册与发现功能
3)应用服务: 覆盖整个业务服务,包括业务逻辑实现、框架 SDK 及外部组件依赖交互等
4)中间件 &数据存储: 为应用服务提供额外的支持能力
5)CI&CD: 持续集成、持续部署
3 Spring Cloud不维护什么
1)注册配置维护
Spring Cloud微服务框架中,Eureka,consul,nacos等服务注册组件,是标准的注册中心解决方案。即 Service provider(服务提供者)
将自己的服务地址注册于 eureka /consul/nacos中,供 Service consumer(服务消费者)
远程调用。这种服务注册与发现的机制,是微服务架构中为了将原来的一站式服务拆解为若干个独立的服务并相互解耦,却又能相互交互所设计的。
一种这么灵活的服务注册/发现机制,却不会维护其它服务组件向服务注册组件自身注册这一动作。即eureka /consul/nacos注册的地址,往往是配置在配置文件里。
2)对接各类中间件
一套完整的 Spring Cloud 微服务体系中,必然会采用多种数据中间件,这类中间件的对接方式也是通过配置文件配置的
3)组件启动顺序
Spring Cloud 微服务组件的启动顺序是比较重要的,一个组件在所依赖的服务没有启动前自行启动,是可能引起错误的。Spring Cloud 微服务框架本身不会维护服务组件的启动顺序
4 Service Mesh解决什么问题
首先简单描述下传统微服务架构的痛点:
1)SDK 升级维护成本高,由于 SDK 耦合在业务进程中,那每次 SDK 升级必然需要绑定业务一起升级
2)多语言框架 SDK 维护成本高,SDK 意味着和语言绑定
3)没有统一微服务策略控制,各种治理能力控制比较分散
4)引入额外组件带来的运营开销,如注册中心
概括起来,Service Mesh 的功能主要体现在以下4个方面:
1)可见性: 运行时指标遥测、分布式跟踪
2)可管理性: 服务发现、负载均衡、运行时动态路由等
3)健壮性: 超时、重试、熔断等弹性能力
4)安全性: 服务间访问控制、TLS
加密通信
Service Mesh主要解决用户如下3个维度的痛点需求:
1)完善的微服务基础设施
通过将微服务通信下沉到基础设施层,屏蔽了微服务处理各种通信问题的复杂度,形成微服务之间的抽象协议层。
开发者无需关心通信层的具体实现,也无需关注RPC
通信(包含服务发现、负载均衡、流量调度、流量降级、监控统计等)的一切细节,真正像本地调用一样使用微服务
2)语言无关的通信和链路治理
改变的是通信和服务治理能力提供的方式,通过将这些能力实现从各语言业务实现中解耦,下沉到基础设施层面,
以一种更加通用和标准化的方式提供,屏蔽不同语言、不同平台的差异性,
3)通信和服务治理的标准化
Service Mesh是标准化、体系化、无侵入的分布式治理平台
通过标准化,带来一致的服务治理体验,减少多业务之间由于服务治理标准不一致带来的沟通和转换成本,提升全局服务治理的效率
5 为什么会存在把Spring Cloud体系的应用迁移到Service Mesh
除去容器化是趋势或者未来外,Spring Cloud架构的功能和Service Mesh也有重叠,对比如下:
功能列表
|
Spring Cloud
|
Service Mesh/Istio
|
---|---|---|
服务注册与发现支持 | 基于Eureka,consul,nacos等组件,提供server和Client管理支持 | 基于XDS接口获取服务信息,并依赖virtual service实现服务发现 |
链路监控支持 | 基于Zikpin或者Pinpoint或者Skywalking实现支持 | 基于sideCar代理模型,记录网络请求信息实现 |
API网关支持 | 基于zuul或者spring-cloud-gateway实现支持 | 基于Ingress gateway以及egress实现 |
熔断器支持 | 基于Hystrix实现支持 | 基于声明配置文件,最终转化成路由规则实现 |
服务路由支持 | 基于网关层实现路由转发支持 | 基于iptables规则实现 |
安全策略支持 | 基于spring-security组件实现,包括认证,鉴权等,支持通信加密支持 | 基于RBAC的权限模型,依赖Kubernetes实现,同时支持通信加密 |
配置中心支持 | springcloud-config组件实现 | 不支持 |
性能监控支持 | 基于Spring cloud提供的监控组件收集数据,对接第三方的监控数据存储支持 | 基于SideCar代理,记录服务调用性能数据,并通过metrics adapter,导入第三方数据监控工具 |
日志收集支持 | 提供client,对接第三方日志系统 | 基于SideCar代理,记录日志信息,并通过log adapter,导入第三方日志系统 |
工具客户端集成支持 | 提供消息,总线,部署管道,数据处理等多种工具客户端SDK | 不支持 |
分布式事务支持 | 支持不同的分布式事务模式:JTA,TCC,SAGA等,并且提供实现的SDK框架 | 不支持 |
分析下来,可以替换的组件包括:
1)网关(gateway 或者 Zuul,由Ingress gateway 或者 egress 替换)
2)熔断器(hystrix,由SideCar替换)
3)注册中心(Eureka及Eureka client,由Polit,SideCar 替换)
4)负责均衡(Ribbon,由SideCar 替换)
5)链路跟踪及其客户端(Pinpoint 及 Pinpoint client,由 SideCar 及Mixer替换)
Spring Cloud在非k8s生态与k8s的生态对比
6 Spring Cloud向Service Mesh框架迁移
6.1 迁移原则
在实施迁移时,建议遵守以下迁移原则:
1)渐进式迁移: 为了避免 Service Mesh
迁移过程中的风险,必须采用渐进式迁移原则,每次只迁移少量服务,待迁移后观察足够长的时间,没有问题后再继续迁移
2)业务透明: 为减少 Service Mesh
迁移对业务的影响,减少业务的迁移阻力,迁移初期必须确保业务完全透明且不需要过多的变更和修改
3)兼容性: 在迁移阶段,必然会存在两种模式( Spring Cloud
和 Service Mesh
框架)并存,至少能够满足未迁移和已迁移部分能够通信
6.2基础改造
1)容器化:sprint cloud服务容器化改造,以便于在k8s上部署
2)服务资源及编排:了解sprint cloud服务在k8s是运行是使用什么资源,如:Deployment来部署您的微服务,Service来暴露您的微服务,Ingress来将请求路由到相应的Service
3)配置管路:k8s一般使用ConfigMap和Secret来管理配置和敏感信息
4)日志:配置日志的输出等级及路径,方便平台将日志采集到中心日志存储
5)监控:通过meitric的方式将服务的指标暴露,方便Prometheus等监控工具监控服务的监控状况
6.3 重叠功能改造
Spring Cloud 作为当下主流的微服务框架,在功能层面为服务治理定义了智能路由、熔断机制、服务注册与发现等一系列的标准,并提供了对应的库和组件来实现这些标准特性。
从上文第五章节的分析,Spring Cloud架构的功能和Service Mesh存在大量重叠功能,需将Spring Cloud
与 Istio
中重叠功能去除,缺失功能保留,理论上可轻松去重。
对于 Spring Cloud
而言,这些重叠功能大部分只需去除 pom.xml
中依赖包、相关配置及代码中注解即可轻松完成,剩余一个相对干净的应用
6.3.1 去注册中心
去掉原有nacos/Eureka注册中心,改用 Spring Cloud Kubernetes 项目下的 Discovery。
Spring Cloud 官方推出的项目 Spring Cloud Kubernetes 提供了通用的接口来调用 Kubernetes 服务,让 Spring Cloud 和 Spring Boot 程序能够在 Kubernetes 环境中更好运行;
以eurake/nacos为例,https://cloud.spring.io/spring-cloud-static/spring-cloud-kubernetes/1.1.3.RELEASE/reference/html/#discoveryclient-for-kubernetes
来替换eurake/nacos,
也就是直接将原来的 eurake /nacos项目删掉,在以前的 eurake /nacos客户端的项目中换成下面这个引用:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-kubernetes</artifactId> </dependency> |
6.3.2 加入kubernetes的负载均衡器
改用 Spring Cloud Kubernetes Ribbon(其他亦可)。Ribbon 负载均衡模式有 Service / Pod 两种,在 Service 模式下,可以使用 Kubernetes 原生负载均衡,并通过 Istio 实现服务治理
项目中负载均衡替换下面这个引用:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-kubernetes-ribbon</artifactId> </dependency> |
6.3.3 替换配置中心
也可以根据自己的需要将配置中心换在k8s的configmap
分布式配置 Config 统一为 Apollo(DAS平台提供分布式配置功能)
为了配置文件方便追溯,有需要的自行替换,如果要进行替换的话,那么原项目中的config-server也就不需要了
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-kubernetes-config</artifactId> </dependency> |
6.3.4 网关边缘化
网关作为原来的入口,全部去除需要对原有代码进行大规模的改造;
我们把原有的网关作为微服务部署在 Kubernetes 内,并利用 Istio 来管理流量入口。
同时,我们还去掉了熔断器和智能路由,整体基于 Istio 实现服务治理
6.4 兼容性设计
一种思路是通过增加一个间接的中间层来实现:存量应用和迁移完成的 Service Mesh
应用依然能保持业务上的互通
基于Service Mesh
的控制平面,通过自定义控制插件(WASM
)将 Spring Cloud
框架中原有注册中心的功能纳入进来,由控制平面提供原有服务注册与发现的能力,并结合 Istio
中入口网关 Ingress
和 ServiceEntry
资源配置,以实现服务间互通,统一治理,整个实现逻辑架构如下图所示:
特别说明:自定义控制插件未落地,目前建议应用全部迁移后再引流
6.5 sidecar注入
将应用服务部署到网格时,将 Sidecar
注入到应用服务中去,以实现网格的代理
参考文档
https://istio.io/latest/docs/concepts/what-is-istio/
https://www.cnblogs.com/mrhelloworld/p/springcloud.html
https://developer.aliyun.com/article/870333