Spring Cloud和Kubernetes + Spring Boot都是用于构建微服务架构的解决方案,它们各有优势和不足,选择哪个更好取决于你的具体需求和上下文。
Spring Cloud是一个基于Spring Boot的微服务开发框架,它提供了一套完整的微服务解决方案,包括服务注册与发现、负载均衡、熔断、智能路由等。Spring Cloud与Spring Boot集成良好,可以快速构建出生产级别的微服务应用。
Kubernetes是一个开源的容器编排引擎,它可以自动化容器的部署、扩展和管理。Kubernetes提供了一种抽象层,使得开发者可以忽略底层Docker容器引擎的具体实现细节,专注于应用的开发和部署。Spring Boot则是一个用于快速创建Spring应用的开发框架,它简化了应用的配置和部署。
对于选择哪个更好,以下是一些考虑因素:
- 技术栈:如果你已经使用了Spring框架,那么Spring Cloud和Kubernetes + Spring Boot都是不错的选择。如果你更倾向于使用其他技术栈,那么可能需要考虑其他解决方案。
- 复杂度:Spring Cloud提供了一套完整的微服务解决方案,但是相对来说也更加复杂一些。Kubernetes + Spring Boot则需要自己搭建一些基础设施,但是相对来说更加灵活和自由。
- 运维能力:如果你有一个强大的运维团队,那么Kubernetes + Spring Boot可能更适合你,因为它们提供了更多的自定义和配置选项。如果你的运维能力相对较弱,那么Spring Cloud可能更适合你,因为它提供了一套更加完整的解决方案。
综上所述,选择Spring Cloud还是Kubernetes + Spring Boot取决于你的具体需求和上下文。建议你可以先了解它们各自的优势和不足,然后结合自己的实际情况做出决策。
参考:构建微服务技术中台,SpringCloud和Kubernetes该如何选型? (xjx100.cn)
SpringCloud和K8s,分别是Netflix和谷歌,针对微服务公共关注点给出的解,只不过它们两家的解法和侧重点有所不同。这里有两个表,通过这两个表,我们对SpringCloud vs K8s所支持的功能点,做一个全面的横向比对:
- 服务发现和LB:服务发现和LB是微服务基本问题,两家都给出了解决方案。SpringCloud的服务发现主要引用Netflix的Eureka,配合使用Ribbon实现客户端发现和软负载。K8s则直接在平台层解决这个问题,它直接在平台中引入了Service这个抽象概念,屏蔽了底层服务发现和负载均衡细节,让应用开发和服务框架都不需要关心这层细节。
- API网关:这层SpringCloud主要引用Netflix的Zuul网关,它是经过Netflix大流量考验的一个成熟产品。在K8s体系中,和网关对应的概念叫Ingress,它定义了一些规范,具体可以采用各种实现,例如Nginx、Envoy或者Traefik等,都可以做Ingress。
- 配置管理:这块SpringCloud有Spring Cloud Config对应产品,实现比较简单,后端基于git进行配置管理。K8s则在平台层内置支持ConfigMaps/Secrets等配置机制,配置可以通过环境变量注入容器中,也可以挂载到容器文件系统中。
- 限流容错:这块SpringCloud支持Netflix开源的Hystrix容错限流组件,Hystrix在Netflix平台稳定性方面发挥了巨大作用,它已经成为业界限流熔断的一个标配。K8s平台内置支持健康检查(HealthCheck),启动就绪探针(Probe)等容错机制,如果需要细粒度流量控制,则需要引入ServiceMesh机制进行配合。
- 日志监控:这块两者都没有单独的开源产品,不过社区已经有ELK(Elasticsearch/Logstash/Kibana)这样的成熟标配解决方案,两者都可以直接集成。K8s推荐使用Fluentd进行日志采集。
- Metrics监控:SpringCloud支持MicroMeter/Actuator等机制,可以采集和暴露Metrics指标,方便对接Prometheus等监控告警系统。K8s内置支持MetricServer,可以采集K8s平台内部资源性能指标,方便对接Promethues,如果要进一步监控应用层性能指标,可以引入ServiceMesh配合支持。
- 调用链监控:这块SpringCloud提供Spring Cloud Sleuth,支持对接Zipkin调用链监控。K8s推荐采用Uber开源的Jaeger进行调用链监控,也可以使用Zipkin。
- 应用打包:SpringCloud支持嵌入式容器+Uber Jar方式打包,方便应用发布和运行。K8s则直接支持容器镜像部署,它不关心容器内部的具体应用形式。K8s还支持Helm这样的应用级打包标准,可以实现应用商店。
- 服务框架:Spring本质上是一种HTTP/REST框架,比较松散简单,开发测试都友好。K8s是一个平台,它是具体框架无关的,它只认容器,不同语言栈(Java/Go/Python/Node/Ruby等等)的各种框架都可以住在K8s里头。具体语言栈无关是K8s区别于其它服务框架的最大亮点。
- 发布和调度:这块SpringCloud没有单独考虑,而是交由运维去解决。K8s平台本身重点解决的问题就是服务发布和容器调度。
- 自动伸缩和自愈:这块SpringCloud没有单独考虑,而是交由运维去解决。K8s具备自动故障检测和自愈的能力,自动伸缩需要引入额外组件,完全实现有一定的技术门槛。
- 进程隔离:这块SpringCloud没有单独考虑。K8s通过容器进行进程隔离,同时还引入了Pod进一步对服务进行隔离。
- 环境管理:这块SpringCloud没有单独考虑。K8s内置支持Namespace进行逻辑隔离,可以实现多环境,各个环境可以单独配置认证授权机制。
- 资源配额:这块SpringCloud没有单独考虑。K8s支持对CPU/Memory进行使用量限制,也支持Namespace级别的配额管理。
- 流量治理:主要指高级流量调度,A/B和蓝绿部署等能力。这块SpringCloud没有专门方案。K8s则需要引入ServiceMesh配合支持。
Spring Cloud和Kubernetes优劣比对
SpringCloud的不足主要是仅限于JVM语言栈,其它语言栈支持非常有限。另外,SpringBoot因为封装较多,运行起来比较吃资源,尤其是跑在容器里的时候。
SpringCloud仅解决了微服务基础设施的部分问题,而K8s则是一个完整的微服务基础设施解决方案,所以,K8s是构建微服务技术中台的推荐基础方案。
我比较倾向K8s平台+SpringBoot框架,这两个是目前社区的绝对主流,可以用如日中天来形容,K8s是针对微服务公共关注点最完备的解决方案,服务框架我倾向直接用SpringBoot,我不需要SpringCloud那套,因为它支持的功能K8s已经覆盖了很大部分。另外,考虑到K8s技术门槛和运维成本高,对于一般的中小公司,我不倾向自建K8s,而是建议直接采用公有云K8s(例如阿里云K8s),把K8s运维的活外包给阿里云(开发商)。
微服务的关注点:
可以看到,里面差不多一半关注点是和运维相关的。这么看来,似乎拿spring cloud和kubernetes比较有点不公平,spring cloud只是一个开发框架,对于应用如何部署和调度是无能为力的,而kubernetes是一个运维平台。也许用spring cloud+cloud foundry去和kubernetes比较才更加合理,但需要注意的是,即使加入了cloud foundry的paas能力,spring cloud仍然是“侵入式”的且语言相关,而kubernetes是“非侵入式”的且语言无关。
spring cloud关注的功能是kubernetes的一个子集,下面来详细对比一下:
kubernetes这边,在Istio还没出来以前,其实只能提供最基础的服务注册、服务发现能力(service只是一个4层的转发代理),istio出来以后,具有了相对完整的微服务能力。而spring cloud这边,除了发布、调度、自愈这些运维平台的功能,其他的功能也支持的比较全面。相对而言,云厂商会更喜欢kubernetes的方案,原因就是三个字:非侵入。平台能力与应用层的解耦,使得云厂商可以非常方便的升级、维护基础设施而不需要去关心应用的情况,这也是我比较看好service mesh这类技术前景的原因。
Istio主要被设计用来连接、保护、控制、观测服务
连接
主要是定义路由规则,配合virtual service和destination rule实现各种高级路由功能,能够非常细粒度的实现灰度、金丝雀、多版本路由等能力,这块是istio的最大亮点,spring cloud这部分能力完全缺失,没得比。
保护
主要是端到端的mTLS加密、服务间认证授权、终端用户认证授权,这部分Spring Cloud提供了Spring Cloud Security可以实现最终用户认证功能,但Spring Security本质上来讲是在单体应用的背景下设计出来的,运用在分布式系统上有诸多不便(例如Session同步),端到端加密和服务间认证也是没有的。
控制
主要是策略(policy),例如黑白名单、限速等各类控制能力,通过适配器(Adapter)实现,并且可以自定义适配器扩展各类个性化的控制能力。这部分由于需要通过mixer来实现,历来争议很大(Istio最新版本policy功能都是默认关闭的)。Spring Cloud可以通过Hystrix/Resillience4j来实现限速、熔断等方面的功能,理论上说istio的设计是更好的,因为适配器是可以灵活扩展的。可惜mixer的设计问题,现在处于比较尴尬的地位,mixer v2计划把policy做到sidecar里面,大方向是对的,可以期待一下。
观测
主要是遥测(telemetry)。一般我们说的可观测性(Observability),包含Logging、Tracing、Metrics 这三部分,istio也都有解决方案。Logging和Metrics不说了,都是通过envoy收集好以后上报给基础设施后端(也是通过mixer,不过这个是异步的,稍微好一点)。
在目前这个时间节点,对于中小型的技术团队来说,我推荐的组合就如文章标题所说:使用spring boot+kubernetes来实现微服务架构,这是一个比较清爽的搭配。如果是没有历史包袱的,且底层基础设施准备上k8s的技术团队来说,个人认为现在来说已经没有必要使用spring cloud了。毕竟kubernetes已经提供了比较完整的微服务解决方案,何苦再自己搞一套服务注册、服务发现、配置管理的轮子呢(况且还是语言绑定)?
基于spring boot+kubernetes的微服务架构技术选型如下:(仅代表个人观点)
服务注册与服务发现:kube-proxy+coredns
配置管理:ConfigMap
api网关:Ingress(外部网关,位于集群入口,https加密,证书管理,域名管理,限速等)+zuul(内部网关,用于服务转发,并可以开发比较灵活的各类定制化适配器)
metrics监控:prometheus+spring actuator
调用链监控:skywalking
日志收集:EFK
参考:Kubernetes 的istio可以完全替代 Spring Cloud 吗? - 知乎 (zhihu.com)
ServiceMesh是号称可取代SpringCloud的下一代微服务技术。
Spring Cloud是微服务架构的一个解决方案,他的具体实现之一是:Spring Cloud Alibaba
Service Mesh(服务网格)也是微服务架构的一个解决方案,他的具体实现之一是:istio
然后istio是基于k8s的sidecar实现的。
然后这个问题应该是:Serivice Mesh可以完全替代Spring Cloud吗?
作者:烟雨姜囡
链接:https://www.zhihu.com/question/451313635/answer/3164717408
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Kubernetes的Istio和Spring Cloud是两个不同的技术栈,虽然它们都可以用于构建和管理微服务架构,但它们在很多方面有着不同的设计理念和功能。因此,不能简单地说Istio可以完全替代Spring Cloud,而是应该根据具体的需求和情况来选择使用哪个技术。
以下是一些关键的比较点:
1. 范围和用途:
a. Istio是一个服务网格(Service Mesh)平台,用于管理和监控微服务之间的通信,提供流量管理、故障恢复、安全性等功能。
b. Spring Cloud是一个用于构建微服务的开发框架,提供诸如服务发现、负载均衡、配置管理等功能。
2. 功能重点:
a. Istio专注于处理服务之间的通信、安全性和监控等问题,通过Sidecar代理来实现这些功能。
b. Spring Cloud提供了更多的微服务开发支持,包括服务注册与发现、负载均衡、断路器、配置管理等功能。
3. 复杂性:
a. Istio在处理服务通信时可以提供更高级的功能,但也可能增加部署和管理的复杂性。
b. Spring Cloud相对来说更轻量级,适合小到中等规模的微服务应用。
4. 学习曲线:
a. 学习Istio可能需要更多时间,因为它涉及到服务网格的概念和技术。
b. Spring Cloud更接近传统的Java开发模式,可能对已经熟悉Spring框架的开发者更友好。
Istio和Spring Cloud各自有着自己的优势和适用场景。在某些情况下,您可能会发现Istio能够更好地满足需要,特别是当您关注服务通信、流量管理和监控等方面时。而在其他情况下,Spring Cloud可能更适合,特别是对于那些更侧重于开发和构建微服务的项目。最终的选择应该根据您的项目需求、团队技术熟练程度和偏好来做出。
要搭建基于Kubernetes、Istio和Spring Boot的微服务,您可以按照以下步骤进行操作:
- 创建Kubernetes集群:首先,您需要创建一个Kubernetes集群。您可以选择使用托管的Kubernetes服务,如AKS、GKE或Amazon EKS,或者您可以在本地机器上使用如kubeadm、kubespray等工具自行安装。对于本地开发测试,也可以使用Minikube等工具创建单节点集群。
- 安装Istio:在Kubernetes集群上安装Istio。Istio提供了丰富的微服务治理功能,如流量管理、安全性、可观察性等。您可以访问Istio的官方网站,按照其提供的指南进行安装。
- 创建Spring Boot微服务:使用Spring Boot创建您的微服务应用。Spring Boot是一个基于Java的开发框架,用于创建独立的、生产级的Spring基础应用程序。您可以根据业务需求,使用Spring Boot开发您的微服务应用。
- 部署Spring Boot微服务到Kubernetes:在完成了Spring Boot微服务的开发后,您需要将其部署到Kubernetes集群上。您可以使用Kubernetes的kubectl命令行工具,或者通过编写YAML文件来进行部署。
- 配置Istio进行微服务治理:在Spring Boot微服务成功部署到Kubernetes集群后,您可以通过Istio进行微服务的治理。例如,您可以配置Istio的VirtualService和DestinationRule等资源,来实现微服务的路由、负载均衡、熔断、故障注入等功能。
参考:【IstioCon 2021】最佳实践:从Spring Cloud 到 Istio-CSDN博客
微服务SDK曾经是一个常用的解决方案。将微服务化后通用的能力封装在一个开发框架中,开发者使用这个框架开发写自己的业务代码,生成的微服务自然就内置了这些能力。在很长的一段时间内,这种形态是微服务治理的标配,以至于初学者以为只有这些SDK才是微服务。
SDK形态中Spring cloud是最有影响力的代表项目。Spring cloud提供了构建分布式应用的开发工具集,如列表所示。其中被大部分开发者熟知的是微服务相关项目,如:服务注册发现eureka、配置管理 config、负载均衡ribbon、熔断容错Hystrix、调用链埋点sleuth、网关zuul或Spring cloud gateway等项目。
服务网格则通过另一种形态提供治理能力。不同于SDK方式,服务治理的能力在一个独立的代理进程中提供,完全和开发解耦。虽然从图上看两者差异非常小,后面我们将会从架构和实际案例来分析两者在设计理念上的差异,来体会前者是一个开发框架,而后者是一个基础设施。
网格形态中,最有影响力的项目当属Istio。架构上由控制面和数据面组成,控制面管理网格里面的服务和对服务配置的各种规则。数据面上每个服务间的出流量和入流量都会被和服务同POD的数据面代理拦截和执行流量管理的动作。
除了架构外,作为背景的另外一个部分,我们挑两个基础功能稍微打开看下两者的设计和实现上的相同和不同。首先是服务发现和负载均衡。
左边是Spring cloud,所有的微服务都会先注册中心,一般是Eureka进行服务注册,然后在服务访问时,consumer去注册中心进行服务发现得到待访问的目标服务的实例列表,使用客户端负载均衡ribbon选择一个服务实例发起访问。
右边Istio不需要服务注册的过程,只需要从运行平台k8s中获取服务和实例的关系,在服务访问时,数据面代理Envoy拦截到流量,选择一个目标实例发送请求。可以看到都是基于服务发现数据进行客户端负载均衡,差别是服务发现数据来源不同,负载均衡的执行体不同。
左边为经典的Hystrix的状态迁移图。一段时间内实例连续的错误次数超过阈值则进入熔断开启状态,不接受请求;隔离一段时间后,会从熔断状态迁移到半熔断状态,如果正常则进入熔断关闭状态,可以接收请求;如果不正常则还是进入熔断开启状态。
Istio中虽然没有显示的提供这样一个状态图,但是大家熟悉Istio规则和行为应该会发现,Istio中OutlierDection的阈值规则也都是这样设计的。两者的不同是Spring cloud的熔断是在SDK中Hystrix执行,Istio中是数据面proxy执行。Hystrix因为在业务代码中,允许用户通过编程做一些控制。
以上分析可以看到服务发现、负载均衡和熔断,能力和机制都是类似的。如果忽略图上的某些细节,粗的看框图模型都是完全一样的,对比表格中也一般只有一项就是执行位置不同,这一点不同在实际应用中带来非常大的差异。
使用Spring cloud微服务框架遇到的问题
首先,多语言问题。基于服务网格,业务和治理的数据面无需运行在同一个进程里,也无需一起编译,因此也没有语言和框架上的绑定。无论什么语言开发的服务,只要有一个对外可以被访问和管理的一定应用协议上的端口,都可以被网格进行管理。通过统一的网格控制面,下发统一的治理规则给统一的网格数据面执行,进行统一的治理动作,包括前面介绍到的灰度、流量、安全、可观察性等等。
关于Spring cloud服务在Kubernetes运行时,关于原有的服务注册和发现不及时的问题。根本原因是两套服务发现导致的不一致问题,那么解决办法也比较简单,统一服务发现即可。既然K8s已经在Pod调度的同时维护有服务和实例间的数据,那么就没有必要再单独搞一套名字服务的机制,还要费劲的进行服务注册,然后再发现。
比较之前Spring cloud注册发现那张图,注册中心没了,服务基于注册中心的服务注册和服务发现的动作也不需要了,Istio直接使用k8s的服务发现数据,但从架构上看也简洁很多。
我们也总结过,大部分碰到这个问题的场景,都是将微服务框架从VM迁移到k8s时候碰到的,有点把容器当作之前的VM使用,只使用了k8s作为容器部署运行的平台,并没有用到k8s的service。
对于SDK自身升级导致业务全部重新升级的问题,解决办法就是把服务治理的公共能力和业务解耦。在网格中,将治理能力下沉到基础设施后,业务的开发、部署、升级都和服务治理的基础设施解耦了。业务开发者专注自己的业务部分。只要没有修改业务代码,就无需重新编译和上线变更。
当治理能力升级只需基础设施升级即可,基础设施的升级对用户业务完全没有影响。像华为云ASM这样大部分网格服务的服务提供商都能做到一键升级,用户完全感知不到这个过程。
关于渐进微服务化的问题,使用Isito服务网格可以非常完美的解决。Istio治理的是服务间的访问,只要一个服务被其他服务访问,就可以通过Istio来进行管理,不管是微服务还是单体。Istio接管了服务的流量后,单体和微服务都可以接收统一的规则进行统一的管理。
如图中,在微服务化的过程中,可以对某个单体应用svc1根据业务拆分优先进行微服务化,拆分成三个微服务svc11、svc12和svc13,svc1服务依赖的另外一个单体应用svc2不用做任何变更,在网格中运行起来就可以和另外三个微服务一样的被管理。同样在运行一段时间后,svc2服务可以根据自身的业务需要再进行微服务化。从而尽量避免一次大的重构带来的工作量和业务迁移的风险,真正做到马丁富勒倡导的渐进微服务化的实践。
主要是思路是解耦和卸载。卸载原有SDK中非开发的功能,SDK只提供代码框架、应用协议等开发功能。涉及到微服务治理的内容都卸载到基础设施去做。
从图上可以看到开发人员接触到开发框架变薄了,开发人员的学习、使用和维护成本也相应的降低了。而基础设施变得厚重了,除了完成之前需要做的服务运行的基础能力外,还包括非侵入的服务治理能力。即将越来越多的之前认为是业务的能力提炼成通用能力,交给基础设施去做,交给云厂商去做,客户摆脱这些繁琐的非业务的事务,更多的时间和精力投入到业务的创新和开发上。在这种分工下,SDK才真的回归到开发框架的根本职能。
主要的迁移工作在微服务的服务调用方。我们推荐3个步骤:
第一步:废弃原有的微服务注册中心,使用K8S的Service。
第二步:短路SDK中服务发现和负载均衡等逻辑,直接使用k8s的服务名和端口访问目标服务;
第三步:结合自身项目需要,逐步使用网格中的治理能力替换原有SDK中提供的对应功能,当然这步是可选的,如调用链埋点等原有功能使用满足要求,也可以作为应用自身功能保留。
为了达成以上迁移,我们有两种方式,供不同的用户场景采用。
一种是只修改配置的方式:Spring cloud本身除了支持基于Eureka的服务端的服务发现外,还可以给Ribbon配置静态服务实例地址。利用这种机制给对应微服务的后端实例地址中配置服务的Kubernetes服务名和端口。
当Spring cloud框架中还是访问原有的服务端微服务名时,会将请求转发到k8s的服务和端口上。这样访问会被网格数据面拦截,从而走到网格数据面上来。服务发现负载均衡和各种流量规则都可以应用网格的能力。
这种方式其实是用最小的修改将SDK的访问链路和网格数据面的访问链路串接起来。在平台中使用时,可以借助流水线工具辅助,减少直接修改配置文件的工作量和操作错误。可以看到我这个实际项目中,只是修改了项目的application.yaml配置文件,其他代码都是0修改。当然对于基于annotation的方式的配置也是同样的语义修改即可。
另外一种更简单直接的方式,既然原有SDK中服务发现负载均衡包括各种服务治理能力都不需要了,干脆这些依赖也全部干掉。从最终的镜像大小看,整个项目的体量也得到了极大的瘦身。这种方式客户根据自己的实际使用方式,进行各种裁剪,最终大部分是把Spring cloud退化成Spring boot。
迁移中还有另外一部分比较特殊,就是微服务外部访问的Gateway。
Spring cloud 有两种功能类似的Gateway,Zuul和Spring cloud Gateway。基于Eureka的服务发现,将内部微服务映射成外部服务,并且在入口处提供安全、分流等能力。在切换到k8s和Istio上来时,和内部服务一样,将入口各个服务的服务发现迁移到k8s上来。
大多数情况下我们推荐使用Istio的Ingress Gateway直接替换这个微服务网关,以非侵入的方式提供外部TLS终止、限流、流量切分等能力。
Envoy 是开源的边缘和服务代理,用于云原生应用,云原生基金会 CNCF 项目。
控制面上可以配置统一的服务管理规则。数据面上,统一使用Envoy进行服务发现、负载均衡和其他流量、安全、可观察性等相关能力。数据面上的服务即可以运行在容器里,也可以运行在虚机上。并且可以运行在多个k8s集群中。
1)微服务和容器都有轻量和敏捷的共同特点,容器是微服务非常适合的一个运行环境;
2)在云原生场景下,在微服务场景下,容器从来都不是独立存在的,使用k8s来编排容器已经是一个事实标准;
3)Istio和k8s在架构和应用场景上的紧密结合,一起提供了一个端到端的微服务运行和治理的平台。
4)也是我们推荐的方案,使用Istio进行微服务治理正在成为越来越多用户的技术选择。