摘要:本文结合华为云在Serverless Microservice方面的实践,总结提炼出七大Serverless Microservice开发 “实践标准”,为加速全域Serverless产业升级、推动企业应用开发框架从微服务向Serverless演进提供一些思考。

作者信息——

历川:华为云 Serverless 研发专家

丙真:华为云中间件 Serverless 产品经理

冯嘉:华为云中间件首席专家

一、背景

分散治理、数据去中心化、基础设施自动化等优秀设计原则,使得微服务架构在过去几年中逐渐发展为企业应用架构的首选。然而,随着应用规模的持续增长和微服务生态的成熟,新的挑战也在不断涌现出来。相比于传统SOA等架构, 微服务架构给予开发者更多设计和开发 “自由度”,同一应用的各微服务模块,可以采用不同的技术栈来实现独立自治的业务逻辑。但自由也相应增加了开发运维的复杂度,提高了软件开发者的认知成本;同时,微服务架构在业务资源开销、交付速度、扩展性能和基础设施弹性等方面,也面临一系列新的挑战。

Serverless编程范式的兴起,允许开发者聚焦业务逻辑本身,无需再感知底层运行时细节和后端资源的维护伸缩等问题,给微服务应用开发提供了效率更高的选择。本文结合华为云函数工作流FunctionGraph、事件网格EventGrid以及云应用引擎 CAE等在Serverless Microservice方面的实践,总结提炼出包括基础设施无感知、全生命周期可观测、 状态管理自动化等在内的七大Serverless Microservice开发 “实践标准”,为加速全域Serverless产业升级、推动企业应用开发框架从微服务向Serverless演进提供一些思考。

二、微服务架构新挑战

图1. 微服务应用开发的生命周期示意

如图1所示,在微服务架构中,应用程序由一组功能自治的小型化服务围绕业务能力构建,服务之间采用轻量级通信,可以独立开发、构建、测试、发布和监控。微服务的目的是有效拆分应用,实现敏捷开发和部署 [1]。Martin Fowler 和 James Lewis在《Microservices: A Definition of This New Architectural Term》中,列举了微服务架构的九大特征,如表1所示 (参见 [2]),这些特征使得微服务相比于传统软件开发架构,具有更加灵活的设计开发模式,服务之间支持独立部署和扩展,有效提升了企业应用的开发、迭代和运维效率。

表1:微服务架构的九大特征

尽管微服务架构秉承众多优秀设计原则,随着应用规模增长、技术生态的成熟和工具链的多元化发展,一系列新的挑战逐渐呈现在企业应用开发者面前。

挑战一:开发运维的复杂性高

相比于单体(Monolithic)或SOA(Service-Oriented Architecture)等传统架构下的 “规范标准”,微服务更提倡基于 “实践标准” 解决分布式问题 [2];因此,对于服务注册发现、负载均衡、配置和安全、事务处理等,在微服务场景中不再有统一的解决方案。例如,服务间通信方案就有数十种,包括REST、gRPC、Thrift、Dubbo等,服务发现也包含CoreDNS、Eureka、ZooKeeper、ETCD等多种技术选型; 应用开发人员从这些各有千秋的技术中,选择最适合自己业务场景的系统性方案,无疑是一件门槛很高的任务; 尽管有Spring Cloud等一站式的全家桶工具集,对应用设计和运维人员来说,一揽子工具集所提供的技术组合复杂多样,导致问题定位、定界效率低。

除Spring Cloud,Kubernetes也逐渐成为一种主流的微服务解决方案。与Spring Cloud相比,Kubernetes的配置管理和服务注册功能更加友好,且“边车代理模式”、服务网格 (e.g., Istio) 等技术的提出,显著提高了服务治理的效率;但要实现这类解决方案的高效利用,开发者的认知成本和所面对的复杂性并不低;从Spring Cloud 到Kubernetes,复杂性没有被减弱,更多地是被转移。微服务架构也需要开发者掌握并发编程框架和分布式事务一致性等技术,这些技术本身具备不低的复杂性,以事务一致性为例,常见机制就包括TCC (Try-Confirm-Cancel)、2/3PC (2/3 Phase Commit)、SAGA等模式。

挑战二:服务扩展效率与应用规模难平衡

尽管微服务提倡对应用进行拆分,但微服务的粒度仍然比较大。同一个微服务单元中,不同子功能之间的使用频率(e.g., QPS、RPS et al.)、变更频率等往往也不相同,因而对扩展性的诉求也不一样。图2展示了一个Web应用中“用户管理”微服务的例子[3],该微服务包含账号注册API、登录API和登出API三项子功能,在实际使用中,注册API和登录API的调用频率通常远高于登出API,因此对扩展性的要求也高于后者;此时虽然可以对微服务进一步进行拆分,但整个应用的服务数量也可能会随之翻倍,从而加重应用基础设施的管理负担。

图2. 一个Web应用中“用户管理”微服务的示例

微服务粒度较大的问题也使得单个服务的扩容速度十分受限,在高并发场景下要实现微服务的快速弹性是一件十分困难的事;对于时延敏感型应用,并发请求的扩容诉求通常在秒级以内,甚至毫秒级,但在微服务架构下,服务弹性扩容则通常需要秒级以上甚至分钟级的时延。

挑战三:高可用与弹性保障成本高

与服务扩展效率和应用规模平衡相关的另一个难题是成本问题。受限于单个服务的弹性能力,微服务架构通常采用“多实例主备”或“多实例多活”的方案,来保障应用的高可用性,实现容错、容灾、负载均衡等目标。但与前文中讨论的相似,同一个微服务应用的不同子服务之间,其承载的流量大小、调用频率等的差距也可能很大,因此对资源的横向、纵向扩缩容诉求也不一致,这种差距往往给企业带来无畏的成本浪费。图3展示了一个由6个功能不可或缺的子服务构建而成的微服务应用, 每个服务运行在虚机或容器中,图中实线表示在给定的一段时间内企业为每个服务所占据的虚机或容器所支付的资源成本,虚线表示服务在业务运行中所实际消耗的资源成本。

图3. 一个微服务应用的资源成本示意

在图3的示例中,微服务F由于被调用的频率很高,其所占据的资源利用率也较高,而微服务A则相反,其所占据的资源成本和F相差不大(e.g., 2u2G的容器),但A被调用的频率则相对低很多,资源利用率也相应更低。在实际应用开发运维中,为保障高可用性和资源弹性,图中实线与虚线之间通常存在较大的差距,这部分成本是企业为应用所占据但未使用的资源付出的成本,属于一种成本浪费;同时,由于微服务架构通常不支持(一般也不建议)单个服务 “Scale-to-Zero”,且微服务应用逐渐变得越来越 “重”,上述 “资源占而不用” 导致的浪费现象也更加严重。

三、事件驱动式Serverless函数架构

云原生基础设施的发展,有力促进了事件驱动的Serverless架构的广泛应用。相比于微服务,Serverless提供了一种更加细粒度的应用开发模型,以及更加便捷、轻量的应用运维框架。以FaaS(Function-as-a-Service)为例,应用开发支持以单个函数作为最小部署单元,开发者只需提供函数代码(包括源码文件、镜像等)和一些配置信息,即可实现应用的快速发布和上线;同时,后端资源的维护及其随流量的自适应伸缩等复杂任务,则全部被下移到Serverless平台侧,显著降低了开发者的认知成本和开发、运维门槛,如图4所示;开发者只需为应用函数所实际使用的资源时长进行付费,付费粒度精确到毫秒级;同时,在应用流量负载为零的所有时间区间中,函数实例通过“Scale-to-zero”可以有效消除成本浪费,实现应用开发经济化。

图4. Serverless应用开发架构的资源边界示意

与在微服务场景下相似,事件驱动式(Event-driven)也是Serverless函数架构的核心特征。Serverless函数一般由函数代码包和事件处理程序(event handler)构成,函数通过事件进行触发,并对接收到的事件进行响应、处理。例如,FunctionGraph支持多种类型的事件触发器,满足应用在不同业务场景下的诉求;同时,通过原生集成事件网格服务EventGrid,FunctionGraph为各类云服务、自定义应用、SaaS应用提供了标准化、中心化的接入方式,事件可以在不同应用和服务之间灵活路由,帮助开发者快速构建松耦合、分布式的事件驱动式Serverless应用,如图5所示。

图5. EFG:基于EventGrid和FunctionGraph的事件驱动式Serverless应用模型

四、基于函数快速实现Serverless Microservice应用

图6给出了基于FunctionGraph和APIG(API Gateway)的Serverless Microservice简易应用模型,整个应用采用云上托管服务(managed services)构建,每个微服务由函数实现,并通过APIG对外暴露,函数之间采用Workflow进行功能编排。在该模型基础上,我们用函数快速实现一个Serverless Microservice示例。

图6. 基于FunctionGraph和APIG的Serverless Microservice模型

以经典的电商应用为例,首先用FunctionGraph创建三个函数,分别实现Product, Basket, Order微服务,其中,Product实现商品清单及详情浏览,Basket负责加购,Order完成下单。交易相关的状态采用分布式缓存服务DCS(Distributed Cache Service)进行存储,DCS实例通过绑定独立VPC来实现网络私有和隔离,最后,我们为每个函数分别绑定一个APIG触发器,对外暴露服务;如图7(1) - 7(5) 所示。

图7-(1). 分别创建三个函数,实现微服务功能

图7-(2). 授权FunctionGraph访问VPC内服务 (i.e., DCS 实例)

图7-(3). 开启函数访问VPC

图7-(4). 在函数中获取对应环境变量

图7-(5). 最后为每个函数绑定APIG触发器

我们用APIPost进行简单测试并返回函数界面查看监控信息,如图8(1) – (3) 所示:

图8-(1). 用APIPost测试函数微服务

图8-(2). 查看日志监控

图8-(3). 查看并发数等监控信息

最后,我们通过EventGrid进行异步事件解耦,并采用分布式消息服务DMS(Distributed Message Service)实现基于Fan Out/Fan In的批处理,如图9所示:

图9. 一个基于事件驱动的Serverless 函数架构的电商应用示例

其中,EventGrid创建事件订阅时,事件源选择DCS实例,事件目标选择FunctionGraph函数,如图10所示:

图10. 创建EventGrid事件订阅

五、云上Serverless Microservice实践标准探索

在基于事件驱动式Serverless函数架构开发应用的过程中,遵循一定的设计/开发原则或“实践标准”,有利于开发者构建更加高效、经济和稳健的企业应用。本文结合华为云FunctionGraph、EventGrid以及 CAE等云服务在Serverless领域的最佳实践,总结并提炼出Serverless microservice应用开发的七类实践标准,为开发者的架构决策提供参考;如表2所示。

表2. 云上Serverless Microservice 应用开发的实践标准探索

基础设施无感知(Infra-less):基础设施无感知帮助开发者更快、更高效地构建应用程序,并显著降低应用运维的成本和复杂性。除服务器无感知外,基础设施无感知具有更广泛的含义。包括开发者对平台底层操作系统、分布式运行时以及硬件的有限制访问,开发者无需感知FunctionGraph平台是如何架构的,其它云服务与FunctionGraph的集成由华为云统一管理,只公开少量配置选项给开发者,开发者也无需感知函数在任何时间点被调用时实例资源位于哪个可用区(Available Zone, AZ),等等;这种抽象允许开发者专注于应用程序本身的功能开发、数据流设计和业务逻辑优化,从而更聚焦地为应用的终端用户提供价值。

全生命周期可观测(Deep Observability):基础设施无感知在提供便捷性的同时,也在开发者的“心智模型”方面降低了透明性,因此,全生命周期、深度、实例级的可观测性,对于开发者实现对应用的自主掌控具有关键作用。Serverless可观测性包含链路追踪,日志,和指标三类,主要服务于异常监控、性能调测、故障定位、问题定界等。例如,FunctionGraph通过内置对接云日志服务LTS,为应用函数提供日志监控能力,包括高级日志分析能力(e.g., loginsight)等;通过对接应用性能管理服务APM,提供指标丰富的函数实例级监控;同时,支持全链路调用链管理等。开发者无需复杂的配置,即可享受应用函数全生命周期的深度可观测性能力。

流式编排(Flow Orchestration):编排是Serverless的核心概念之一,狭义的编排主要指工作流编排,如FunctionGraph Workflow,在Serverless microservice 应用开发中,开发者应尽量避免在单个函数中定制化地开发应用的各类分支逻辑及其异常处理程序,应尽可能采用函数工作流编排来实现,工作流编排提供了一种更加便捷的分支路由、错误捕获以及异常处理方法,能够增强应用逻辑的稳健性并提高全链路可观测性 [4]。广义的编排还包括服务流编排(Service Flow),应用架构所依赖的三方功能,如网关、消息、缓存等,也应尽可能采用云上托管服务,通过配置驱动、服务流编排的方式进行组装式构建,从而尽可能减少定制化代码的开发和维护,降低应用运维的负担。FunctionGraph原生支持开发者集成云上其它服务,表3列出了在Serverless microservice开发中最常用的几类云服务。

表3:Serverless microservice应用程序开发中常用的几类云服务

事件驱动(Event-driven):事件,表示状态的变化。采用事件驱动的方式构建应用的优点在于松耦合、独立扩缩容、良好的扩展性等。在状态查询、数据存取、函数调用等场景中,优先采用事件来代替传统应用开发中常用的轮询、Webhook等机制,可以有效降低应用的复杂性、提高系统性能、或降低应用成本 [5]。以轮询为例,由于系统状态的更新在时间维度上不一定是规律且连续的,使得轮询类策略往往是低效或非经济的;Webhook 机制则在被集成的服务之间不一定能够得到广泛的支持。同时,轮询和webhook机制在支持应用按需扩缩容方面也存在较大挑战。采用事件驱动模式,开发者既可以很方便地构建实时系统,实现数据按需流动并避免过量的批处理任务;也可以通过将事件发布到DMS等消息服务,利用弹性缓冲区实现异步解耦,然后利用EventGrid 对事件进行过滤和路由,从而增强应用在流量激变情形下的可伸缩性。

交互式控制(Interactive Autopilot):交互式控制主要解决如何通过广义的自动驾驶技术(autopilot)[7] 实现应用迭代和生产的高性能、低成本;对于Serverless函数而言,自动驾驶主要包括函数代码包瘦身、源码优化、资源规格选择、并发度调优等问题。以函数资源规格选择为例,过去主要依赖于开发者的工程经验和其对自身业务场景的理解进行设定,但经验性配置往往具有误差大、静态性、黑盒化等缺点;因此,FunctionGraph提出在线式资源消耗感知与规格动态推荐等autopilot技术,配合离线式最佳规格调优(power tuning),最大限度帮助用户实现应用函数FinOps效果,让开发者能够真正享受到Economical Serverless的福利 [8];开发者无需感知应用自动驾驶技术的实现细节,但整个过程 “处处可观察、 实时可干预”。

状态管理自动化(Automatic State Management):尽管Serverless提倡无状态优先,但在多数分布式应用中,状态管理是无法回避且复杂度很高的任务。随着数据密集型应用逐渐成为云上应用的主流,如大规模机器学习、大数据与流处理、实时交互型应用、多人协作类应用等,Serverless编程框架对支持有状态的诉求越来越强烈。FunctionGraph 作为业界首个支持有状态的Serverless平台,为开发者提供多种状态一致性模型和自动化的并发处理机制,开发者通常只需要对函数中的简单结构体进行操作,即可实现状态数据的快速存取,整个状态管理过程由平台内置提供,无需与外部存储服务之间进行频繁交互,显著减少了涉及大量状态数据操作的网络访问次数,具有自动化、高性能、高可用等特点。

伸缩原子轻量化(Lightweight Scaling Unit):伸缩原子,指最小可伸缩的运行单元,如单个函数。 在Serverless microservice 应用开发中,函数应尽可能小型化,功能上保持逻辑内聚,以响应外部事件为主,对应用全局逻辑弱感知;伸缩原子的轻量化,不仅能够支持快速的独立扩缩容以及高并发下的快速弹性能力,也能够最大限度地保证应用的各个微服务函数能够“按需扩缩容”,从而在保障应用负载QoS的前提下,实现极致成本。

六、总结和展望

以事件驱动式函数架构为代表的Serverless编程模型,正在成为微服务应用开发的新一代标准框架。本文结合华为云FunctionGraph和EventGrid等在Serverless微服务方面的最佳实践,总结并提炼出七大Serverless Microservice实践标准, 为推动全域Serverless产业升级提供一些思考。

更进一步地,华为云事件网格服务EventGrid将于近期正式转商用,并联合FunctionGraph推出事件驱动式函数应用开发模型EFG(EventGrid-FunctionGraph); 同时,基于七大实践标准并结合丰富的客户实践,EFG将推出Serverless Microservice参考架构,为开发者构建事件驱动式Serverless解决方案提供可视化的架构抽象和优秀的业务建模支持。

参考资料

[1] Introduction to Microservices. https://www.nginx.com/blog/introduction-to-microservices/

[2] 周志明,《凤凰架构:构筑可靠的大型分布式系统》

[3] 刘方明, 李林峰, 王磊, 《华为Serverless核心技术与实践》.

[4] Understanding event-driven architecture – Part 1

https://aws.amazon.com/blogs/compute/operating-lambda-design-principles-in-event-driven-architectures-part-2/

[5] Design principles in event-driven architectures – Part 2

https://aws.amazon.com/cn/blogs/compute/operating-lambda-design-principles-in-event-driven-architectures-part-2/

[6] Anti-patterns in event-driven architectures

https://aws.amazon.com/cn/blogs/compute/operating-lambda-anti-patterns-in-event-driven-architectures-part-3/

[7] Rzadca, K., Findeisen, P., Swiderski, J., Zych, P., Broniek, P., Kusmierek, J., ... & Wilkes, J. (2020, April). Autopilot: workload autoscaling at google. In Proceedings of the Fifteenth European Conference on Computer Systems (pp. 1-16).

[8] 历川, 平山, 冯嘉, Serverless 遇到 FinOps: Economical Serverless,

https://www.infoq.cn/article/ckibtiofxn4whycfjt8b

点击关注,第一时间了解华为云新鲜技术~

Serverless时代的微服务开发指南:华为云提出七大实践新标准的更多相关文章

  1. 使用 ASP.NET Core 3.1 的微服务开发指南

    使用 ASP.NET Core 3.1 的微服务 – 终极详细指南 https://procodeguide.com/programming/microservices-asp-net-core/ A ...

  2. 微服务开发平台 Spring Cloud Blade 部署实践

    本文介绍使用 Rainbond 快速部署 Spring Cloud Blade 微服务平台.Spring Cloud Blade 是一个由商业级项目升级优化而来的微服务架构,采用Spring Boot ...

  3. ServiceStage-华为微服务开发与管理平台

    前言 在上一篇文章一年前,我来到国企搞IT 中,和小伙伴分享了我在国企这一年当中的所见,所闻,所想,很高兴能够获得很多同道中人的共鸣.过去一年,我的很大一部分工作都投入到公司技术平台的建设中.Jira ...

  4. Serverless 下的微服务实践

    作者:弈川 审核&校对:筱姜.潇航 编辑&排版:雯燕 微服务架构介绍 微服务架构诞生背景 在互联网早期即 Web 1.0 的时代,当时流行的是单体应用,研发团队比较小,主要是外部网页, ...

  5. 【SFA官方翻译】使用 Kubernetes、Spring Boot 2.0 和 Docker 的微服务快速指南

    [SFA官方翻译]使用 Kubernetes.Spring Boot 2.0 和 Docker 的微服务快速指南 原创: Darren Luo SpringForAll社区 今天 原文链接:https ...

  6. 【新书推荐】《ASP.NET Core微服务实战:在云环境中开发、测试和部署跨平台服务》 带你走近微服务开发

    <ASP.NET Core 微服务实战>译者序:https://blog.jijiechen.com/post/aspnetcore-microservices-preface-by-tr ...

  7. 都 2021 年了,Serverless 能取代微服务吗?

    来源 | Serverless 公众号 编译 | OrangeJ 作者 | Mariliis Retter "Serverless 能取代微服务吗?" 这是知乎上 Serverle ...

  8. 构建微服务开发环境4————安装Docker及下载常用镜像

    [内容指引] 下载Docker: Mac下安装Docker: Windows下安装Docker; 下载常用docker镜像. 一.下载Docker 1.Mac适用Docker下载地址:https:// ...

  9. 构建微服务开发环境8————Hello 微服务

    [内容指引] 1.用IDEA打开微服务项目; 2.更新Maven依赖: 3.IntelliJ IDEA JDK配置; 4.修改代码: 5.运行微服务: 6.将代码变更提交到Github. 经过前面的努 ...

  10. 黑少微服务商店之Iron Cloud微服务开发云

    近日,由黑少微服务研发团队推出的Iron Cloud微服务开发云已经正式对外提供服务,这是国内第一家基于云端操作的微服务专业开发工具. Iron Cloud 微服务开发云(www.ironz.com) ...

随机推荐

  1. 内存与CPU:计算机默契交互的关键解析

    内存 内存和CPU之间的交互是计算机体系结构中至关重要的一部分.它们之间的互动类似于一对不可分割的爱侣,彼此相互依赖且密不可分.没有内存,CPU无法执行程序指令,这样计算机就会变得毫无意义.同样地,如 ...

  2. KL-Divergence KL散度

    KL散度(KL-divergence) 直观解释:KL 散度是一种衡量两个分布(比如两条线)之间的匹配程度的方法. 需要解决的问题:已知数据太大,逍遥使用较小的信息表示已知数据.用某种已知分布来表示真 ...

  3. TerraMoursGPT V1.0 开发总结

    TerraMoursGPT V1.0 开发总结 TerraMoursGPT V1.0 是之前gpt项目基于TerraMours后端框架的重构,实现用户登陆和基于SK的多语言模型聊天.基于chatgpt ...

  4. 该如何选择ClickHouse的表引擎

    该如何选择ClickHouse的表引擎 本文将介绍ClickHouse中一个非常重要的概念-表引擎(table engine).如果对MySQL熟悉的话,或许你应该听说过InnoDB和MyISAM存储 ...

  5. 看完包你搞懂Redis缓存穿透、击穿和雪崩!!!说到做到

    缓存穿透 缓存穿透是指当用户对Redis发出无效或者不存在的数据信息操作时,这条数据在Redis中不存在,Redis就会在MySQL数据库中查询,可时无效的信息在mysql数据库中也不存在,就会造成R ...

  6. Reflect API:每个 JavaScript 开发人员都需要的瑞士军刀

    前言 您是否曾经希望拥有一个神奇的工具包,可以让您像超级英雄一样控制 JavaScript 对象?向ReflectAPI 打个招呼吧,它是 ES6 中引入的一个新的全局对象 ,它能够处理简单的代码操作 ...

  7. 玩转开源 | 搭建 Hugo 管理 Markdown 文档

    在工作.学习中,不可避免会要写一些文档:又或者想搭建个简单网站,记录和分享您的生活经验或知识:撰写这些文档中使用 markdown 是一个非常不错的选择,让我们更加聚焦在文档表达的内容上.实际上笔者的 ...

  8. cookie和session的区别?一文讲透

    一.问题 cookie和session的区别? 二.回答 1.总结如下- cookie: - cookie存储于客户端本地,即浏览器缓存 - cookie存储着sessionId,作为后台sessio ...

  9. [CF1325E] Ehab's REAL Number Theory Problem

    Ehab's REAL Number Theory Problem 题目描述 You are given an array $ a $ of length $ n $ that has a speci ...

  10. cocos2d-Js 各类碰撞检测

    这里总结一下点.圆.矩形之间的简单碰撞检测算法(矩形不包括旋转状态) 点和圆的碰撞检测: 1.计算点和圆心的距离 2.判断点与圆心的距离是否小于圆的半径 isCollision: function(p ...