長期函式中的繫結 (Azure Functions)
Durable Functions 延伸模組推出了三個觸發程序繫結,可控制協調器、實體與活動函式的執行。 它也引進了輸出繫結,可作為長期函式執行階段的用戶端。
請務必在文章頂端選擇您的Durable Functions開發語言。
重要
本文支援適用于 Durable Functions 的 Python v1 和 Python v2 程式設計模型。
Python v2 程式設計模型目前為預覽狀態。
Python v2 程式設計模型
Durable Functions提供新Python v2 程式設計模型的預覽支援。 若要使用 v2 模型,您必須安裝 Durable Functions SDK,這是 PyPI 套件 azure-functions-durable
、版本 1.2.2
或更新版本。 在預覽期間,您可以在Durable Functions SDK for Python 存放庫中提供意見反應和建議。
v2 模型目前不支援使用擴充功能套件組合搭配Durable Functions。 您必須手動管理擴充功能,如下所示:
extensionBundle
請移除函式文章中所述的host.json
區段。func extensions install --package Microsoft.Azure.WebJobs.Extensions.DurableTask --version 2.9.1
在您的終端機上執行 命令。 這會為您的應用程式安裝Durable Functions擴充功能,這可讓您使用 v2 模型預覽。
協調流程觸發程序
協調流程觸發程序可讓您撰寫長期協調器函式。 當排程新的協調流程執行個體,以及現有協調流程執行個體接收到事件時,就會執行此觸發程序。 可觸發協調器函式的事件範例包括長期計時器到期、活動函式回應,以及由外部用戶端引發的事件。
當您在 .NET 中撰寫函式時,會使用 OrchestrationTriggerAttribute .NET 屬性來設定協調流程觸發程序。
針對 JAVA, @DurableOrchestrationTrigger
批註是用來設定協調流程觸發程式。
當您撰寫協調器函式時,協調流程觸發程式是由function.json檔案陣列中的 bindings
下列 JSON 物件所定義:
{
"name": "<Name of input parameter in function signature>",
"orchestration": "<Optional - name of the orchestration>",
"type": "orchestrationTrigger",
"direction": "in"
}
orchestration
是此協調流程的名稱,且為用戶端在想要啟動這個協調器函式的新執行個體時必須使用的值。 這是選用屬性。 如果未指定,會使用函式的名稱。
Azure Functions支援兩個適用于 Python 的程式設計模型。 您定義協調流程觸發程式的方式取決於您選擇的程式設計模型。
在內部,觸發程序繫結會輪詢新協調流程事件的已設定長期存放區,例如協調流程啟動事件、長期計時器到期事件、活動函式回應事件,以及由其他函式引發的外部事件。
觸發程序行為
以下是協調流程觸發程序的一些附註:
- 單一執行緒 - 單一發送器執行緒用於單一主機執行個體上的所有協調器函式執行。 基於這個理由,請務必確保協調器函式程式碼有效率,且不會執行任何 I/O。 也務必要確保此執行緒不會執行除了等候長期函式特定工作類型以外的任何非同步工作。
- 有害訊息處理 - 協調流程觸發程序中並無支援有害訊息。
- 訊息可見度 - 協調流程觸發程序訊息會被清除佇列,並且在可設定持續期間保持不可見。 只要函式應用程式正在執行且狀況良好,就會自動更新這些訊息的可見度。
- 傳回值 - 傳回值會序列化為 JSON,保存到 Azure 資料表儲存體中的協調流程歷程記錄資料表。 協調流程用戶端繫結可以查詢這些傳回值,會在稍後說明。
警告
協調器函式應該永不使用協調流程繫結觸發程序繫結以外的任何輸入或輸出繫結。 這麼做有可能會造成長期工作延伸模組的問題,因為這些繫結可能不會遵照單一執行緒和 I/O 規則。 如果您想使用其他繫結,請將繫結新增至從協調器函式呼叫的活動函式。 如需協調器函式編碼條件約束的詳細資訊,請參閱協調器函式程式碼條件約束文件。
警告
協調器函式不應宣告 async
為 。
觸發程序使用方式
協調流程觸發程序繫結支援輸入及輸出。 協助了解輸入和輸出處理的一些事項如下:
- 輸入 - 協調流程觸發程序可透過內容輸入物件存取的輸入來叫用。 所有輸入都必須是可序列化的 JSON。
- 輸出 - 協調流程觸發程序支援輸出值以及輸入。 函式的傳回值會用來指派輸出值,而且必須是 JSON 可序列化。
觸發程序範例
以下範例程式碼顯示最簡單的 "Hello World" 協調器函式內容。 請注意,此範例協調器實際上不會排程任何工作。
用來定義觸發程式的特定屬性取決於您是在 進程 內或 隔離背景工作進程中執行 C# 函式。
[FunctionName("HelloWorld")]
public static string Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
string name = context.GetInput<string>();
return $"Hello {name}!";
}
注意
先前的程式碼適用於 Durable Functions 2.x。 針對 Durable Functions 1.x,您必須使用 DurableOrchestrationContext
而不是 IDurableOrchestrationContext
。 如需版本差異的詳細資訊,請參閱 Durable Functions 版本一文。
const df = require("durable-functions");
module.exports = df.orchestrator(function*(context) {
const name = context.df.getInput();
return `Hello ${name}!`;
});
注意
當產生器函式結束時,durable-functions
程式庫會負責呼叫同步 context.done
方法。
param($Context)
$InputData = $Context.Input
$InputData
@FunctionName("HelloWorldOrchestration")
public String helloWorldOrchestration(
@DurableOrchestrationTrigger(name = "ctx") TaskOrchestrationContext ctx) {
return String.format("Hello %s!", ctx.getInput(String.class));
}
大部分協調器函式會呼叫活動函式;因此,這裡的 "Hello World" 範例示範如何呼叫活動函式:
[FunctionName("HelloWorld")]
public static async Task<string> Run(
[OrchestrationTrigger] IDurableOrchestrationContext context)
{
string name = context.GetInput<string>();
string result = await context.CallActivityAsync<string>("SayHello", name);
return result;
}
注意
先前的程式碼適用於 Durable Functions 2.x。 針對 Durable Functions 1.x,您必須使用 DurableOrchestrationContext
而不是 IDurableOrchestrationContext
。 如需版本差異的詳細資訊,請參閱 Durable Functions 版本一文。
const df = require("durable-functions");
module.exports = df.orchestrator(function*(context) {
const name = context.df.getInput();
const result = yield context.df.callActivity("SayHello", name);
return result;
});
@FunctionName("HelloWorld")
public String helloWorldOrchestration(
@DurableOrchestrationTrigger(name = "ctx") TaskOrchestrationContext ctx) {
String input = ctx.getInput(String.class);
String result = ctx.callActivity("SayHello", input, String.class).await();
return result;
}
活動觸發程序
活動觸發程序可讓您撰寫由協調器函式呼叫的函式,其又稱為活動觸發程序。
活動觸發程式是使用 ActivityTriggerAttribute .NET 屬性來設定。
活動觸發程式是使用批註來 @DurableActivityTrigger
設定。
活動觸發程式是由function.json陣列中的 bindings
下列 JSON 物件所定義:
{
"name": "<Name of input parameter in function signature>",
"activity": "<Optional - name of the activity>",
"type": "activityTrigger",
"direction": "in"
}
activity
是活動的名稱。 此值是協調器函式用來叫用此活動函式的名稱。 這是選用屬性。 如果未指定,會使用函式的名稱。
在內部,觸發程序繫結會輪詢已設定的長期存放區以取得新的活動執行事件。
觸發程序行為
以下是活動觸發程序的一些附註:
- 執行緒 - 與協調流程觸發程序不同,活動觸發程序在執行緒或 I/O 方面沒有任何限制。 它們可以被視為一般函式。
- 有害訊息處理 - 活動觸發程序中並無支援有害訊息。
- 訊息可見度 - 活動觸發程序訊息會被清除佇列,並且在可設定持續期間保持不可見。 只要函式應用程式正在執行且狀況良好,就會自動更新這些訊息的可見度。
- 傳回值 - 傳回值會序列化為 JSON,並保存到已設定的長期存放區。
觸發程序使用方式
活動觸發程序繫結支援輸入及輸出,就像協調流程觸發程序一樣。 協助了解輸入和輸出處理的一些事項如下:
- 輸入 - 可以使用協調器函式的輸入來叫用活動觸發程序。 所有輸入都必須是可序列化的 JSON。
- 輸出 - 活動函式支援輸出值和輸入。 函式的傳回值會用來指派輸出值,而且必須是 JSON 可序列化。
- 中繼資料:.NET 活動函式可以繫結至
string instanceId
參數,以取得呼叫協調流程的執行個體識別碼。
觸發程序範例
下列範例程式碼顯示簡單 SayHello
活動函式的外觀。
[FunctionName("SayHello")]
public static string SayHello([ActivityTrigger] IDurableActivityContext helloContext)
{
string name = helloContext.GetInput<string>();
return $"Hello {name}!";
}
.NET ActivityTriggerAttribute
繫結的預設參數類型為 IDurableActivityCoNtext (或 Durable Functions v1 的 DurableActivityCoNtext)。 不過,.NET活動觸發程序也支援直接繫結至JSON 可序列化類型 (包括基本類型),因此,同一個函式可以簡化如下:
[FunctionName("SayHello")]
public static string SayHello([ActivityTrigger] string name)
{
return $"Hello {name}!";
}
module.exports = async function(context) {
return `Hello ${context.bindings.name}!`;
};
JavaScript 繫結也能以額外參數形式傳入,因此,同一個函式可以簡化如下:
module.exports = async function(context, name) {
return `Hello ${name}!`;
};
param($name)
"Hello $name!"
@FunctionName("SayHello")
public String sayHello(@DurableActivityTrigger(name = "name") String name) {
return String.format("Hello %s!", name);
}
使用輸入與輸出繫結
除了活動觸發程序繫結之外,您還可以使用一般輸入和輸出繫結。
例如,您可以將活動繫結的輸入,使用 EventHub 輸出繫結傳送訊息至 EventHub:
{
"bindings": [
{
"name": "message",
"type": "activityTrigger",
"direction": "in"
},
{
"type": "eventHub",
"name": "outputEventHubMessage",
"connection": "EventhubConnectionSetting",
"eventHubName": "eh_messages",
"direction": "out"
}
]
}
module.exports = async function (context) {
context.bindings.outputEventHubMessage = context.bindings.message;
};
協調流程用戶端
協調流程用戶端繫結可讓您撰寫與協調器函式互動的函式。 這些函式通常稱為用戶端函式。 例如,您可以下列方式處理協調流程執行個體:
- 啟動它們。
- 查詢其狀態。
- 終止它們。
- 在它們執行時傳送事件給它們。
- 清除執行個體記錄。
您可以在 Durable Functions v1.x) 中使用DurableClientAttribute屬性 (OrchestrationClientAttribute系結至協調流程用戶端。
您可以使用注釋系結至協調流程用戶端 @DurableClientInput
。
永久性用戶端觸發程式是由function.json陣列中的 bindings
下列 JSON 物件所定義:
{
"name": "<Name of input parameter in function signature>",
"taskHub": "<Optional - name of the task hub>",
"connectionName": "<Optional - name of the connection string app setting>",
"type": "orchestrationClient",
"direction": "in"
}
taskHub
- 在多個函式應用程式共用相同儲存體帳戶,但是必須相互隔離的案例中使用。 若未指定,就會使用host.json
的預設值。 此值必須符合目標協調器函式所使用的值。connectionName
- 包含儲存體帳戶連接字串的應用程式設定名稱。 這個連接字串代表的儲存體帳戶,必須是目標協調器函式使用的相同帳戶。 如果未指定,則會使用函數應用程式的預設儲存體帳戶連接字串。
注意
在大部分情況下,建議您省略這些屬性,並依賴預設行為。
用戶端使用方式
您通常會系結至 Durable Functions v1.x) 中的IDurableClient (DurableOrchestrationClient,這可讓您完整存取Durable Functions支援的所有協調流程用戶端 API。
您通常會系結至 DurableClientContext
類別。
您必須使用特定語言的 SDK 來存取用戶端物件。
以下是範例佇列觸發函式,它會啟動 "HelloWorld" 協調流程。
[FunctionName("QueueStart")]
public static Task Run(
[QueueTrigger("durable-function-trigger")] string input,
[DurableClient] IDurableOrchestrationClient starter)
{
// Orchestration input comes from the queue message content.
return starter.StartNewAsync("HelloWorld", input);
}
注意
先前的 C# 程式碼適用於 Durable Functions 2.x。 針對 Durable Functions 1.x,您必須使用 OrchestrationClient
屬性 (而非 DurableClient
屬性),而且必須使用 DurableOrchestrationClient
參數類型 (而非 IDurableOrchestrationClient
)。 如需版本差異的詳細資訊,請參閱 Durable Functions 版本一文。
function.json
{
"bindings": [
{
"name": "input",
"type": "queueTrigger",
"queueName": "durable-function-trigger",
"direction": "in"
},
{
"name": "starter",
"type": "durableClient",
"direction": "in"
}
]
}
index.js
const df = require("durable-functions");
module.exports = async function (context) {
const client = df.getClient(context);
return instanceId = await client.startNew("HelloWorld", undefined, context.bindings.input);
};
run.ps1
param([string] $input, $TriggerMetadata)
$InstanceId = Start-DurableOrchestration -FunctionName $FunctionName -Input $input
import azure.functions as func
import azure.durable_functions as df
myApp = df.DFApp(http_auth_level=func.AuthLevel.ANONYMOUS)
@myApp.route(route="orchestrators/{functionName}")
@myApp.durable_client_input(client_name="client")
async def durable_trigger(req: func.HttpRequest, client):
function_name = req.route_params.get('functionName')
instance_id = await client.start_new(function_name)
response = client.create_check_status_response(req, instance_id)
return response
function.json
{
"bindings": [
{
"name": "input",
"type": "queueTrigger",
"queueName": "durable-function-trigger",
"direction": "in"
},
{
"name": "starter",
"type": "durableClient",
"direction": "in"
}
]
}
run.ps1
param([string]$InputData, $TriggerMetadata)
$InstanceId = Start-DurableOrchestration -FunctionName 'HelloWorld' -Input $InputData
@FunctionName("QueueStart")
public void queueStart(
@QueueTrigger(name = "input", queueName = "durable-function-trigger", connection = "Storage") String input,
@DurableClientInput(name = "durableContext") DurableClientContext durableContext) {
// Orchestration input comes from the queue message content.
durableContext.getClient().scheduleNewOrchestrationInstance("HelloWorld", input);
}
啟動執行個體的更多詳細資料可以在執行個體管理中找到。
實體觸發程序
實體觸發程序讓您能夠撰寫實體函式。 此觸發程序支援處理特定實體執行個體的事件。
注意
從 Durable Functions 2.x 開始可以使用實體觸發程序。
在內部,此觸發程序繫結會輪詢已設定的長期存放區,以取得需要執行的新實體作業。
實體觸發程式是使用 EntityTriggerAttribute .NET 屬性來設定。
注意
隔離的背景工作進程應用程式尚不支援實體觸發程式。
實體觸發程式是由function.json陣列中的 bindings
下列 JSON 物件所定義:
{
"name": "<Name of input parameter in function signature>",
"entityName": "<Optional - name of the entity>",
"type": "entityTrigger",
"direction": "in"
}
根據預設,實體名稱就是函式的名稱。
注意
JAVA 尚不支援實體觸發程式。
觸發程序行為
以下是實體觸發程序的一些注意事項:
- 單一執行緒:單一發送器執行緒是用來處理特定實體的作業。 如果同時將多個訊息傳送至單一實體,則會一次處理一個作業。
- 有害訊息處理 - 實體觸發程序中並未支援有害訊息。
- 訊息可見度 - 實體觸發程序訊息會被清除佇列,並且在可設定的持續期間內保持不可見。 只要函式應用程式正在執行且狀況良好,就會自動更新這些訊息的可見度。
- 傳回值 - 實體函式不支援傳回值。 有特定 API 可用來儲存狀態或將值傳回協調流程。
在實體執行期間對其所做的任何狀態變更,都會在執行完成後自動儲存。
如需定義實體觸發程序給與其互動的詳細資訊和範例,請參閱持久性實體文件。
實體用戶端
實體用戶端繫結可讓您以非同步方式觸發實體函式。 這些函式有時稱為用戶端函式。
您可以在 .NET 類別庫函式中使用 DurableClientAttribute .NET 屬性系結至實體用戶端。
注意
[DurableClientAttribute]
也可以用來繫結至協調流程用戶端。
實體用戶端是由function.json陣列中的 bindings
下列 JSON 物件所定義:
{
"name": "<Name of input parameter in function signature>",
"taskHub": "<Optional - name of the task hub>",
"connectionName": "<Optional - name of the connection string app setting>",
"type": "durableClient",
"direction": "in"
}
taskHub
- 在多個函式應用程式共用相同儲存體帳戶,但是必須相互隔離的案例中使用。 若未指定,就會使用host.json
的預設值。 此值必須符合目標實體函式所使用的值。connectionName
- 包含儲存體帳戶連接字串的應用程式設定名稱。 這個連接字串代表的儲存體帳戶,必須是目標實體函式使用的相同帳戶。 如果未指定,則會使用函數應用程式的預設儲存體帳戶連接字串。
注意
在大部分情況下,建議您省略選用的屬性,並依賴預設行為。
注意
JAVA 尚不支援實體用戶端。
如需以用戶端身分與實體互動的詳細資訊和範例,請參閱持久性實體文件。
host.json 設定
Durable Functions 的組態設定。
注意
Azure Functions 執行階段的所有版本,都支援 Durable Functions 的所有主要版本。 不過,根據您所使用的 Azure Functions 執行階段和 Durable Functions 延伸模組版本,host.json 設定的架構會稍有不同。 下列範例適用於 Azure Functions 2.0 和 3.0。 在這兩個範例中,如果您使用 Azure Functions 1.0,則可用的設定相同,但 host.json 的 [durableTask] 區段應位於 host.jso 設定的根目錄中,而不是在 [延伸模組] 下的欄位。
{
"extensions": {
"durableTask": {
"hubName": "MyTaskHub",
"storageProvider": {
"connectionStringName": "AzureWebJobsStorage",
"controlQueueBatchSize": 32,
"controlQueueBufferThreshold": 256,
"controlQueueVisibilityTimeout": "00:05:00",
"maxQueuePollingInterval": "00:00:30",
"partitionCount": 4,
"trackingStoreConnectionStringName": "TrackingStorage",
"trackingStoreNamePrefix": "DurableTask",
"useLegacyPartitionManagement": true,
"workItemQueueVisibilityTimeout": "00:05:00",
},
"tracing": {
"traceInputsAndOutputs": false,
"traceReplayEvents": false,
},
"notifications": {
"eventGrid": {
"topicEndpoint": "https://topic_name.westus2-1.eventgrid.azure.net/api/events",
"keySettingName": "EventGridKey",
"publishRetryCount": 3,
"publishRetryInterval": "00:00:30",
"publishEventTypes": [
"Started",
"Pending",
"Failed",
"Terminated"
]
}
},
"maxConcurrentActivityFunctions": 10,
"maxConcurrentOrchestratorFunctions": 10,
"extendedSessionsEnabled": false,
"extendedSessionIdleTimeoutInSeconds": 30,
"useAppLease": true,
"useGracefulShutdown": false,
"maxEntityOperationBatchSize": 50
}
}
}
工作中樞名稱必須以字母開頭,且只包含字母和數字。 如果未指定,函式應用程式的預設工作中樞名稱為 TestHubName。 如需詳細資訊,請參閱工作中樞。
屬性 | 預設 | 描述 |
---|---|---|
hubName | 如果使用 Durable Functions 1.x) TestHubName (DurableFunctionsHub | 替代工作中樞名稱可用來彼此隔離多個 Durable Functions 應用程式,即使它們使用相同的儲存體後端。 |
controlQueueBatchSize | 32 | 要從控制佇列中一次提取的訊息數。 |
controlQueueBufferThreshold | Python 的使用量方案:32 JavaScript 和 C# 的使用量方案:128 專用/進階方案:256 |
可以在記憶體中一次緩衝處理的控制佇列訊息數目,到達這個數目之後發送器會在針對任何其他訊息清除佇列之前等待。 |
partitionCount | 4 | 控制佇列的資料分割計數。 必須是介於 1 到 16 之間的正整數。 |
controlQueueVisibilityTimeout | 5 分鐘 | 已從控制佇列中清除之訊息的可見度逾時。 |
workItemQueueVisibilityTimeout | 5 分鐘 | 已清除佇列之工作項目佇列訊息的可見度逾時。 |
maxConcurrentActivityFunctions | 使用量方案:10 專用/進階方案:目前機器上處理器數目的 10 倍 |
可以在單一主機執行個體上同時處理的活動函式數目上限。 |
maxConcurrentOrchestratorFunctions | 使用量方案:5 專用/進階方案:目前機器上處理器數目的 10 倍 |
可以在單一主機執行個體上同時處理的協調器函式數目上限。 |
maxQueuePollingInterval | 30 秒 | 最大控制和工作項目佇列輪詢間隔的格式為「hh:mm:ss」。 較高的值可能會導致訊息處理延遲較高。 較低的值會因為儲存體交易增加而導致儲存成本較高。 |
connectionName (2.7.0 和更新版本) connectionStringName (2.x) azureStorageConnectionStringName (1.x) |
AzureWebJobsStorage | 應用程式設定或設定集合的名稱,該名稱會指定連線到基礎 Azure 儲存體資源的方式。 提供單一應用程式設定時,它應該是 Azure 儲存體連接字串。 |
trackingStoreConnectionName (2.7.0 和更新版本) trackingStoreConnectionStringName |
指定如何連線到記錄和執行個體表格的應用程式設定或設定集合名稱。 提供單一應用程式設定時,它應該是 Azure 儲存體連接字串。 如果未指定,則會使用 connectionStringName (Durable 2.x) 或 azureStorageConnectionStringName (Durable 1.x) 連線。 |
|
trackingStoreNamePrefix | 指定 trackingStoreConnectionStringName 時,用於歷程記錄和執行個體資料表的前置詞。 如果未設定,預設的前置詞值將會是 DurableTask 。 如果未指定 trackingStoreConnectionStringName ,則歷程記錄和執行個體資料表會使用 hubName 值作為其前置詞,而且會忽略 trackingStoreNamePrefix 的任何設定。 |
|
traceInputsAndOutputs | false | 此值指出是否要追蹤函式呼叫的輸入和輸出。 追蹤函式執行事件時的預設行為就是在函式呼叫的序列化輸入和輸出中包含位元組數目。 此行為可提供輸入和輸出的最基本資訊,而不會讓記錄變大,或者不小心公開敏感性資訊。 將此屬性設定為 true,會導致預設函式記錄功能記錄函式輸入和輸出的整個內容。 |
traceReplayEvents | false | 此值可指出是否要將協調流程重新執行事件寫入 Application Insights。 |
eventGridTopicEndpoint | Azure 事件方格自訂主題端點的 URL。 若已設定這個屬性,協調流程生命週期通知事件就會發佈到此端點。 這個屬性支援應用程式設定解析。 | |
eventGridKeySettingName | 應用程式設定的名稱,其中包含在 EventGridTopicEndpoint 用來向 Azure 事件方格自訂主題進行驗證的金鑰。 |
|
eventGridPublishRetryCount | 0 | 如果發佈到 Event Grid 主題失敗,重試的次數。 |
eventGridPublishRetryInterval | 5 分鐘 | 「事件方格」會以 hh:mm:ss 格式發佈重試間隔。 |
eventGridPublishEventTypes | 要發佈到事件方格的事件類型清單。 如果未指定,則會發佈所有事件種類。 允許的值包括 Started 、Completed 、Failed 或 Terminated 。 |
|
useAppLease | true | 設定為 true 時,應用程式必須在處理工作中樞訊息之前,取得應用程式層級的 Blob 租用。 如需詳細資訊,請參閱災害復原和異地分佈文件。 從 v2.3.0 開始可供使用。 |
useLegacyPartitionManagement | false | 設為 false 時,會使用資料分割管理演算法,以降低擴增時函式重複執行的可能性。從 v2.3.0 開始可供使用。 |
useGracefulShutdown | false | (預覽) 啟用正常關機以減少主機關機讓內含式函式執行失敗的機會。 |
maxEntityOperationBatchSize(2.6.1) | 使用量方案:50 專用/進階方案:5000 |
以批次方式處理的實體作業數目上限。 如果上限設為 1,則會停用批次處理,而且每個作業訊息都會由個別的函式引動來處理。 |
上述許多設定適用於將效能最佳化。 如需詳細資訊,請參閱效能和擴充。