浅谈服务治理、微服务与Service Mesh(二) Spring Cloud从入门到精通到放弃【转载】
作为本系列文章的第二篇(第一篇链接请戳:浅谈服务治理、微服务与Service Mesh(一)Dubbo的前世今生),本文主要为大家介绍下微服务概念中非常火热的Spring Cloud开发框架。由于网上关于Spring Cloud的文章多如牛毛,为了让大家阅读后能有不一样的收获,因此本文将用一个相对轻松的叙述方式来为大家讲解一下Spring Cloud框架和微服务。虽然不可能通过一篇文章让大家对Spring Cloud做到从“入门到精通到放弃”,但是希望大家通过阅读本文能对Spring Cloud和微服务有一个更加清晰的认识和了解,为后面学习Service Mesh做好一个铺垫。
Spring Cloud 之“出身名门望族”
作为当下最火热的微服务框架,Spring Cloud的名字可以说是无人不知、无人不晓,凭借之前Spring Framework的良好群众基础和Cloud这个具有时代感的名字,Spring Cloud一出现便被大家认知。
提到Spring Cloud,便会让人想起刚刚发布了2.0版本的Spring Boot。Spring Boot和Spring Cloud都是出自Pivotal公司,Spring Boot和Spring Cloud虽然火热,但是了解Pivotal公司的人在国内却是不多。实际上Pivotal公司在云计算、大数据、虚拟化等领域都有所建树,这里先给大家简单八卦下Pivotal的情况。
Pivotal公司是由EMC和VMware联合成立的一家公司,GE(通用电气)也对Pivotal进行了股权收购,同时GE也是Pivotal的一个重要大客户。除了Spring Framework、Spring Boot和Spring Cloud之外,我们日常开发中经常使用的Reids、RabbitMQ、Greenplum、Gemfire、Cloud Foundry等,目前都是归属于Pivotal公司的产品。其中Gemfire也是被中国铁路总公司12306使用的分布式内存数据库,也就是说你过年回家买不到火车票,这个锅Pivotal的Gemfire也会跟着一起背(开个小玩笑,哈哈)。
Spring Cloud 之“入门”
Spring Cloud作为一个微服务的开发框架,其包括了很多的组件,包括:Spring Cloud Netflix(Eureka、Hystrix、Zuul、Archaius)、Spring Cloud Config、Spring Cloud Bus、Spring Cloud Cluster、Spring Cloud Consul、Spring Cloud Security、Spring Cloud Sleuth、Spring Cloud Data Flow、Spring Cloud Stream、Spring Cloud Task、Spring Cloud ZooKeeper、Spring Cloud Connectors、Spring Cloud Starters、Spring Cloud CLI等。
在上述组件中,Spring Cloud Netflix是一套微服务的核心框架,由互联网流媒体播放商Netflix开源后并入Spring Cloud大家庭,它提供了的微服务最基础的功能:服务发现(Service Discovery)、动态路由(Dynamic Routing)、负载均衡(Load Balancing)和边缘服务器(Edge Server)等。
Spring Boot是Spring的一套快速配置脚手架,可以基于Spring Boot快速开发单个微服务。Spring Boot简化了基于Spring的应用开发,通过少量的代码就能创建一个独立的、生产级别的Spring应用。由于Spring Cloud是基于Spring Boot进行的开发,因此使用Spring Cloud就必须使用到Spring Boot。
下图是一个常见的关于Spring Cloud的架构图。下面此图为例,对Spring Cloud最常用的几个组件做一个简单的介绍:
- Eureka:服务注册中心,一个基于REST的服务,用于定位服务,以实现微服务架构中服务发现和故障转移。
- Hystrix:熔断器,容错管理工具,旨在通过熔断机制控制服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。
- Turbine:Turbine是聚合服务器发送事件流数据的一个工具,用来监控集群下Hystrix的Metrics情况。
- Zuul:API网关,Zuul是在微服务中提供动态路由、监控、弹性、安全等边缘服务的框架。
- Ribbon:提供微服务中的负载均衡功能,有多种负载均衡策略可供选择,可配合服务发现和断路器使用。
- Feign:Feign是一种声明式、模板化的HTTP客户端。
- Spring Cloud Config:配置管理工具包,让你可以把配置放到远程服务器,集中化管理集群配置,目前支持本地存储、Git以及Subversion。
- Spring Cloud Security:基于Spring Security的安全工具包,为微服务的应用程序添加安全控制。
- Spring Cloud Sleuth:日志收集工具包,封装了Dapper和log-based追踪以及Zipkin和HTrace操作,为SpringCloud应用实现了一种分布式追踪解决方案。
除了上面介绍的基础组件外,常见的Spring Cloud组件还有非常多种,涉及到了微服务以及应用开发的方方面面:
- Spring Cloud Starters:Spring Boot式的启动项目,为Spring Cloud提供开箱即用的依赖管理。
- Archaius:配置管理API,包含一系列配置管理API,提供动态类型化属性、线程安全配置操作、轮询框架、回调机制等功能。
- Consul:封装了Consul操作,Consul是一个服务发现与配置工具,与Docker容器可以无缝集成。
- Spring Cloud Stream:数据流操作开发包,封装了与Redis,Rabbit、Kafka等发送接收消息。
- Spring Cloud CLI:基于 Spring Boot CLI,可以让你以命令行方式快速建立云组件。
- Spring Cloud Task:提供云端计划任务管理、任务调度。
- Spring Cloud Bus:事件、消息总线,用于在集群(例如,配置变化事件)中传播状态变化,可与 Spring Cloud Config 联合实现热部署。
- Spring Cloud Data Flow:大数据操作工具,作为Spring XD的替代产品,它是一个混合计算模型,结合了流数据与批量数据的处理方式。
- Spring Cloud ZooKeeper:操作ZooKeeper的工具包,用于使用ZooKeeper方式的服务发现和配置管理。
- Spring Cloud Connectors:便于云端应用程序在各种PaaS平台连接到后端,如:数据库和消息代理服务。
Spring Cloud之“精通”
Spring Cloud虽然集成了众多组件,可以构建一个完整的微服务应用,但是其中的各个组件却并非完美无缺,很多组件在实际应用中都存在诸多不足和缺陷。因此,需要我们对其中的一些组件进行替换和修改,方能构建一个强大、灵活、健壮的微服务架构应用。
配置中心
Spring Cloud Config可以说是Spring Cloud家族中实现最Low的一个组件,直接采用了本地存储/SVN/Git的方式进行存储。同时,Spring Cloud Config也缺乏一个完整的可视化管理查询后台,当存在比较复杂的权限管理和版本管理需求时,Spring Cloud Config会显得非常力不从心。如果需要在配置修改后,能自动进行配置信息推送的话,使用Spring Cloud Config也无法满足要求,需要自行编写代码进行实现。
目前开源社区中,已经有了很多的开源配置中心实现方案,同时很多公司也自研了自己的配置中心方案。包括淘宝的统一配置中心Diamond(已经多年未更新)、百度的分布式配置管理平台Disconf、携程的开源分布式配置中心Apollo、360的分布式配置管理工具QConf等等。目前,笔者公司采用的是自己公司自研的配置中心,没有采用开源实现的主要原因是因为需要同时适配Spring Cloud和Dubbo等多种场景的应用。
注册中心
作为Spring Cloud的服务注册中心,从分布式CAP理论来看,Eureka采用是AP型设计,强调的是注册中心的高可用性。和Dubbo常用的服务注册中心ZooKeeper相比,ZooKeeper则是采用的CP型设计,强调的是注册中心数据的一致性。
Eureka的设计确实简单易用,但是默认没有实现对注册中心数据的持久化。同时,在极端场景下,也会出现多个Eureka注册中心节点数据不一致,甚至服务注册数据丢失的情况。当然,从分布式CAP理论来看,理论上是没办法做到同时兼顾CAP三点的。目前也有一些互联网公司对Eureka进行了改造,支持了数据的持久化,但是尚不能完整的支持CAP的全部要求。
API网关
API网关可以说是微服务需求最多,也是最有难点的一个组件。Spring Cloud中集成的Zuul应该说更多的是实现了服务的路由功能,对于负载均衡等其他功能,需要结合Ribbon等组件来实现。对于很多个性化的需求,需要开发者自己来进行编码实现。
和大部分基于Java的Web应用类似,Zuul也采用了Servlet架构,因此Zuul处理每个请求的方式是针对每个请求是用一个线程来处理。同时,由于Zuul是基于JVM的实现,因此性能也会在高并发访问场景下成为瓶颈。虽然网上一些文章评测Zuul和Nginx性能接近,但是在性能要求较高的场景下,JVM的内存管理和垃圾回收问题,仍然是一个很大的问题。所以在实际的应用场景中,通常会采用在多个Zuul几点前面再添加一层Nginx或者OpenResty来进行代理。
为了解决Zuul的性能问题,Netflix将自己的网关服务Zuul进行了升级,新的Zuul 2将HTTP请求的处理方式从同步变成了异步,并且新增诸如HTTP/2、websocket等功能。但是遗憾的是,开源版本的Zuul 2一直处于难产状态中,始终没有和大家正式见面。
熔断器
微服务中对于服务的限流、降级、熔断的需求是多种多样的,需要在API网关和各个具体服务接口中分别进行控制,才能满足复杂场景下微服务架构的应用需求。
单独使用Spring Cloud中的Hystrix无法完整的满足上述的复杂需求,需要结合API网关,并通过Kubernetes对资源、进程和命名空间来提供隔离,并通过部分自定义编码方能实现对全部服务的限流、降级、熔断等需求。
监控系统
无论是Spring Cloud中集成的Spring Cloud Sleuth,还是集成经典的ELK,都只是对日志级别的追踪和监控。在大中型微服务应用架构中,尤其是基于JVM的项目,还需要添加APM的监控机制,才能保证及时发现各种潜在的性能问题。
APM整体上主要完成3点功能:1.日志追踪、2.监控报警、3.性能统计。目前,国内外商业版本的APM方案已经有很多,开源版本的APM方案也开始丰富起来。国内开源的APM方案主要有:大众点评的CAT和Apache孵化中的SkyWalking。这里给大家重点推荐下SkyWalking,SkyWalking是针对分布式系统的应用性能监控系统,特别针对微服务、Cloud Native和容器化(Docker、Kubernetes、Mesos)架构,项目的关注度和发展速度都很快,中文文档资料也比较齐全。
Spring Cloud之“放弃”
Spring Cloud可以说是一个完美的微服务入门框架,如果你是在一个中小型项目中应用Spring Cloud,那么你不需要太多的改造和适配,就可以实现微服务的基本功能。但是如果是在大型项目中实践微服务,可能会发现需要处理的问题还是比较多,尤其是项目中老代码比较多,没办法全部直接升级到Spring Boot框架下开发的话,你会非常希望能有一个侵入性更低的方案来实施微服务架构。在这种场景下,Service Mesh将会成为你的最佳选择,经过一段时间的发展,目前Service Mesh这个概念已经开始逐步被大家了解和认知。同时,一些Service Mesh的实现方案也逐步成熟和落地,例如Istio、Linkerd、Envoy等。在本系列文章的下一篇中,将为大家对Service Mesh概念做一个系统的介绍。但是在了解Service Mesh概念之前,还是建议大家先对微服务和Spring Cloud这些概念和框架有一个深入的了解,这样才能体会到应用Service Mesh的价值和意义。
Spring Cloud与Dubbo
网上关于Spring Cloud和Dubbo对比的文章很多,大多数对比结果都是Spring Cloud压倒性优势战胜Dubbo,下表是对Dubbo和Spring Cloud做的一个基础功能的对比:
实际上,Dubbo的关注点在于服务治理,并不能算是一个真正的微服务框架。包括目前在开发中的Dubbo 3.0,也不能完整覆盖微服务的各项功能需求。而Spring Cloud一方面是针对微服务而设计,另外一方面Spring Cloud是通过集成各种组件的方式来实现微服务,因此理论上可以集成目前业内的绝大多数的微服务相关组件,从而实现微服务的全部功能。
而对Dubbo而言,如果一定要应用到微服务的使用场景中的话,上表中欠缺的大多数功能都可以通过集成第三方应用和组件的方式来实现,跟Spring Cloud相比主要的缺陷在于集成过程中的便利性和兼容性等问题。
Spring Cloud与Docker
虽然网上也有很多文章写到如何使用Docker来实现微服务,但是事实上单独使用Docker是没办法完整的实现微服务的所有功能的。在实际上微服务架构中,Spring Cloud和Docker更多的是一种协作的关系,而不是一种竞争的关系。通过Docker容器化技术,可以更好的解决引入Spring Cloud微服务后带来的部署和运维的复杂性。
Spring Cloud生态圈中的Pivotal Cloud Foundry(PCF)作为PaaS实现,也提供一些类似于Docker的功能支持,但是无论上功能上还是易用性上和Docker还是存在比较大的差异。Pivotal Cloud Foundry和Docker之间的关系更多的是一种兼容关系,而不是竞争关系,Pivotal Cloud Foundry的主要竞争对手是Red Hat的OpenShift。目前,Pivotal Cloud Foundry支持的IaaS包括:AWS、AZURE、GCP、vSphere、OpenStack等。
Spring Cloud与Kubernetes
网上也有一些“Spring Cloud与Kubernetes哪个更好”,“当已经有了Kubernetes之后,还需要使用Spring Cloud么”之类的文章。首先说笔者并不认为Spring Cloud与Kubernetes是竞争关系,但是也不否认二者确实在诸多功能上存在一些重合。下图是对Spring Cloud与Kubernetes在微服务架构中的一些基础功能上的对比:
通过对比可以看出,Spring Cloud和Kubernetes确实存在一些功能上的重合,但是二者的定位其实差别很大。Spring Cloud是一个基于Java语言的微服务开发框架,而Kubernetes是一个针对容器应用的自动化部署、伸缩和管理的开源系统,它兼容多种语言且提供了创建、运行、伸缩以及管理分布式系统的原语。Spring Cloud更多的是面向有Spring开发经验的Java语言开发者,而Kubernetes不是一个针对开发者的平台,它的目的是供有DevOps思想的IT人员使用。
为了区分Spring Cloud和Kubernetes两个项目的范围,下面这张图列出了几乎是端到端的微服务架构需求,从最底层的硬件,到最上层的DevOps和自服务经验,并且列出了如何关联到Spring Cloud和Kubernetes平台。
总结
通过Spring Cloud、Docker和Kubernetes的组合,可以构建更加完整和强大的微服务架构程序。通过三者的整合,使用Spring Boot提供应用的打包,Docker和Kubernetes提供应用的部署和调度。Spring Cloud通过Hystrix线程池提供应用内的隔离,而Kubernetes通过资源、进程和命名空间来提供隔离。Spring Cloud为每个微服务提供健康终端,而Kubernetes执行健康检查,且把流量导到健康服务。Spring Cloud外部化配置并更新它们,而Kubernetes分发配置到每个微服务。
对于一名开发人员或者架构师来说,想要精通微服务设计与开发,能够在大中型项目中应用微服务架构,单纯掌握Spring Cloud是远远不够的,Docker和Kubernetes等都是需要学习和掌握的内容。同时,由于采用微服务架构后带来了分布式的相关问题,对于分布式系统理论也必须有一定的了解。当然,最重要的还是对系统业务的深入理解,对整体业务进行合理的规划和拆分,才能真正行之有效的应用微服务架构,构建高效、健壮、灵活、可扩展的微服务应用。