无服务器函数编排：Step Functions, Durable Functions, Cloud Composer

admin
Fri, 06 Jun 2025 15:04:30 +0000
云服务与模式, durable, functions, step

好的，各位观众老爷，欢迎来到“无服务器函数编排：Step Functions, Durable Functions, Cloud Composer——让你的云端舞蹈跳得更优雅！”的现场。我是你们今天的导游，人称“代码界的段子手”，保证让大家在欢声笑语中学到真本事！ 今天我们要聊聊一个非常时髦，但又容易让人挠头的概念：无服务器函数编排。说白了，就是把一堆零散的无服务器函数（比如AWS Lambda、Azure Functions、Google Cloud Functions），像串珍珠项链一样，按照一定的顺序和逻辑，把它们“串”起来，完成一项复杂的任务。 想象一下，你要烤一个美味的蛋糕，你需要： 准备食材（鸡蛋、面粉、糖等） 搅拌面糊 预热烤箱 烘烤 冷却 装饰 每个步骤都可以看作一个单独的函数，而把这些函数按照正确的顺序执行，就相当于完成了蛋糕的制作流程。如果我们把这些步骤都放在一个巨大的函数里，那简直就是“代码界的巨无霸”，维护起来让人崩溃。而无服务器函数编排，就是把这些步骤拆解成一个个独立的函数，然后用一种“导演”的角色，来指挥这些函数按照剧本演出。 那么，问题来了，谁来当这个“ …

继续阅读“无服务器函数编排：Step Functions, Durable Functions, Cloud Composer”

The post 无服务器函数编排：Step Functions, Durable Functions, Cloud Composer first appeared on 智猿学院-前后端，数据库，人工智能，云计算等领域前沿技术讲座.

好的，各位观众老爷，欢迎来到“无服务器函数编排：Step Functions, Durable Functions, Cloud Composer——让你的云端舞蹈跳得更优雅！”的现场。我是你们今天的导游，人称“代码界的段子手”，保证让大家在欢声笑语中学到真本事！

今天我们要聊聊一个非常时髦，但又容易让人挠头的概念：无服务器函数编排。说白了，就是把一堆零散的无服务器函数（比如AWS Lambda、Azure Functions、Google Cloud Functions），像串珍珠项链一样，按照一定的顺序和逻辑，把它们“串”起来，完成一项复杂的任务。

想象一下，你要烤一个美味的蛋糕 ，你需要：

1. 准备食材（鸡蛋、面粉、糖等）

2. 搅拌面糊

3. 预热烤箱

4. 烘烤

5. 冷却

6. 装饰

每个步骤都可以看作一个单独的函数，而把这些函数按照正确的顺序执行，就相当于完成了蛋糕的制作流程。如果我们把这些步骤都放在一个巨大的函数里，那简直就是“代码界的巨无霸”，维护起来让人崩溃。而无服务器函数编排，就是把这些步骤拆解成一个个独立的函数，然后用一种“导演”的角色，来指挥这些函数按照剧本演出。

那么，问题来了，谁来当这个“导演”呢？这就是我们今天的主角：Step Functions, Durable Functions, Cloud Composer。

一、三大“导演”登场：Step Functions, Durable Functions, Cloud Composer

这三位“导演”各有千秋，擅长的领域也略有不同，我们先来简单认识一下：

特性 | Step Functions (AWS) | Durable Functions (Azure) | Cloud Composer (Google Cloud)
定位 | 专为无服务器工作流设计，擅长短时、状态机驱动的工作流。 | 专注于有状态的无服务器函数编排，特别适合处理长时间运行、需要人工干预或者需要可靠地处理外部事件的工作流。 | 基于Apache Airflow，提供托管的Airflow服务，擅长数据管道（Data Pipelines）的编排，也适用于通用的工作流。
编排方式 | 基于状态机定义语言 (ASL)，通过图形化界面或者代码定义状态机。 | 基于代码，使用C#、Python等编程语言定义工作流。 | 基于Python，使用Airflow的DAG（Directed Acyclic Graph，有向无环图）定义工作流。
状态管理 | 自动管理状态，支持重试、错误处理等机制。 | 自动管理状态，支持长时间运行、等待外部事件、人工干预等。 | 依赖于Airflow的元数据存储，可以追踪任务状态、执行历史等。
适用场景 | – 订单处理流程 – 审批流程 – ETL流程 – 视频处理流程 | – 人工审批流程 – 长时间运行的后台任务 – 财务结算流程 – IoT设备数据处理 | – 数据清洗 – 数据转换 – 数据加载 – 机器学习模型训练
学习曲线 | 相对简单，易于上手，图形化界面友好。 | 需要一定的编程基础，但灵活性更高。 | 陡峭，需要熟悉Airflow的概念和API。
定价 | 按状态转换次数计费。 | 按函数执行次数、存储时间和IOPS计费。 | 按节点数量、存储空间等计费，相对较贵。
生态系统 | 深度集成AWS其他服务，例如Lambda、S3、DynamoDB等。 | 深度集成Azure其他服务，例如Azure Functions、Azure Storage、Azure Logic Apps等。 | 深度集成Google Cloud Platform其他服务，例如BigQuery、Dataflow、Cloud Storage等。
代码示例 | （稍后提供） | (稍后提供) | (稍后提供)

接下来，我们来分别深入了解一下这三位“导演”的特点和使用方法。

1. Step Functions：状态机的艺术大师

Step Functions是AWS提供的无服务器工作流服务，它最大的特点就是基于状态机。你可以把一个工作流想象成一个状态机，每个状态代表工作流的一个步骤，状态之间通过转换规则连接起来。

Step Functions使用一种叫做Amazon States Language (ASL) 的JSON格式来定义状态机。ASL定义了状态机的各个状态、状态之间的转换规则、以及状态执行的任务。

举个例子，假设我们要创建一个简单的订单处理流程：

1. 接收订单

2. 验证订单

3. 扣款

4. 发货

5. 发送通知

我们可以用ASL来定义这个状态机：

{
  "Comment": "A simple order processing workflow",
  "StartAt": "ReceiveOrder",
  "States": {
    "ReceiveOrder": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:ReceiveOrderFunction",
      "Next": "ValidateOrder"
    },
    "ValidateOrder": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:ValidateOrderFunction",
      "Next": "ChargeCustomer"
    },
    "ChargeCustomer": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:ChargeCustomerFunction",
      "Next": "ShipOrder"
    },
    "ShipOrder": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:ShipOrderFunction",
      "Next": "SendNotification"
    },
    "SendNotification": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:SendNotificationFunction",
      "End": true
    }
  }
}

在这个例子中，每个状态都是一个Task类型，它会调用一个AWS Lambda函数。Resource字段指定了Lambda函数的ARN（Amazon Resource Name）。Next字段指定了下一个要执行的状态。End字段表示这是一个结束状态。

Step Functions的优点：

可视化界面: Step Functions提供了图形化的界面，可以方便地创建和管理状态机。你可以像搭积木一样，把各个状态拖拽到画布上，然后用箭头连接起来。

自动状态管理: Step Functions会自动管理状态机的状态，包括状态的输入、输出、错误处理等。

集成AWS服务: Step Functions可以方便地集成AWS的其他服务，例如Lambda、S3、DynamoDB等。

重试和错误处理: Step Functions支持重试和错误处理机制，可以保证工作流的可靠性。

Step Functions的缺点：

ASL学习成本: ASL虽然简单，但还是需要一定的学习成本。

不适合长时间运行的工作流: Step Functions主要面向短时的工作流，对于长时间运行的工作流，可能不太适合。

2. Durable Functions：有状态的函数编织者

Durable Functions是Azure Functions的扩展，它最大的特点就是支持有状态的函数编排。这意味着你可以创建长时间运行、需要人工干预或者需要可靠地处理外部事件的工作流。

Durable Functions的核心概念是Orchestrator函数。Orchestrator函数是一个特殊的函数，它可以协调其他函数的执行，并且可以记住自己的状态。

Durable Functions支持多种编程语言，例如C#、Python、JavaScript等。我们以C#为例，来看一个简单的例子：

[FunctionName("OrchestrationExample")]
public static async Task<List<string>> RunOrchestrator(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var outputs = new List<string>();

    // Replace "Hello" with the name of your Durable Activity Function.
    outputs.Add(await context.CallActivityAsync<string>("Hello", "Tokyo"));
    outputs.Add(await context.CallActivityAsync<string>("Hello", "Seattle"));
    outputs.Add(await context.CallActivityAsync<string>("Hello", "London"));

    // returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]
    return outputs;
}

[FunctionName("Hello")]
public static string SayHello([ActivityTrigger] string name, ILogger log)
{
    log.LogInformation($"Saying hello to {name}.");
    return $"Hello {name}!";
}

在这个例子中，RunOrchestrator函数是一个Orchestrator函数，它会调用三次Hello函数。Hello函数是一个普通的Activity函数，它会返回一个字符串。

Durable Functions的优点：

有状态: Durable Functions可以记住自己的状态，这使得它可以处理长时间运行、需要人工干预或者需要可靠地处理外部事件的工作流。

多种编程语言支持: Durable Functions支持多种编程语言，可以满足不同开发者的需求。

集成Azure服务: Durable Functions可以方便地集成Azure的其他服务，例如Azure Functions、Azure Storage、Azure Logic Apps等。

Durable Functions的缺点：

需要一定的编程基础: Durable Functions需要一定的编程基础，特别是对于Orchestrator函数的编写。

学习曲线较陡峭: Durable Functions的概念比较多，学习曲线相对较陡峭。

3. Cloud Composer：数据管道的交响乐指挥家

Cloud Composer是Google Cloud Platform提供的托管的Apache Airflow服务。Airflow是一个开源的工作流管理平台，它最大的特点就是基于DAG（Directed Acyclic Graph，有向无环图）。

DAG是一个有向图，图中的节点代表任务，边代表任务之间的依赖关系。Airflow使用DAG来定义工作流，可以方便地管理任务的执行顺序和依赖关系。

Cloud Composer使用Python来定义DAG。我们来看一个简单的例子：

from airflow import DAG
from airflow.operators.bash_operator import BashOperator
from datetime import datetime

default_args = {
    'owner': 'airflow',
    'depends_on_past': False,
    'start_date': datetime(2023, 1, 1),
    'retries': 1,
}

dag = DAG(
    'my_first_dag',
    default_args=default_args,
    schedule_interval='@daily',
)

task1 = BashOperator(
    task_id='print_date',
    bash_command='date',
    dag=dag,
)

task2 = BashOperator(
    task_id='sleep',
    bash_command='sleep 5',
    dag=dag,
)

task3 = BashOperator(
    task_id='echo_hello',
    bash_command='echo "Hello, Airflow!"',
    dag=dag,
)

task2.set_upstream(task1)
task3.set_upstream(task2)

在这个例子中，我们定义了一个名为my_first_dag的DAG。这个DAG包含三个任务：print_date、sleep和echo_hello。task2依赖于task1，task3依赖于task2。

Cloud Composer的优点：

强大的调度能力: Airflow提供了强大的调度能力，可以根据时间、依赖关系等条件来触发任务的执行。

可视化界面: Airflow提供了可视化界面，可以方便地查看DAG的执行状态、任务的执行历史等。

丰富的Operator: Airflow提供了丰富的Operator，可以方便地集成各种服务，例如BigQuery、Dataflow、Cloud Storage等。

Cloud Composer的缺点：

学习曲线陡峭: Airflow的概念比较多，学习曲线相对较陡峭。

成本较高: Cloud Composer是托管服务，成本相对较高。

二、实战演练：打造一个图片处理工作流

为了让大家更好地理解这三大“导演”的使用方法，我们来打造一个简单的图片处理工作流。这个工作流的功能是：

1. 从S3/Blob Storage/Cloud Storage读取图片

2. 缩放图片

3. 上传到另一个S3/Blob Storage/Cloud Storage

1. Step Functions实现

首先，我们需要创建三个Lambda函数：

ReadImageFunction: 从S3读取图片

ResizeImageFunction: 缩放图片

UploadImageFunction: 上传图片

然后，我们可以用ASL来定义状态机：

{
  "Comment": "A simple image processing workflow",
  "StartAt": "ReadImage",
  "States": {
    "ReadImage": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:ReadImageFunction",
      "Next": "ResizeImage"
    },
    "ResizeImage": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:ResizeImageFunction",
      "Next": "UploadImage"
    },
    "UploadImage": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:UploadImageFunction",
      "End": true
    }
  }
}

2. Durable Functions实现

首先，我们需要创建两个Azure Functions：

ResizeImageActivity: 缩放图片

ImageProcessingOrchestrator: Orchestrator函数，协调其他函数的执行

[FunctionName("ImageProcessingOrchestrator")]
public static async Task<bool> RunOrchestrator(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    string imagePath = context.GetInput<string>();

    // 调用Activity函数缩放图片
    string resizedImagePath = await context.CallActivityAsync<string>("ResizeImageActivity", imagePath);

    // 上传图片到另一个Blob Storage
    // ... (省略上传代码)

    return true;
}

[FunctionName("ResizeImageActivity")]
public static string ResizeImage([ActivityTrigger] string imagePath, ILogger log)
{
    log.LogInformation($"Resizing image: {imagePath}.");
    // ... (省略缩放图片的代码)
    return "resized_image.jpg"; // 返回缩放后的图片路径
}

3. Cloud Composer实现

首先，我们需要创建三个Python函数：

read_image: 从Cloud Storage读取图片

resize_image: 缩放图片

upload_image: 上传图片

然后，我们可以用Python来定义DAG：

from airflow import DAG
from airflow.operators.python_operator import PythonOperator
from datetime import datetime

def read_image_task():
    # 从Cloud Storage读取图片
    print("Reading image from Cloud Storage...")

def resize_image_task():
    # 缩放图片
    print("Resizing image...")

def upload_image_task():
    # 上传图片到另一个Cloud Storage
    print("Uploading image to Cloud Storage...")

default_args = {
    'owner': 'airflow',
    'depends_on_past': False,
    'start_date': datetime(2023, 1, 1),
    'retries': 1,
}

dag = DAG(
    'image_processing_dag',
    default_args=default_args,
    schedule_interval='@once',
)

read_task = PythonOperator(
    task_id='read_image',
    python_callable=read_image_task,
    dag=dag,
)

resize_task = PythonOperator(
    task_id='resize_image',
    python_callable=resize_image_task,
    dag=dag,
)

upload_task = PythonOperator(
    task_id='upload_image',
    python_callable=upload_image_task,
    dag=dag,
)

resize_task.set_upstream(read_task)
upload_task.set_upstream(resize_task)

三、总结：选择最适合你的“导演”

好了，各位观众老爷，今天的“无服务器函数编排”就讲到这里。相信大家对Step Functions、Durable Functions、Cloud Composer这三大“导演”都有了一定的了解。

那么，到底应该选择哪个“导演”呢？这取决于你的具体需求：

如果你需要编排短时、状态机驱动的工作流，并且希望使用可视化界面，那么Step Functions是你的不二之选。

如果你需要编排长时间运行、需要人工干预或者需要可靠地处理外部事件的工作流，并且对编程有一定的基础，那么Durable Functions是你的最佳选择。

如果你需要编排数据管道，并且熟悉Airflow，那么Cloud Composer是你的首选。

记住，没有最好的“导演”，只有最适合你的“导演”。希望大家能够根据自己的实际情况，选择合适的工具，让你的云端舞蹈跳得更优雅！

最后，送大家一句话：代码虐我千百遍，我待代码如初恋！ 祝大家编程愉快！