微服务的构建环境比较--Spring Cloud和Kubernetes

微服务的构建环境比较--Spring Cloud和Kubernetes

背景

Spring Cloud 和 Kubernetes 都声称是开发和运行微服务的最佳环境,但它们本质上有很大不同,并且解决的问题也不尽相同。在本文中,我们将了解两个平台如何帮助搭建基于微服务的架构 (Microservice based architectures, MSA),它们各自擅长的领域,以及如何各取所长以便在微服务之旅中取得成功。

微服务的构建环境比较--Spring Cloud和Kubernetes

 

该图涵盖了系统运行时所涉及的很多方面,但没有涉及在 MSA 世界中非常重要的打包、持续集成、扩展、高可用性、自我修复。我们假定大多数 Java 开发人员都熟悉 Spring Cloud,在本文中,我们将通过分析这些额外的问题来对比看一看, Kubernetes 与 Spring Cloud 有什么区别和关联。

微服务的关注点

与其逐个功能进行比较,不如让我们站在更高的角度来看看,作为微服务应该关注的点, Spring Cloud 和 Kubernetes 又是如何解决这些问题的。 MSA 这种架构风格的优点和所做的取舍,今天已经被大家所熟知。微服务支持强大的模块边界、独立部署和技术多样性(Strong Module Boundaries, Independent Deployment, Technology Diversity),但代价就是需要开发分布式系统(Distribution)、保证最终一致性( Eventual Consistency)以及大量的运维开销(Operational Complexity)。因此,尽可能使用现成的工具是成功的关键因素之一,这些工具可以帮助你尽可能地解决 MSA 问题。采用MSA快速轻松的启动开发很重要,但从项目启动到最终发布的过程是漫长的,你需要做到以下几点才能真正利用好微服务。

  • 基本监控、仪表、健康检查
  • 分布式日志记录、跟踪
  • 针对每个服务,隔离的不只是代码,而是整个构建+测试+打包+推广
  • 可以为每个服务明确定义上游/下游/编译时/运行时的依赖关系
  • 知道如何构建、发布和维护良好的 API 和契约
  • 尊重向后和向前兼容性,就算你即是服务的提供者又是消费者
  • 良好的单元测试技能和准备好做更多的工作(随着微服务的增加,一切都变得更加困难,因此需要更多的单元/契约/api 测试驱动,以及更少的 e2e 驱动)
  • 了解 微服务 vs 模块 vs 库、分布式单体应用、协调发布、数据库驱动集成等
  • 了解基础设施自动化(这里需要了解更多)
  • 有可用的 CI/CD 基础设施
  • 已经或准备投资开发工具、共享库、内部Artifact注册表等
  • 拥有工程方法和流程工具来分解功能需求,并在多个服务中实现/跟踪/发布(xp、pivotal、scrum 等)

还有很多当前没有想到的,重点是 - 上面这些通常都是良好的工程实践。 对于微服务,工程的标准必须非常高。微服务的构建环境比较--Spring Cloud和Kubernetes

 

上图中的列表,包含必须在 MSA 中解决的最常见的技术问题(不包括非技术问题,例如组织结构、文化等)。这是我的观点,不同的组织会有所不同,但大多数情况下是适用的。

技术映射

这两个平台差异很大,它们之间没有直接的对等功能。如果我们将每个 MSA 的关注点映射到这两个平台中的解决方案,我们会得出下表。微服务的构建环境比较--Spring Cloud和Kubernetes

 

上表的主要结论是:

  • Spring Cloud 拥有一组丰富的集成良好的 Java 库,可以解决所有运行时问题。因此,微服务可以利用类库和运行时代理来进行客户端服务发现、负载平衡、配置更新、指标跟踪等。单例集群服务、批处理作业等模式也在 JVM 中进行管理。
  • Kubernetes 是支持多语言的,不仅针对 Java 平台,还适用于其他所有语言,它提供一种通用解决方案来应对分布式计算的问题。在应用程序之外,它以平台的方式为配置管理、服务发现、负载平衡、跟踪、度量、单例、计划作业等提供服务。应用程序不需要任何库或代理,并且可以使用任意语言。
  • 在某些领域,两个平台都依赖类似的第三方工具。例如 ELK 和 EFK 堆栈、跟踪库等。
  • 一些库如 Hystrix、Spring Boot 在这两种环境中同样有用。在某些领域,两个平台是互补的,可以组合在一起以创建更强大的解决方案(KubeFlix 和 Spring Cloud Kubernetes 就是这样的例子)。

微服务的要求

为了展示每个项目的范围,这里有一个表格,其中包含(几乎)端到端的 MSA 要求,从底部的硬件开始,到顶部的 DevOps 和自助服务体验,以及它们与 Spring Cloud 和 Kubernetes 平台的关系。微服务的构建环境比较--Spring Cloud和Kubernetes

 

在某些情况下,两个项目使用不同的方法满足相同的要求,在某些领域,一个项目可能比另一个项目更强大。但也有一个甜蜜点,两个平台相互补充,可以互相结合以获得卓越的微服务体验。例如 Spring Boot 提供了用于构建单个 jar 应用程序包的 Maven 插件。结合 Docker 和 Kubernetes 声明式部署和调度功能,运行微服务变得轻而易举。类似地,Spring Cloud 具有应用程序内部库,用于使用 Hystrix(带有隔板和断路器模式)和 Ribbon(用于负载均衡)创建弹性、容错的微服务。但这还不够,当它与 Kubernetes 健康检查、进程重启和自动扩展功能相结合时,微服务将变成一个真正的健壮系统(反脆弱系统, antifragile system)。

优点和缺点

由于两个平台不能直接逐个比较,我们没有深入研究每个项目,而是总结了每个平台的优缺点。

Spring Cloud

Spring Cloud 为开发者提供了快速构建一些常见的分布式系统所需的工具,例如配置管理、服务发现、断路器、路由等。它构建在 Netflix OSS 库之上,用 Java 编写,供 Java 开发者使用。

优点

  • Spring Platform自身提供的统一编程模型,以及Spring Boot的快速应用创建能力,给开发者带来了极好的微服务开发体验。例如,您可以使用少量注释创建一个配置服务器,再添加一些注释就可以让客户端库配置您的服务。
  • 有丰富的类库可供选择,涵盖了大多数运行时问题。所有库都是用 Java 编写的,提供了多种功能、更好的控制和优化选项。
  • 不同的 Spring Cloud 库彼此很好地集成在一起。例如,一个 Feign 客户端也将使用 Hystrix 进行断路,使用 Ribbon 对请求进行负载平衡。一切都是注解驱动的,易于开发,感觉就像是 Java 开发人员的天堂。

缺点

  • Spring Cloud 的主要优点之一也是它的缺点——它仅限于 Java。 MSA 的一个强大动力是能够在需要时更改技术堆栈、库甚至语言。这在 Spring Cloud 中是不可能的。如果想要替换配置管理、服务发现、负载均衡等Spring Cloud/Netflix OSS的基础服务,很难找到一个优雅的解决方案。 Netflix Prana 项目实现了 sidecar 模式,通过 HTTP 公开 Java 客户端类库,使得非 JVM 语言编写的应用程序可以存在于 NetflixOSS 的生态系统中,但这个方案不是很优雅。此外,我写完这篇文章之后,Pivotal 宣布了一个名为 SteelToe 的新项目,它也允许从 .Net 客户端使用服务发现和配置服务。
  • Java 开发人员承担了太多的责任。每个微服务都需要运行各种客户端来进行配置检索、服务发现和负载均衡。设置它们很容易,但这并没有隐藏构建时以及运行时对环境的依赖。例如,我可以轻松地使用 @EnableConfigServer 注释创建一个配置服务器。但每次我想运行单个微服务时,我都需要启动配置服务器。对于受控环境,我必须让配置服务器高度可用,并且为了实现对 Git 或 Svn 的支持,因此我需要共享文件系统。同样对于服务发现,我需要先启动 Eureka Server。对于受控环境,我需要在每个可用区(AZ)上构筑包含多个实例的集群等等。感觉就像作为 Java 开发人员,除了实现所有功能服务之外,我还必须构建和管理一个不平凡的微服务平台。
  • Spring Cloud 在微服务之旅中的覆盖的范围较小,你还需要考虑自动化部署、调度、资源管理、进程隔离、自我修复、构建管道等,以获得完整的微服务体验。在这一点上,我认为单独将 Spring Cloud 与 Kubernetes 进行比较是不公平的,而将 Spring Cloud + Cloud Foundry(或 Docker Swarm)与 Kubernetes 之间的比较更公平。但这也意味着要获得完整的端到端微服务体验,Spring Cloud 必须再加上类似与 Kubernetes 之类的东西。

Kubernetes

Kubernetes 是一个开源系统,用于自动部署、扩展和管理容器化应用程序。它是多语言的,并提供用于配置、运行、扩展和管理分布式系统的基础功能。

优点

  • Kubernetes 是一个多语言的通用容器管理平台,能够运行云原生和传统容器化应用程序。它提供的服务,例如配置管理、服务发现、负载平衡、指标收集、日志聚合,可以被多种语言使用。这允许在组织中拥有一个平台,可供多个团队(包括使用 Spring 框架的 Java 开发人员)使用并服务于多种用途:应用程序开发、测试环境、构建环境(运行源控制系统、构建服务器、Artifact Repository)等等。
  • 与 Spring Cloud 相比,Kubernetes 解决了更广泛的 MSA 问题。除了提供运行时服务,Kubernetes 还允许配置环境、设置资源约束、RBAC、管理应用程序生命周期、启用自动扩展和自我修复(表现得几乎像一个反脆弱平台)。
  • 我忍不住要提一下,Kubernetes 技术是基于谷歌 15 年的研发和管理容器的经验。此外,它拥有近 1000 名贡献者,是 Github 上最活跃的开源社区之一

缺点

  • Kubernetes 是多语言的,因此它的服务是通用的,并没有针对不同的平台进行优化(如 Spring Cloud for JVM)。例如,配置作为环境变量或大量文件系统传递给应用程序。它没有 Spring Cloud Config 提供的花哨的配置更新功能。
  • Kubernetes 不是以开发人员为中心的平台。它旨在供具有 DevOps 意识的 IT 人员使用。因此,Java 开发人员需要学习一些新概念并乐于学习解决问题的新方法。尽管使用 MiniKube 启动 Kubernetes 的开发实例非常容易,但手动安装高可用的 Kubernetes 集群会产生大量的操作开销。
  • Kubernetes 仍然是一个相对较新的平台,并且仍在积极开发和成长。因此,每个版本都添加了许多新功能。好消息是,这个问题早已被预料到了,而且 API 是可扩展和向后兼容的。

强强联合

正如你所看到的,这两个平台在某些领域都有优势,在其他领域有待改进。 Spring Cloud 是一个快速入门、开发人员友好的平台,而 Kubernetes 是 DevOps 友好的,具有陡峭的学习曲线,但涵盖了更广泛的微服务问题。以下是对这些要点的总结。微服务的构建环境比较--Spring Cloud和Kubernetes

 这两个框架解决了不同范围的 MSA 问题,并且它们以完全不同的方式实现。 Spring Cloud 让开发人员能更轻松地解决问题,试图在 JVM 内部解决每个 MSA 的挑战,而 Kubernetes 则试图在平台上解决问题,让开发人员不必直面这些问题。 Spring Cloud 在 JVM 内部非常强大,而 Kubernetes 在管理这些 JVM 方面非常强大。因此,将它们结合起来并从两个项目的最佳部分中受益,感觉就像一个自然的过程。微服务的构建环境比较--Spring Cloud和Kubernetes

 

通过这样的组合,Spring 提供了应用程序打包,Docker 和 Kubernetes 提供了部署和调度。 Spring 通过 Hystrix 线程池提供应用内隔板,Kubernetes 通过资源、进程和命名空间隔离提供隔板。 Spring 为每个微服务提供健康端点,Kubernetes 执行健康检查并将访问路由到健康的服务。 Spring 将配置外部化并更新配置,Kubernetes 将配置分发到每个微服务。这个列表不胜枚举。微服务的构建环境比较--Spring Cloud和Kubernetes

 

上面是我最喜欢的微服务平台,怎么样?小孩子才做选择题,成年人当然是全都要。我喜欢 Spring 框架提供的开发人员体验。它都是注解驱动的,并且有涵盖各种功能需求的库。我也喜欢 Apache Camel(在这种情况下是 Spring Integration),因为它与应用程序级别的集成、连接器、消息传递、路由、弹性和容错有关。然后,对于与集群和管理多个应用实例有关的任何事情,我更喜欢 Kubernetes 的神奇功能。每当有功能重叠时,例如服务发现、负载平衡、配置管理,我都会尝试使用 Kubernetes。


 

 

上一篇:PCL中使用KdTree搜索


下一篇:Spring Boot 14. 与分布式