多个 Azure EventHub 触发器到 Azure Function 应用程序中的单个函数

Multiple Azure EventHub trigger to single function in Azure Function app

我想从两个不同的事件中心执行相同的功能(根据消息数据进行少量更改)。

是否可以将两个消费者组附加到一个函数。

即使我将它添加到 function.json 也没有用。

简短的回答是否定的。您不能将多个输入触发器绑定到同一个函数: https://github.com/Azure/azure-webjobs-sdk-script/wiki/function.json

A function can only have a single trigger binding, and can have multiple input/output bindings.

但是,您可以通过将共享代码包装在辅助方法中或使用 Precompiled Functions.

从多个函数调用相同的 "shared" 代码

这里推荐的做法是利用单个功能应用程序可以由多个功能组成的事实,在功能之间共享业务逻辑。

MyFunctionApp
|     host.json
|____ business
|     |____ logic.js
|____ function1
|     |____ index.js
|     |____ function.json
|____ function2
      |____ index.js
      |____ function.json

在"function1/index.js"和"function2/index.js"

var logic = require("../business/logic");

module.exports = logic;

function1和function2的function.json可以配置不同的触发器。

在“business/logic.js

module.exports = function (context, req) {
    // This is where shared code goes. As an example, for an HTTP trigger:
    context.res = {
        body: "<b>Hello World</b>",
        status: 201,
        headers: {
            'content-type': "text/html"
        }
    };     
    context.done();
};

Is it possible to attach two consumer group to a single function.

假设您正在寻找触发器并且不想在函数内部执行 your own polling using EventProcessorClient。因为您可以安排一个函数定期使用 API 从多个事件中心获取消息并处理它们。但是您需要实现使用触发器时获得的所有 built-in 逻辑(轮询、处理多个分区、check-pointing、缩放等)。

几个解决方法:

  1. 捕获:如果事件中心位于同一个命名空间中,您可以在所有事件中心上启用捕获。然后为您的函数创建一个 event grid trigger 。您将收到一条包含捕获文件路径的消息。例如
{
    "topic": "/subscriptions/9fac-4e71-9e6b-c0fa7b159e78/resourcegroups/kash-test-01/providers/Microsoft.EventHub/namespaces/eh-ns",
    "subject": "eh-1",
    "eventType": "Microsoft.EventHub.CaptureFileCreated",
    "id": "b5aa3f62-15a1-497a-b97b-e688d4368db8",
    "data": {
        "fileUrl": "https://xxx.blob.core.windows.net/capture-fs/eh-ns/eh-1/0/2020/10/28/21/39/01.avro",
        "fileType": "AzureBlockBlob",
        "partitionId": "0",
        "sizeInBytes": 8011,
        "eventCount": 5,
        "firstSequenceNumber": 5,
        "lastSequenceNumber": 9,
        "firstEnqueueTime": "2020-10-28T21:40:28.83Z",
        "lastEnqueueTime": "2020-10-28T21:40:28.908Z"
    },
    "dataVersion": "1",
    "metadataVersion": "1",
    "eventTime": "2020-10-28T21:41:02.2472744Z"
}

显然这不是real-time,您可以设置的最短捕获时间为 1 分钟,捕获的 avro 文件写入时间和写入时间之间可能会有一点延迟您的函数已被调用。

  1. 至少在 Java 中没有限制每个函数必须有一个单独的 class。所以你可以这样做:
public class EhConsumerFunctions {
    private void processEvent(String event) {
        // process...
    }

    @FunctionName("eh1_consumer")
    public void eh1_consumer(
        @EventHubTrigger(name = "event", eventHubName = "eh-ns", connection = "EH1_CONN_STR") String event,
        final ExecutionContext context) {
        processEvent(event);
    }

    @FunctionName("eh2_consumer")
    public void eh2_consumer(
        @EventHubTrigger(name = "event", eventHubName = "eh-ns", connection = "EH2_CONN_STR") String event,
        final ExecutionContext context) {
        processEvent(event);
    }

}

并在您的应用设置中定义 EH1_CONN_STREH2_CONN_STR