函数组合的 N 种模式

随着以函数即服务(Function as a Service)为表明的无服务器计算(Serverless)的普遍使用,不少用户遇到了涉及多个函数的场景,须要组合多个函数来共同完成一个业务目标,这正是微服务“分而治之,合而用之”的精髓所在。本文以阿里云函数计算为例,试图全面介绍函数组合的常见模式和使用场景,但愿有助于选择合适的解决方案。html

虽然本文主要介绍的是函数组合,可是基本思想也可用于服务组合。git

函数同步调用函数

746005ab344914991609f2d30e065701

在这种模式里,函数直接调用 InvokeFunction 同步 API 执行一个或者多个函数,等待被调用函数返回结果,而后继续执行。这是一个有些争议的模式,不使用同步调用一般有如下缘由:github

  1. 从费用的角度:因为函数计算按照函数实际执行时间收费,调用者在等待被调用函数返回前也会产生必定费用。
  2. 执行时长限制:因为函数最长执行10分钟,这就决定了调用的其它函数执行时间之和有限。
  3. 从容错的角度:被调用者出错会直接影响调用者,若是这个调用链很长,则这种错误会一直蔓延到最初的调用者,容错性较差。同时因为执行时长限制,调用者一般不容易针对错误作长时间重试。

上面的理由是在有些场景下成立的,可是微服务最经典最多见的组合方式就是同步调用,函数做为微服务的一种实现方式,这种同步调用的需求是不可回避的,在有些场景下采用同步调用模式是值得考虑的,这些场景包括:数据库

  1. 调用者函数须要被调用函数执行结果作后续处理或者返回给客户端。
  2. 函数执行时间较短,最好在毫秒到秒级别。
  3. 调用者是无状态的,不须要针对被调用者的错误作复杂重试。

在这种模式里,调用者一般不须要作复杂的计算,主要时间花在调用函数和等待返回上,所以调用者函数能够设置较小的内存,以减小费用;调用者还能够根据业务需求缓存调用结果,减小对其它函数的调用,从而节约费用和加强容错性。api

函数经过 API 网关调用函数

b805552a8de08160fe1852fb2fdb1c10

与函数直接调用函数不一样,这里被调用函数在 API 网关后面,使它看起来更像一个微服务。这种模式的限制和使用场景跟上面的直接调用模式相似,不一样之处是 API 网关提供了一些额外的能力,好比认证和限流等。若是被调用者要根据某些业务信息对请求作处理,则使用 API 网关是一个好的选择。固然,使用 API 网关也带来了额外的延迟和费用,若是不须要使用 API 网关提供的能力,则让函数直接调用函数是一个更好的选择。数组

函数异步调用函数

be45bc3b11d5822a224b6f2da7778a43

在这种模式里,函数执行完自身业务逻辑后,调用 InvokeFunction 异步 API 通知其它函数执行并退出,它不关心被调用函数是否执行完成。函数计算的 InvokeFunction 异步 API 是经过队列实现的,异步请求首先被写入队列,而后有一个组件从队列里消费请求,执行相应函数。这种模式的优点和使用场景有:缓存

  1. 对执行延迟不敏感的场景,适合削峰填谷,减轻对依赖服务的压力。函数计算会根据用户的资源使用状况动态的调整队列的处理速度,平滑请求对系统的压力,固然这种平滑也可能会致使一些请求被延缓执行。
  2. 调用者能够较容易的触发多个被调用者执行,实现 Fan-Out 模式。好比一个视频处理函数能够异步调用多个函数来分别将视频转换成不一样格式。
  3. 因为每一个函数所花时间都用在执行业务逻辑,而非等待其它函数返回上,没有产生没必要要的费用。

这种模式有以下局限性:安全

  1. 调用者显然没法知道被调用者的执行结果。
  2. 被调用者之间最好是独立执行的,不须要相互协调,不然经过数据库来协调执行会增长复杂度。例如,上面提到的视频处理函数调用多个函数分别将视频转换成不一样格式,若是须要在全部的视频转换完成后发邮件通知用户,这就须要等待全部的转换函数执行结束。这种等待多个事件发生的模式叫作 Fan-In,不适合经过这种异步调用模式实现。

基于消息主题的函数调用

a81b47c9c3e73fdff6e3e41c035cfb23

与上面的模式须要指定被调用函数不一样,基于事件触发模式让调用者只须要发布消息,不关心谁去消费消息。在消息服务(MNS)中,主题是发布消息的目的地,发布者能够经过 PublishMessage API 向主题发布消息, 主题的订阅者会接收到发布到主题上的消息,MNS 与函数计算服务的集成让函数能够直接做为订阅者,简化了消息处理应用的开发和运维代价。服务器

和上面的异步调用模式相比,基于消息主题的调用模式有如下优点:网络

  1. 进一步解耦函数调用。调用者无需知道被调用者的信息,只须要约定消息的格式。
  2. 得益于一个主题能够对应多个订阅者,更容易实现 Fan-Out 模式。发布者只须要发布一条消息就能触发多个函数。在上面的异步调用方式中,调用者仍须要显式调用一个或者多个函数来触发执行。
  3. 虽然主题模式本质上是消息服务推送消息给订阅者,不会考虑订阅者的承载能力,可是因为阿里云消息服务是经过 InvokeFunction 异步 API 调用函数,所以这种模式也具有基于消息队列模式的削峰填谷能力。

这种模式的局限性跟异步调用函数相似:

  1. 很难支持等待多个事件触发一个函数的场景(Fan-In)。
  2. 须要作必定工做才能跟踪多个函数执行状态。
  3. 很难限制单个函数的执行时间或者全部函数的总执行时间。
  4. 没法针对函数执行错误定义重试策略。

基于对象存储服务的函数调用

97c87db6ed57833eebdab5aa2f578574

函数计算服务除了集成了消息主题之外,还集成了对象存储服务 (OSS),表格存储等其它事件源,这些事件源服务一样能够做为链接函数的渠道。好比,一个非函数应用对 OSS 对象操做(建立,删除等)后,一般须要其它渠道(好比消息服务)通知其它应用作后续处理,而因为 OSS 和函数计算的集成,只需简单配置,这些事件就能够直接传递给自定义函数,而不须要额外渠道再传递信息,简化了数据处理流水线的开发和运维代价。

基于日志库的函数调用

05bbc670f1354950ad39f6465112c673

日志服务的日志库是一个流(Stream)存储,生产者写入数据到日志库,消费者读出数据并处理。日志服务和函数计算的集成,使得消费者能够是函数,从而实现了经过流存储来协调函数调用。上面全部模式都是调用者显式或者隐式的触发一个或多个被调用函数执行,而这里生产者函数写入的数据不必定会马上被消费者函数处理,日志服务会根据用户配置将多个数据批量推送给消费者函数。

这种模式有如下优点:

  1. 日志服务会针对每一个分区(Shard)并行调用函数,若是数据吞吐较大,能够经过扩展分区来提升消费吞吐能力。
  2. 日志服务给函数推送的同一分区数据是串行的和严格保序的,在老的数据没有消费成功前不会推送新的数据。
  3. 日志服务会持续推送相同数据到函数直到函数消费数据后返回正常。

基于函数工做流的函数组合

9bad3110cdaf618492064cde03723413

函数工做流(Function Flow,简称 FnF)是一个用来协调多个分布式任务执行的全托管 Serverless 云服务,简化了开发和运行业务流程所须要的任务协调、状态管理以及错误处理等繁琐工做,让用户更好的专一业务逻辑开发。能够说函数工做流是转为函数组合而生,有效的解决了上面几种异步组合模式的局限性。

上面的全部模式都是经过点对点的方式来组合函数,而函数工做流是一个集中的协调者,函数以前再也不直接或者间接通讯,全部的触发都是由函数工做流发起,不一样函数的输入和输出是经过函数工做流来传递。所以,这种方式下的函数代码全是业务逻辑相关,没有上面模式里的发送主题消息,或者调用其它函数的逻辑,实现更加清晰。

函数工做流有如下优点:

  1. 服务编排能力:能够将流程逻辑与任务执行分开,支持多种控制原语,好比顺序执行多个函数,根据函数执行结果选择执行其它函数,让多个函数并行处理数据,或者让一个函数并行处理一组数据等,以及上面的 Fan-In 模式。函数工做流还内置了错误重试和捕获能力,节省了编写编排代码的时间。
  2. 支持长流程:不管是毫秒级仍是长达一年的业务流程,FnF 均可以跟踪整个流程,确保流程执行完成。
  3. 流程状态管理:FnF 会管理流程执行中的全部状态,包括跟踪它所处的执行步骤,以及存储在步骤之间的输入输出。您无需本身管理流程状态,也没必要将复杂的状态管理构建到任务中。
  4. 协调分布式组件:FnF 可以协调运行在不一样架构,不一样网络,不一样语言实现的分布式应用。不管是私有云、专有云的应用想要平滑过渡到混合云、公共云,仍是单体架构的应用想要演进到微服务架构,FnF 都能在其中发挥协调做用。函数工做流经过集成消息队列,让任何能够访问消息队列的应用也能够做为流程一部分,相互协做,共同完成业务目标。
  5. 可视化监控:FnF 提供了可视化界面来协助定义流程和查看执行状态,方便您快速识别故障位置,并快速排除故障问题。
  6. 运维全托管和按需付费:FnF 让您从基础设施维护中解放出来,提供了安全的、高可用的、高容错的弹性服务。用户只需支付步骤转换费用,不使用不产生费用。

函数工做流目前还不支持同步调用方式,若是您有同步调用需求,欢迎联系咱们(见文章最后钉钉客户群)。

总结

总的来讲,上面的组合模式能够分为同步和异步两种,在场景适合的状况下优先选择异步模式,享受异步模式带来的松耦合,高容错等特性,不然使用同步模式。在异步模式中,若是须要编写复杂的组合逻辑,支持可靠的重试,把控整个流程,则推荐使用函数工做流,不然使用消息主题或者其它事件源服务来组合函数。

上面的模式也不是割裂的,它们在有些场景下能够搭配使用,好比有时候基于对象存储服务的调用须要触发多个函数,这就能够结合使用 OSS 的事件触发和函数工做流;又好比函数工做流经过消息队列将任务发送给更普遍的消费者,触达函数计算没法触达的地方。

最后,欢迎加入函数工做流和函数计算客户群。

1571936661683
1571970520181

阿里巴巴云原生关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,作最懂云原生开发者的技术圈。”

相关文章
相关标签/搜索