我最近有机会从事一个项目,发现自己面临着将操作精心将操作分为两个不同步骤的任务,每个步骤都复杂地链接且苛刻的顺序执行。增加了额外的复杂性,这些步骤需要在指定时间每天启动。在进行有关遵循哪种体系结构的研究时,我偶然发现了持久功能链接的巧妙概念。在此博客中,我很高兴能深入研究精心策划的功能应用程序的复杂性,其中无缝链接功能是中心舞台的。
介绍
在无服务器计算的世界中,有效地编排复杂的工作流是至关重要的。 Azure耐用功能为构建此类编排提供了有力的解决方案。功能编排是指在特定顺序中协调和管理执行多个功能或任务的过程,以实现所需的结果或完成复杂的工作流程。它涉及定义执行顺序,管理任务之间的依赖关系,处理错误以及确保正确有效地执行整体工作流程。这篇博客文章将带您完成使用Node.js。
创建耐用功能链的过程。先决条件
在进入本教程之前,请确保您有以下内容:
- 安装在计算机上的node.js。
- Azure功能本地开发的核心工具
- 对Azure功能和无服务器概念的基本理解
建立开发环境
首先创建一个新的Azure功能项目。打开终端并运行以下命令:
npm install -g azure-functions-core-tools@3 --unsafe-perm true
func init DurableFunctionChaining --language javascript
cd DurableFunctionChaining
接下来,安装耐用功能扩展名:
npm install durable-functions
参与耐用功能链的组件
耐用函数链包含三个主要组件。让我们深入研究这些,
-
耐用功能HTTP启动器 - 耐用功能HTTP启动器是启动整个耐用工作流程的入口点。这是一个HTTP触发的Azure函数,通常只执行每个工作流实例一次。当客户端将HTTP请求发送到此启动器函数时,它启动了定义的编排函数的实例,并返回一个实例ID,该实例ID唯一地标识了工作流实例。它接受来自HTTP请求有效载荷的输入参数或数据。返回一个可以用于跟踪和管理工作流程进度的实例ID。
-
耐用功能编排 - 耐用功能编排器负责控制整个工作流的流程。它定义了要执行的活动的顺序,管理任务之间的依赖性,并处理错误方案和重试。编排功能协调逻辑将活动融合在一起并管理其执行。在工作流程中管理状态,在活动之间存储和传递数据。可以暂停执行,等待某些条件或外部输入。
-
耐用功能活动 - 耐用功能活动代表单个工作单位,这些单位是工作流程的一部分。这些功能是设计执行特定任务的,例如数据处理,验证,与外部服务集成等等。乐队使用呼叫方法调用活动,其输出可以用作后续活动的输入。可以作为具有单一责任的独立职能实施。可以在不同的编排和工作流程中重复使用。
创建您的第一个耐用功能
现在您已经了解了我们基本上需要三个组件来实现耐用的功能链。现在,让我们通过功能及其配置。
在创建功能之前,您需要准备好环境。在VS代码中,安装扩展Azure功能。安装后,您可以在VS代码的左侧查看图标,为
下一步是登录Azure。然后可以在资源下看到订阅。
现在,通过单击“工作区”选项卡上的“ Azure功能应用”按钮,将功能添加到功能应用程序中。您可以创建新功能应用程序,也可以在现有功能应用程序中添加函数。
让我们首先创建一个由HTTP触发的函数。单击创建功能选项以添加耐用函数http启动器
在Node.js中创建项目时,它将要求您选择要创建功能的文件夹。您正在构建应用程序的语言,选择打字稿,然后打字稿编程模型为模型V4。现在,选择耐用功能HTTP启动器并将其命名。一个文件夹以您的功能名称添加到您的根文件夹中,此文件夹将包含两个文件
httpstart是函数名称和函数。JSON将具有index.ts将具有代码的配置。对于添加到项目但具有不同配置的所有功能的所有功能都可以看到相同的结构。
函数。json看起来像
{
"bindings": [
{
"authLevel": "function",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"route": "orchestrators/{functionName}",
"methods": [
"post",
"get"
]
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"name": "starter",
"type": "orchestrationClient",
"direction": "in"
}
],
"scriptFile": "../dist/HttpStart/index.js"
}
和index.ts
import * as df from "durable-functions"
import { AzureFunction, Context, HttpRequest } from "@azure/functions"
const httpStart: AzureFunction = async function (context: Context, req: HttpRequest): Promise<any> {
const client = df.getClient(context);
const instanceId = await client.startNew(req.params.functionName, undefined, req.body);
context.log(`Started orchestration with ID = '${instanceId}'.`);
return client.createCheckStatusResponse(context.bindingData.req, instanceId);
};
export default httpStart;
client.startnew()创建了一个实例,将其称为函数中的乐队。JSON我们指定的路由指向Quptestrator。
实施功能链接
考虑我们处理订单的方案。我们将创建三个活动函数:ValidateOrder,ProcessPayment和Send Concriendation。
在您的项目目录中创建一个活动文件夹。
在活动文件夹中,创建三个文件:validateOrder.js,processPayment.js和sendConfirmation.js。或可以从本地工作区中的Azure函数应用图标中添加相同的内容。
在每个文件中,创建一个活动函数如下:
// validateOrder.js
module.exports = async function (context, order) {
// Validation logic
return isValid;
};
// processPayment.js
module.exports = async function (context, order) {
// Payment processing logic
return paymentStatus;
};
// sendConfirmation.js
module.exports = async function (context, order, paymentStatus) {
// Send confirmation logic
return confirmationSent;
};
现在,创建一个编排功能来链接这些活动。在您的主要项目文件夹中,创建一个名为quentestration.js的文件:
const df = require("durable-functions");
module.exports = df.orchestrator(function* (context) {
const order = yield context.df.callActivity("validateOrder", context.bindingData.order);
const paymentStatus = yield context.df.callActivity("processPayment", order);
yield context.df.callActivity("sendConfirmation", order, paymentStatus);
});
编队的呼叫方法将活动方法的名称作为第一个参数,请确保您给您的活动命名了相同的名称。
错误处理和检索
在编排功能中,您可以使用标准的JavaScript try-Catch块和延迟逻辑来实现错误处理并进行重新试验。
错误处理和检索是使用耐用功能建筑弹性编排的关键方面。耐用的功能链式提供了内置机制,用于处理错误和重试活动或编排。让我们以订单处理工作流程的示例来探索这些概念。
我们将实现错误处理并进行重试,以确保工作流可以优雅处理瞬态失败。
const df = require("durable-functions");
module.exports = df.orchestrator(function* (context) {
const order = context.bindingData.order;
try {
// Step 1: Validate Order
const isValid = yield context.df.callActivity("validateOrder", order);
if (!isValid) {
throw new Error("Invalid order");
}
// Step 2: Process Payment
const paymentStatus = yield context.df.callActivityWithRetry(
"processPayment",
new df.RetryOptions(3, TimeSpan.FromSeconds(10)),
order
);
// Step 3: Send Order Confirmation
const confirmationSent = yield context.df.callActivity("sendConfirmation", order, paymentStatus);
return confirmationSent;
} catch (error) {
// Handle errors
context.log.error(`An error occurred: ${error}`);
throw new Error("Failed to process order");
}
});
重要的是要注意,耐用的功能提供了多种控制重试的选项,例如指定最大次数,重试之间的延迟以及处理特定类型的异常。您可以根据您的特定要求来量身定制这些选项。
监视和记录
耐用功能提供内置的记录功能,您可以使用这些功能来监视编排的进度。您也可以与Azure Monitor集成以进行更高级的监视。
测试和调试
您可以直接调用单个活动功能来测试单个活动功能。对于编排功能,请使用持久功能模拟器或将其部署到Azure进行测试。
何时使用耐用功能链
为了像上面的示例一样,对于订单处理(如订单处理),最好选择耐用的功能链接以保持体系结构的简化。它可以有效地处理测序,检索,错误处理和状态管理。对于具有多个集成点的更复杂的工作流程,Azure Service Bus可能会更合适,因为它提供了脱钩的体系结构。评估您的应用程序的要求并选择与您的目标保持一致的方法很重要。
结论
使用node.js链式链接的耐用功能提供了一种在无服务器环境中管理复杂工作流程的有效方法。通过遵循本指南中的步骤,您已经学习了如何创建,实现和管理耐用功能链。尝试不同的编排,并探索更高级的功能以构建可靠的可扩展应用程序。