当前位置: 首页 > 科技观察

拥抱Kubernetes,再见SpringCloud

时间:2023-03-19 21:16:08 科技观察

相信很多Java从业者在熟悉了微服务开发之后,都认为自己已经用SpringCloud成功打造了一个微服务架构帝国,Java已经垄断了微服务领域。然而,在引入k8s之后,SpringCloud已经脱离了CloudNative的生态发展。从SpringBoot2013到2012年10月,MikeYoungstrom在Springjira中创建了一个功能请求,要求在SpringFramework中支持无容器Web应用程序架构。他建议在通过main方法引导的Spring容器中配置Web容器服务。这种需求导致2013年初启动了SpringBoot项目,2014年4月发布了SpringBoot1.0.0。从那时起,出现了一些SpringBoot次要版本。SpringBoot1.1(2014年6月):改进了模板支持、gemfire支持、elasticsearch和apachesolr的自动配置Springboot1.2(2015年3月):升级到servlet3.1/tomcat8/jetty9和spring4.1,支持banner/jms/SpringBootApplicationannotationsSpringboot1.3(2016年12月):升级到spring4.2,新的spring-boot-devtools,自动配置缓存技术(ehcache,hazelcast,redis,guava和infinispan)和完全可用执行的jar支持Springboot1.4(2017年1月):升级到spring4.3,couchbase/neo4j支持,启动失败分析和RestTemplateBuilderSpringboot1.5(2017年2月):支持kafka/ldap,第三方库升级,放弃对CRaSH和executorlogendpoints的支持动态修改应用程序日志级别SpringBoot的简单性使Java开发人员能够快速扩展项目。SpringBoot可以说是用Java开发基于RESTful微服务的Web应用程序最快的方法之一。也非常适合docker容器部署和快速原型制作SpringBoot2.0.0,2018年3月1日发布,新版本特性:基于Java8,支持Java9;支持石英调度器;支持嵌入式Netty,Tomcat,Undertow和Jetty已经支持HTTP/2;Actuator架构重构,支持SpringMVC、WebFlux和Jersey;为响应式编程提供最大限度的支持;引入对Kotlin1.2.x的支持,并提供一个runApplication函数,使用Kotlin常用的方式启动一个SpringBoot应用。直到SpringCloud,第一批选择它的大公司很早就构建了完整的微服务生态,很多解决方案也开源了,很多坑都被国内巨头踩过,所以还是比较稳定的。对于很多想要使用微服务架构的中小企业来说,这绝对是最好的切入时机。直接使用SpringCloud全家桶,绝对是微服务架构稳定且正确的选择。但是当你的公司引入k8s时,事情就变了。k8s与SpringCloud的激烈冲突Java生态的SpringCloud可谓是迄今为止最完善的微服务框架,基本满足了微服务架构的所有要求,网上的教程太多了。但是也因为SpringCloud生态太完整了,现在流行k8s,当我们把基于SpringCloud开发的服务放到k8s里面的时候,有些机制是不受k8s生态控制的。因为k8s从扩展部署和运维的角度,基于最原始的容器,应用部署和网络层管理,已经逐步实现并贴近应用层的需求,微服务架构下的一些基本需求(如如:ServiceDiscovery、APIGateway等)开始直接或间接融入k8s生态。导致两边的组件功能重叠很多,只能二选一。比如一旦选择了SpringCloud方案,就不得不放弃k8s机制。SpringCloud官方提供的解决方案针对这个问题,官方在Github上提供了一个开源的解决方案,讲解了如何将Kubernetes生态中的组件与SpringCloud集成,主要讨论了从原有的组件架构到Kubernetes原生环境的过渡。https://github.com/spring-cloud/spring-cloud-kubernetes本方案重点如下:服务发现(ServiceDiscovery)SpringCloud的经典方案:NetflixEureka、阿里巴巴Nacos。主要原理是在服务部署的时候注册自己的服务,这样其他的服务就可以找回自己。spring.cloud.service-registry.auto-registration.enabled@EnableDiscoveryClient(autoRegister=false)但在k8s中,服务注册和查询由Service组件负责,其连接名称是使用内部DNS实现的。这意味着我们需要将服务发现功能连接到k8s的服务机制上。为实现该目的,方案中提供了DiscoveryClient组件,使得基于SpringCloud开发的程序可以方便地查询其他服务。只有使用了Kubernetes的原生服务发现,才能被Istio跟踪,并纳入到ServiceMesh的管控中。配置管理(ConfigurationManagement)SpringCloud的解决方案:spring-cloud-config。但在Kubernetes上,有可用的ConfigMaps和Secrets,并且通常与Vault搭配使用来管理敏感配置。该方案提供了ConfigMapPropertySource和SecretsPropertySource来访问Kubernetes上的ConfigMap和Secret。负载均衡&断路器(LoadBalancing&CircuitBreaker)SpringCloud最初的解决方案:NetflixRibbon和Hystrix,但是在k8s中有一个Service来实现负载均衡,Istio可以实现断路器。开发人员只需要关注crud。由于负载均衡和断路器依赖于服务发现机制,因此Ribbon和Hytrix原有的功能在k8s原生环境下失效。虽然解决方案中有提到Ribbon集成Kubernetes原生环境的实现,但是相关链接已经消失,应该放弃。所以建议避免使用客户端负载均衡和断路器。SpringCloudV.Sk8s重叠方案当然我们可以完全忽略k8s原生组件,完全采用SpringBoot和SpringCloud方案,只使用k8s作为部署应用的工具和平台。但是很明显,未来ServiceMesh及其通用的CloudNative技术的发展会脱离SpringCloud,不再与我们的应用深度融合。相对于只能使用Java的SpringCloud生态,k8s生态的开发设计更加通用和广泛。SpringCloud中的一些组件功能,除了包括Kubernetes中的支持外,甚至还有更多的集成、考虑和扩展功能。由于CNCF的推动和更多国际厂商的投资,新的工具、运维方式、集成能力层出不穷。因此,在选择微服务架构时,需要将k8s的各种原生方案纳入评估考量。目前网上很多SpringBoot和SpringCloud已经过时,并没有集成k8s。与目前主流的基础设施环境有差距,学习时一定要考虑。