更新时间:2024-11-28 GMT+08:00

函数流简介

当前仅“华东-上海一、亚太-新加坡”区域支持函数流功能。

函数流是一个面向无服务器计算领域,编排无服务器分布式应用的工作流服务。基于该服务,用户可以通过Low Code以及可视化的方式将多个独立的无服务器函数用顺序、分支、并行等方式轻松编排成一个完整的应用,并提供监控和管理平台,用于诊断和调试应用。

本章节主要介绍函数流组件、组件编排规则、表达式运算符和配置示例。

组件说明

函数流提供多种类型的组件,用户可以通过拖拽组件、配置组件和连接组件进行可视化编排,实现函数任务流的编排。使用函数流功能,请先了解表1

表1 组件说明

类型

名称

说明

服务组件

函数

FunctionGraph函数,如何创建函数请参见创建函数

EG

事件网格服务(EventGrid),EG节点会发布已配置的事件至指定的EG事件通道,如何创建EG资源请参见事件网格相关文档。

流程控制器

回调节点

通过人工干预实现对执行中函数流的条件控制,函数流将阻塞在回调节点,直到用户调用回调接口以继续函数流执行,从而达到人工审批的效果。

子流程

把已创建的“函数流”任务作为“子流程”组合成一个新的函数流任务。

并行分支

用于创建多个并行分支的控制器,以便同时执行多个分支任务,并可根据分支执行结束后控制下一步流程。

开始节点

只能加入触发器,用于标识流程的开始,一个流程只能有一个开始节点。

异常处理

用于控制函数执行失败后的下一步流程。

循环节点

用于对数组中每个元素进行循环处理。每次循环会执行一次循环内部的子流程。

时间等待

用于控制当前流程在指定时间延迟后再调用下一个流程。

服务节点

用于对多个函数构成的复杂操作进行抽象,可以将多个函数操作合并成一个原子节点进行管理。

条件分支

用于根据条件判断是否执行下一分支。

结束节点

用于标识流程的结束。

编排规则

  • 设计的函数流必须是一个有向无环图,从开始节点出发,开始节点后续必须且只能连接一个节点(除了异常处理和结束节点);流程必须在某一个节点结束,结束流程有两种形式:
    1. 流程中存在的节点没有任何后继节点,且后续节点非条件分支,并行分支或开始节点。
    2. 流程中存在结束节点,且结束节点后续无其他节点。
  • 组件设计规则
    表2 触发器和函数和EG

    参数

    说明

    创建函数流时,是否必选

    触发器

    • 当前允许流程中配置0-10个触发器。
    • 触发器必须配置在开始节点内。
    • 触发器不允许连接其他任何节点,也不允许被其他节点连接。

    函数

    • 当前允许流程中配置0-99个函数节点。
    • 当函数连接异常处理节点时,最多可以再连接一个非开始节点和非异常处理节点。
    • 当函数不连接异常处理节点时,只能连接一个非开始节点。

    EG

    • 当前允许流程中配置0-10个EG节点。
    • 当EG节点连接异常处理节点时,最多可以再连接一个非开始节点和非异常处理节点。
    • 当EG节点不连接异常处理节点时,只能连接一个非开始节点。

    表3 流程控制器

    参数

    说明

    创建函数流时,是否必选

    回调节点

    回调节点限制规则参考表2中函数参数,但回调节点不可为服务节点的子节点

    子流程

    该节点选择已创建的函数流任务。

    并行分支

    • 用于标识节点后面的分支会并行执行。
    • 后继节点允许连接1-20个节点(除了异常处理,开始节点和结束节点),至少连接一个节点。

    开始节点

    • 用于标识流程开始,每个流程必须有且只能有一个开始节点。
    • 开始节点后面必须接1个节点,后续节点类型不能是结束节点或者异常处理。

    必选

    异常处理

    后面可以接0-10个节点,后继节点不能是开始节点,结束节点和异常处理节点。

    循环节点

    用来对数组中每个元素进行循环处理。每次循环会执行一次循环内部的子流程。

    循环节点内部子流程需要满足如下规则:

    1. 只能有一个起始节点(没有前驱节点),起始节点只能使用函数,时间等待节点。
    2. 循环节点内部只允许编排函数,时间等待,异常处理节点。

    时间等待

    后面可以连接0个或1个节点,节点类型不能是开始节点和异常处理节点。

    服务节点

    服务节点由多个函数节点组成,后续节点可以是结束节点或异常处理节点。

    条件分支

    后面可以连接2-20个后继节点,后继节点类型不能为开始节点,结束节点和异常处理节点。

    结束节点

    后面不能接任何节点。

表达式运算符说明

异常处理和条件分支的表达式的结构为 [JsonPath] + [逻辑运算符] + [对比数据],简单示例:$.age >= 20

JsonPath说明

Operator

Supported

Description

$

Y

执行查询的root,所有正则表达式由此启动。

@

Y

过滤正在处理的当前位置。

.

Y

子节点。

[ (, )]

Y

数组索引。

[start:end]

Y

数组切片运算符。

[?()]

Y

过滤表达式。 表达式必须计算为布尔值。

参见示例

  • 简单取值:JSON数据样例
    {  
         "fruits": [ "apple", "orange", "pear" ],  
         "vegetables": [{      
         "veggieName": "potato",
         "veggieLike": true    
          },     
          {       
              "veggieName": "broccoli",      
              "veggieLike": false    
          }] 
    }

    $.fruits表达式含义:取出fruits下对应的所有value。

    $.fruits解析结果:["apple","orange","pear"]

  • 简单过滤:JSON数据样例
    {   
           "fruits": [ "apple", "orange", "pear" ],
           "vegetables": [{ 
           "veggieName": "potato",
           "veggieLike": true
           },     
          { 
              "veggieName": "broccoli",
              "veggieLike": false     
          }] 
    }

    表达式:$.vegetables[?(@.veggieLike == true)].veggieName

    表达式含义:取出key值vegetables对应的所有value,并根据过滤条件输出veggieLike为True的veggieName。

    取值结果:[potato]

逻辑运算符说明

使用以下数据作为例子中的输入参数:

{
  "name" : "apple",
  "weight": 13.4,
  "type": [3,4,6,8],
  "obj": {
        "a" : 1
   }
}

支持的运算符如下:

符号

作用

例子

返回值

备注

==

相等

$.name == 'apple'

true

支持的数据类型包括:int,float,string,bool,nil

!=

不等

$.name != 'apple'

false

支持的数据类型包括:int,float,string,bool,nil

<

小于

$.weight < 12

false

只支持数字类型

>

大于

$.weight > 12

true

只支持数字类型

<=

小于等于

$.weight <= 13.4

true

只支持数字类型

>=

大于等于

$.weight >= 13.4

true

只支持数字类型

'*'

通配符

$.weight == '*'

true

只支持在== 比较中使用

||

$.name == 'apple' || $.weight < 12

true

支持使用()的复杂与或逻辑

&&

$.name == 'apple' && $.weight < 12

false

支持使用()的复杂与或逻辑

  • 字符串格式常量需要使用‘’包含,例如:‘apple’
  • jsonpath表达式中不能出现上述保留字符'=', '!=', '<', '>', '|', '&'

配置示例

示例一:并行分支使用参考

  1. 新建三个函数, Runtime均使用python 3.9,代码功能及内容如下所示 。
    • 函数1:函数执行返回result的值为函数调用事件内的input输入值
      import json
      def handler (event, context):
          input = event.get('input',0)
          return {
              "result": input
              }
    • 函数2:函数执行返回result的值为函数调用事件内的input输入值+2的结果值
      import json
      def handler (event, context):
          input = event.get('input',0)
          return {
              "result": input+2
              }
    • 函数3:函数执行返回result的值为函数调用事件内的input输入值平方的结果值
      import json
      def handler (event, context):
          input = event.get('input',0)
          return {
              "result": input*input
              }
  1. 在函数流编排区域拖拽组件,“并行分支”节点配置如下。
    图1 并行分支节点配置
  2. 函数节点配置如表2 触发器和函数所示,在3个函数节点均需配置
    图2 函数节点配置
  3. 保存函数流,启动执行时,定义输入值如下所示。
    {
      "input":3
    }
  4. 单击函数流任务名称,查看执行结果。
    图3 执行结果

示例二:服务节点使用参考:串行模式

  1. 在函数编排区域编排与拖拽组件,服务节点选择“串行模式”。
    图4 服务节点配置
  2. 函数节点分别选择示例一中创建的函数2函数3,函数流的配置如下。
    图5 函数2配置
    图6 函数3配置
  3. 保存函数流,启动执行时,定义输入值如下所示。
    {
      "input":3
    }
  4. 单击函数流任务名称,查看执行结果。
    图7 执行结果
示例三:服务节点使用参考:并行模式
  1. 新建两个函数, Runtime均使用Python 3.9,代码内容相同。
    import json
    def handler (event, context):
        print(event)
        return {"result":"success"}
  2. 在函数流编排区域拖拽组件,服务节点的配置如下。
    图8 服务节点配置
  3. 函数1节点配置如下。
    图9 函数1节点配置
  4. 函数2节点配置如下。
    图10 函数2节点配置
  5. 保存函数流,启动执行时,定义输入值如下所示。
    {
      "test":123
    }
  6. 单击函数流任务名称,查看执行结果,可以看到两个函数执行结果合并,分别为result1和result2。
    图11 执行结果

    如果两个函数执行返回的输出值结构一致,会导致函数执行结果被覆盖。

示例四:异常处理使用参考

当函数流里面的函数执行异常时,可以通过“异常处理”来处理执行失败的函数并可添加重试。函数执行失败可分为多种情况:函数执行异常;函数内部业务失败并在返回内容中添加了错误码,例如status,200代表成功,500和404等代表失败。
  1. 在函数流编排区域拖拽组件,各节点功能如下。
    • 函数-input:从event取出input输入值,作为函数返回status的输出值;
    • 异常处理:开启重试机制,当函数返回的status为500或404时进行重试,重试间隔1s,最大重试次数8次;
    • 函数-异常记录:当经过8次重试函数返回的status依旧为500或404时,进行异常记录;
    • 函数-正常输出:如果“函数-input”返回的status不为500或404时,执行“函数-正常输出”。

  2. 配置异常处理,重试条件:$.status==500||$.status==404。
    图12 配置异常处理
  3. 添加重试之后依旧失败的处理逻辑即“函数-异常记录”。

  4. 输入200执行成功。

  5. 输入500,异常处理逻辑进行重试和记录。

    示例五:条件分支节点使用参考

    • 通过函数流的“条件分支”实现:

      如果输入值小于2时,则result为输入值加2;

      如果大于2则平方;

      如果等于2则输出原值;

      具体设计如下:

      输入3,输出3的平方:

    • 输入2,则输出原值:

    输入1,则加2:

    示例六:时间等待节点使用参考

    • 通过函数流的“时间等待”组件实现对函数的延迟调用,函数流设计实现如下:

    • 时间等待默认为60s,如下:

    • 执行如下:

    示例七:子流程使用参考

    函数工作流服务可以把一些“函数流”作为“子流程”组合成一个新的函数流,这样可以抽取出一些函数流作为公共流进行使用,减少函数编排的重复开发工作流。

  • 设计一个函数流:当输入值input<2时,执行子流程串行执行(输入值先加2再平方);当输入值input=2,走默认分支,输出原值;当输入值input>2时,执行子流程并行执行(并行输出原值、输入值加2和输入值的平方值),具体如下:

  • 输入3,走子流程并发,结果如下:

  • 输入1,走子流程串行,结果如下:

  • 输入2,走默认分支,输出原值,结果如下:

示例八:循环节点使用参考

使用“循环”组件来对输入数组中每个元素进行循环处理。每次循环会执行一次循环内部的子流程。

  • 设计一个函数流,输入一个整数数组,通过循环对整数数组的每一个元素先加2再平方,具体实现如下:

  • 配置遍历数组路径$.inputs,迭代变量名称$.item

  • 函数-加2配置,函数参数配置中的Value要与“循环”里面的迭代变量名称一致: