写点什么

后 Kubernetes 时代的微服务

  • 2018-09-14
  • 本文字数:3719 字

    阅读完需:约 12 分钟

本文要点

  • 当前微服务架构依然是最流行的分布式系统架构风格。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-09-14 15:175267
用户头像

发布了 391 篇内容, 共 137.0 次阅读, 收获喜欢 256 次。

关注

评论 1 条评论

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

巧用 readonly与 const

喵叔

7月日更

和12岁小同志搞创客开发:如何使用继电器?

不脱发的程序猿

DIY 嵌入式 创客开发 继电器

密码学系列之:Merkle–Damgård结构和长度延展攻击

程序那些事

加密解密 密码学 程序那些事

手写Spring框架,是时候撸个AOP与Bean生命周期融合了!

小傅哥

Java spring 小傅哥 aop 代理

登陆框有多危险,可能你还不知道。。。

网络安全学海

黑客 网络安全 信息安全 渗透测试· 漏洞分析

Rust从0到1-面向对象编程-设计模式

rust 设计模式 面向对象编程 状态模式 state pattern

携手生态伙伴亮相InfoComm,英特尔赋能智能协作办公

E科讯

maven是什么

卢卡多多

7月日更

linux c解决多个第三方so动态库包含不同版本openssl造成的符号冲突

奔着腾讯去

openssl so动态库 动态链接库

价值连城 知名深度强化学习Pieter Abbeel的采访 John 易筋 ARTS 打卡 Week 56

John(易筋)

ARTS 打卡计划

一个很多人不知道的SpringBoot小技能!!

冰河

Java 分布式 微服务 springboot 服务化

后疫情时代,共享育儿也能变成一门好生意?!

脑极体

没有电和网络的时候如何支付一瓶水?

escray

学习 极客时间 朱赟的技术管理课 7月日更

开跑!Mobileye自动驾驶汽车路测落地纽约

E科讯

ZooKeeper 分布式锁 Curator 源码 03:可重入锁并发加锁

程序员小航

Java zookeeper 源码 分布式锁 zookeeper分布式锁

阿里培训笔记惨遭泄露,Spring+SpringBoot+SpringCloud

Java架构师迁哥

iOS15上线图片翻译功能,能取代专业翻译软件吗?

脑极体

week 9 作业

Geek_2e7dd7

架构实战营

Linux之date命令

入门小站

Linux

王者荣耀商城异地多活架构设计

chenmin

Python OpenCV 图像的 最近邻插值 与 双线性插值算法 优化迭代

梦想橡皮擦

Python 7月日更

23w字!Github一夜爆火被各大厂要求直接下架的Java面试题库也太强了

Java架构师迁哥

网络传输协议kcp原理解析

赖猫

TCP 网络协议

结构化流-Structured Streaming(八-中)

Databri_AI

spark 结构化思维 Kafk

C++17 中的条件变量

hedzr

c++ 算法 并发编程 元编程 policy

Vue进阶(五十七):ES数组操作:find(), findIndex(), filter(), forEach(), some(), every(), map(), reduce()

No Silver Bullet

Vue ES 7月日更 数组操作

Vue进阶(五十八):ES字符串操作:遍历、比较、截取、补全...

No Silver Bullet

Vue ES 字符串 7月日更

并发问题的源头

Java旅程

Java 并发编程

网络协议:TCP可靠传输原理

赖猫

c++ TCP 后端 网络协议

在线时间加减计算器

入门小站

工具

Discourse 的标签(Tag)只能是小写的原因

HoneyMoose

后Kubernetes时代的微服务_DevOps & 平台工程_Bilgin Ibryam_InfoQ精选文章