阿狸写代码 2020-01-19
随着以函数即服务(Function as a Service)为代表的无服务器计算(Serverless)的广泛使用,很多用户遇到了涉及多个函数的场景,需要组合多个函数来共同完成一个业务目标,这正是微服务“分而治之,合而用之”的精髓所在。本文以阿里云函数计算为例,试图全面介绍函数组合的常见模式和使用场景,希望有助于选择合适的解决方案。
虽然本文主要介绍的是函数组合,但是基本思想也可用于服务组合。
在这种模式里,函数直接调用 InvokeFunction 同步 API 执行一个或者多个函数,等待被调用函数返回结果,然后继续执行。这是一个有些争议的模式,不使用同步调用通常有以下原因:
上面的理由是在有些场景下成立的,但是微服务最经典最常见的组合方式就是同步调用,函数作为微服务的一种实现方式,这种同步调用的需求是不可回避的,在有些场景下采用同步调用模式是值得考虑的,这些场景包括:
在这种模式里,调用者通常不需要做复杂的计算,主要时间花在调用函数和等待返回上,因此调用者函数可以设置较小的内存,以减少费用;调用者还可以根据业务需求缓存调用结果,减少对其它函数的调用,从而节约费用和增强容错性。
与函数直接调用函数不同,这里被调用函数在 API 网关后面,使它看起来更像一个微服务。这种模式的限制和使用场景跟上面的直接调用模式类似,不同之处是 API 网关提供了一些额外的能力,比如认证和限流等。如果被调用者要根据某些业务信息对请求做处理,则使用 API 网关是一个好的选择。当然,使用 API 网关也带来了额外的延迟和费用,如果不需要使用 API 网关提供的能力,则让函数直接调用函数是一个更好的选择。
在这种模式里,函数执行完自身业务逻辑后,调用 InvokeFunction 异步 API 通知其它函数执行并退出,它不关心被调用函数是否执行完成。函数计算的 InvokeFunction 异步 API 是通过队列实现的,异步请求首先被写入队列,然后有一个组件从队列里消费请求,执行相应函数。这种模式的优势和使用场景有:
这种模式有如下局限性:
与上面的模式需要指定被调用函数不同,基于事件触发模式让调用者只需要发布消息,不关心谁去消费消息。在消息服务(MNS)中,主题是发布消息的目的地,发布者可以通过 PublishMessage API 向主题发布消息, 主题的订阅者会接收到发布到主题上的消息,MNS 与函数计算服务的集成让函数可以直接作为订阅者,简化了消息处理应用的开发和运维代价。
和上面的异步调用模式相比,基于消息主题的调用模式有以下优势:
这种模式的局限性跟异步调用函数类似:
函数计算服务除了集成了消息主题以外,还集成了对象存储服务 (OSS),表格存储等其它事件源,这些事件源服务同样可以作为连接函数的渠道。比如,一个非函数应用对 OSS 对象操作(创建,删除等)后,通常需要其它渠道(比如消息服务)通知其它应用做后续处理,而由于 OSS 和函数计算的集成,只需简单配置,这些事件就可以直接传递给自定义函数,而不需要额外渠道再传递信息,简化了数据处理流水线的开发和运维代价。
日志服务的日志库是一个流(Stream)存储,生产者写入数据到日志库,消费者读出数据并处理。日志服务和函数计算的集成,使得消费者可以是函数,从而实现了通过流存储来协调函数调用。上面所有模式都是调用者显式或者隐式的触发一个或多个被调用函数执行,而这里生产者函数写入的数据不一定会立刻被消费者函数处理,日志服务会根据用户配置将多个数据批量推送给消费者函数。
这种模式有以下优势:
函数工作流(Function Flow,简称 FnF)是一个用来协调多个分布式任务执行的全托管 Serverless 云服务,简化了开发和运行业务流程所需要的任务协调、状态管理以及错误处理等繁琐工作,让用户更好的专注业务逻辑开发。可以说函数工作流是转为函数组合而生,有效的解决了上面几种异步组合模式的局限性。
上面的所有模式都是通过点对点的方式来组合函数,而函数工作流是一个集中的协调者,函数之前不再直接或者间接通信,所有的触发都是由函数工作流发起,不同函数的输入和输出是通过函数工作流来传递。因此,这种方式下的函数代码全是业务逻辑相关,没有上面模式里的发送主题消息,或者调用其它函数的逻辑,实现更加清晰。
函数工作流有以下优势:
函数工作流目前还不支持同步调用方式,如果您有同步调用需求,欢迎联系我们(见文章最后钉钉客户群)。
总的来说,上面的组合模式可以分为同步和异步两种,在场景适合的情况下优先选择异步模式,享受异步模式带来的松耦合,高容错等特性,否则使用同步模式。在异步模式中,如果需要编写复杂的组合逻辑,支持可靠的重试,把控整个流程,则推荐使用函数工作流,否则使用消息主题或者其它事件源服务来组合函数。
上面的模式也不是割裂的,它们在有些场景下可以搭配使用,比如有时候基于对象存储服务的调用需要触发多个函数,这就可以结合使用 OSS 的事件触发和函数工作流;又比如函数工作流通过消息队列将任务发送给更广泛的消费者,触达函数计算无法触达的地方。
最后,欢迎加入函数工作流和函数计算客户群。
“阿里巴巴云原生关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术圈。”