写点什么

后 Kubernetes 时代的微服务

2018 年 9 月 14 日

本文要点

  • 当前微服务架构依然是最流行的分布式系统架构风格。Kubernetes 和云原生运动已大规模地重新定义了应用设计和开发中的一些方面。
  • 在云原生平台上,服务仅具备可观测性是不够的。更基本的先决条件是使用检查健康、响应信号、声明资源消耗等手段实现微服务的自动化。
  • 在后 Kubernetes 时代,服务网格(Service Mesh)技术已完全取代了使用软件库实现网络运维(例如 Hystrix 断路器)的方式。
  • 当前,设计应针对“可恢复性”。为此,微服务需要实现多个维度上的幂等性。
  • 现代开发人员必须做到不仅要精通编程语言去实现业务功能,而且同样也要精通云原生技术去满足一些非功能性基础架构层上的需求。

微服务的关注热度起源于一大堆极端的想法,涉及组织的结构、团队的规模、服务的规模、重写和抛出服务而不是修复、避免单元测试等。依我的经验看,其中大部分想法已被证明是错误的、不实用的,或者至少在一般情况下是不适用的。当前能残存下来的微服务原则和实践,大部分是非常通用和宽松定义的。虽然它们适合未来许多年内的发展,但在实践中并没有多大的意义。

早在 Kubernetes 横空出世的几年前,微服务理念就得到了采用,目前,它仍然是一种最流行的分布式系统架构风格。Kubernetes 和云原生运动已大规模地重定义了应用设计和开发的一些方面。在本文中,我试图提出一些原始的微服务理念。我将指出,这些理念在后 Kubernetes 时代已不再像以前那样强大。

服务不仅应可观测,而且应是自动化的

可观测性 (Observability) 是微服务自一开始就提出的一个基本原则。可观测性虽然适用于一般的分布式系统,但是当前,尤其是在 Kubernetes 上,可观测性的主要涉及平台层的开箱即可用,例如进程运行状况检查、CPU 和内存消耗等。应用能以 JSON 格式登录控制台,这就是可观测性的最低要求。此外,平台应可以在无需过多服务层开发的情况下,实现跟踪资源的消耗、开展请求追踪、收集全部类型的指标、计算错误率等。

在云原生平台上,服务仅具备可观测性是不够的。更基本的先决条件是使用检查健康、响应信号、声明资源消耗等手段实现微服务的自动化。任何应用都可以置于容器中并运行。但是要创建一个可通过云原生平台自动化和协调编排容器的应用,则需要遵循一定的规则。遵循这些原则和模式,可确保所生成的容器作为云本地成员在大多数容器编排引擎中表现为优秀,并支持对容器进行自动化的调度、扩展和监视。

我们希望平台不仅可观测服务中发生的情况,而且希望平台能检测到异常,并按照声明情况做出协调。纠正措施可以是通过停止引导流量到服务实例、重新启动、向上/ 向下扩展,也可以是将服务迁移到另一台健康的主机、重试失败的请求或是其它一些操作。如果服务实现了自动化,那么所有这些纠正措施都会自动做出,我们只需要描述所需的状态,而不是去观测并做出响应。服务应该是可观测的,但也应在无需人工干预的情况下由平台实现问题整改。

具备正确职责的智能平台和智能设备

在从SOA 转向微服务的过程中,在服务交互上发生的另一个根本转变就是“智能端点哑管道”(smart endpoints and dumb pipes)这一理念。在微服务领域,服务不依赖于所具有的集中式智能路由层,而是依赖于具有某些平台级功能的智能端点。服务的实现是通过在每个微服务中嵌入传统ESB 的部分功能,并转为使用不具有业务逻辑元素的一些轻量级协议。

这仍然是一种惯常采用的方法,即在不可靠的网络层(使用诸如 Hystrix 之类的库)实现服务交互,但在当前的后 Kubernetes 时代,服务交互已完全被服务网格(Sevice Mesh 技术取代。服务网格吸引人之处在于,它甚至要比传统的 ESB 更智能。网格可以执行动态路由、服务发现、基于延迟的负载平衡、响应类型、指标和分布式跟踪、重试、超时,以及我们所能想到的所有特性。

与 ESB 的不同,服务网格只有一个集中路由层,每个微服务通常都具有自己的路由器,即一个使用额外中央管理层执行代理逻辑的“跨斗模式容器”(Sidecar Container)。更重要的是,管道(即平台和服务网格)中并不维持任何业务逻辑。管道完全聚焦于基础架构问题,而让服务聚焦于业务逻辑。下图表示了为适应云环境的动态和不可靠特性,ESB 和微服务在认知上的演变情况。

从 SOA 到 MSA 和 CNA

如果查看服务的其他一些方面,我们就会注意到云原生不仅影响了端点和服务交互。Kubernetes 平台(及其所有附加技术)还负责资源的管理、调度、部署、配置管理、扩展和服务交互等。与其再次称之为“智能代理哑管道”,我认为更好的描述应是一种具备正确职责的智能平台和智能服务。它不仅是与端点相关,而且也是一个完整的平台,实现主要聚焦于业务功能的服务在所有基础架构上的自动化。

设计不应针对“故障”,而应针对“恢复”

毫无疑问,要在基础架构和网络本身并非可靠的云原生环境中运行微服务,我们必须针对故障做出设计。但是越来越多的故障是由平台检测并处理的,而人们对如何从微服务中捕获故障的考虑较少。相反,我们应通过考虑从多个维度实现幂等性,设计我们的恢复服务。

容器技术、容器编排和服务网格(serive mesh)可以检测许多故障,并从中进行恢复。例如无限循环(分配 CPU 份额)、内存泄漏和 OOM(运行状况检查)、磁盘占用(配额问题)、Fork 炸弹(进程限制),批量处理和进程隔离(限制内存份额)、延迟和基于响应的服务发现、重试、超时、自动扩展等。同样,在过渡到无服务器模型后,服务必须在几毫秒内处理一个请求。看上去对垃圾回收、线程池、资源泄漏等问题的关注,越来越成为一些毫不相关的问题……

使用平台处理所有诸如此类的问题,会将服务视为一个密封黑盒子。该黑盒子应支持多次启动和停止(支持服务重新启动)、服务按比例的放大和缩小(通过将服务成为无状态的以支持安全扩展)、假定许多传入请求最终会超时(使端点具有幂等性)、假定许多传出请求将暂时失败并且平台将会做出重试(确保我们使用了幂等服务)。

为实现自动化在云原生环境中适用自动化,服务必须满足下列条件:

  • 对重启的幂等(服务支持多次被杀掉并启动)。
  • 对向上 / 向下扩展幂等(服务可实现多个实例的自动扩展)。
  • 对服务生成者幂等(其它服务可重试调用)。
  • 对服务消费者幂等(服务或服务网格可以重试传出请求)。

如果服务在一次或是多次执行上述行为中总是表现出同一方式,那么平台就可以在无需人工干预的情况下从故障中恢复服务。

最后请记住,平台提供的所有恢复只是一些本地优化。正如Christian Posta 所指出的,分布式系统中应用的安全性和正确性仍然是应用的责任。对于设计一个整体稳定的系统,业务流程整体范围中的思维模式(可能跨越多个服务)十分重要的。

双重开发职责

越来越多的微服务原则已被Kubernetes 及一些补充项目实施和提供。因此,现代开发人员必须做到不仅要精通编程语言去实现业务功能,而且同样也要精通云原生技术去完全满足一些非功能性基础架构层上的需求。

业务需求和基础架构(操作上的需求、跨功能的需求,或是一些系统质量属性)之间的界限通常是模糊不清的,我们不可能只采取其中的某个方面,而期望其他人去实现另一个方面。例如,如果要在服务网格层实现重试逻辑,那么必须使服务中的业务逻辑或数据库层所使用的服务具有幂等性。如果在服务网格层使用超时,那么必须在服务中实现服务使用者超时的同步。如果必须要实现服务的定期执行,那么必须配置Kubernetes 作业去按时间执行。

展望未来,一些服务功能应作为业务逻辑实现在服务中,而其它一些服务功能则应作为平台功能提供。虽然使用正确的工具去完成正确的任务是一种很好的责任分离,但新技术不断出现极大地增加了整体的复杂性。要在业务逻辑方面实现简单的服务,我们需要很好地理解分布式技术堆栈,因为开发职责是分散在各个层上的。

事实证明,Kubernetes 支持向上扩展到数千个节点,数万个Pod 和每秒数百万事务。但它是否同样支持向下扩展?对我来说,我并不清楚应用的规模、复杂性或关键性的阈值应该是多少,才能证明我们引入复杂的“云原生”是正确的。

结论

看到微服务运动为采用Docker 和Kubernetes 等容器技术提供了如此巨大的动力,这是非常有意思的。虽然在一开始是微服务实践推动了这些技术的发展,但现在是Kubernetes 重新定义了微服务架构的原则和实践。

从最近的一些实例看,我们将很快采纳功能模型作为有效的微服务原语,而不是将微服务视为纳米(nanoservice)服务的反模式。我们并没有充分质疑云原生技术对于中小型案例的实用性和适用性,而是出于兴奋有些随意地投身到这个领域中。

Kubernetes 从 ESB 和微服务中汲取了大量经验,因此它将会成为最终的分布式系统平台。它是一种用于定义建筑风格的技术,而不是反之。究竟是好是坏,只有时间才能证明。

作者简介

Bilgin Ibryam (@bibryam) 是 Red Hat 的首席架构师、提交者和 ASF 成员。他也是一名开源布道师、博客作者,《Camel 设计模式》(Camel Design Patterns)和《Kubernetes 模式》(Kubernetes Patterns)等书的作者在他的日常工作中,Bilgin 喜欢指导、编码和领导开发人员成功地构建云解决方案。他目前的工作重点是应用程序集成、分布式系统、消息传递、微服务、DevOps 和云原生的挑战。可通过 Twitter Linkedin 个人博客联系Bilgin。

查看英文原文: Microservices in a Post-Kubernetes Era

2018 年 9 月 14 日 15:174316
用户头像

发布了 376 篇内容, 共 95.1 次阅读, 收获喜欢 220 次。

关注

评论 1 条评论

发布
用户头像
受这篇文章启发,我也写了篇同名文章,Service Mesh——后 Kubernetes 时代的微服务:https://jimmysong.io/blog/service-mesh-the-microservices-in-post-kubernetes-era/
2020 年 05 月 19 日 15:23
回复
没有更多了
发现更多内容

模块4作业 千万级学生管理系统考试试卷存储方案

TH

架构实战营

【Flutter 专题】123 图解简易 GroupList 二级分组列表

阿策小和尚

5月日更 Flutter 小菜 0 基础学习 Flutter Android 小菜鸟

架构训练营模块四作业

Geek_e0c25c

架构训练营

Scrum Team不等于Development Team——《Scrum指南》重读有感(2)

Bruce Talk

Scrum 敏捷 随笔 Agile

【建议收藏】缺少 Vue3 和 Spring Boot 的实战项目经验?我这儿有啊!

十三

vue.js 面试 springboot Vue3 项目经验

谣言粉碎机 - 极短时间内发送两个Odata request,前一个会自动被cancel掉?

Jerry Wang

JavaScript SAP SAP UI5

架构实战营 - 模块4- 作业

莫问

SAP CRM中间件里的CSA队列有什么用

Jerry Wang

中间件 消息中间件 CRM SAP

一种不通过UI给C4C自定义BO创建测试数据的方式

Jerry Wang

CRM SAP C4C Cloud for Customer

Flume知识点总结

大数据技术指南

flume 5月日更

灵魂拷问:学会就能效率翻倍的Java数组,到底怎么用?小白都知道

java专业爱好者

Java

前端之变(二)- "不变"的前端

御剑

程序员 前端 架构师

SAP ABAP的权限检查跟踪(Authorization trace)工具使用步骤介绍

Jerry Wang

SAP abap Authorization Authentication

第四次作业 设计千万级学生管理系统的考试试卷存储方案

函数方程(弘宇)

模块4 学习总结

TH

架构实战营

Java Elasticsearch 使用

Java elasticsearch

架构实战营模块四作业

薛定谔的指南针

架构实战营

千万级考试管理系统的考试试卷存储方案

黄双鹏

架构实战营

第四次作业

Geek_9cf7b5

为什么有的系统的事务码BSP_WD_CMPWB看不见Enhance Component这个按钮

Jerry Wang

CRM SAP abap

SAP CRM 和 Cloud for Customer 的 Document flow API 介绍

Jerry Wang

CRM SAP abap C4C documentFlow

同时开左右两个SAPGUI编辑器显示同一段ABAP代码

Jerry Wang

SAP abap SAPGUI

千万级学生管理系统的考试试卷存储方案

颜培攀

架构实战营

模块四作业 - 考试试卷存储方案

张大彪

模块 4 - 千万级学生管理系统的考试试卷存储方案

小遵

HBase常见问题

数据社

大数据 HBase 5月日更

Flink的Time与Window

五分钟学大数据

大数据 5月日更

实战|教你用Python玩转Mysql

Python研究者

Python MySQL MySQL 运维

如何处理错误信息 Pricing procedure could not be determined

Jerry Wang

CRM SAP

网络攻防学习笔记 Day23

穿过生命散发芬芳

5月日更 网络攻防

Inkscape 案例:俱乐部 Logo

junsircoding

矢量图 Inkscape 开源软件

QCon 全球软件开发大会 | 主题演讲直播

QCon 全球软件开发大会 | 主题演讲直播

后Kubernetes时代的微服务-InfoQ