重试在 Azure Functions 中的服务总线消息发送失败时。

huangapple go评论63阅读模式
英文:

Retry output Service Bus Message on failure in Azure Functions

问题

我有一个HTTP触发器Azure函数。这个函数将持久化一些数据到数据库中,返回HttpResponseData并输出Azure Service Bus消息。

问题是,如果由于任何原因(例如配置错误的服务总线连接字符串),函数无法将消息发送到Service Bus,那么数据已经被持久化,但在服务总线中没有消息。

如何让Azure函数在无法发送消息到Service Bus时进行重试或回滚整个事务?

这是我的函数代码,.NET 6隔离模式。

[Function("TestFunction")]
public async Task<TestFunctionResult> Run([HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequestData req)
{
    _logger.LogInformation("C# HTTP触发器函数处理了一个请求。");

    // 这是将一些数据持久化到数据库的操作
    var result = await _someService.SubmitSomeData(someData);

    // 这是创建HttpResponseData对象的操作
    var response = await req.CreateResponseAsync(result);

    return new TestFunctionResult
    {
        OutputMessage = new TestTopic("First Last", "My Company"),
        HttpResponse = response
    };
}

这是TestFunctionResult的定义

public class TestFunctionResult
{
    [ServiceBusOutput("TestTopic", Connection = "ServiceBus", EntityType = ServiceBusEntityType.Topic)]
    public TestTopic OutputMessage { get; set; }

    public HttpResponseData HttpResponse { get; set; }
}
英文:

I have an HTTP Trigger Azure Function. This function will persist some data into the database, return HttpResponseData and output an Azure Service Bus message.

The case is, if the function can't send the message to Service Bus by any reason (misconfigured service bus connection string, for example), the data is already persisted but there is no message in service bus.

How do I make Azure Functions to retry on failing to send a message to Service Bus or roll back the entire transaction?

This is my function code, .NET 6 Isolated.

[Function(&quot;TestFunction&quot;)]
public async Task&lt;TestFunctionResult&gt; Run([HttpTrigger(AuthorizationLevel.Function, &quot;get&quot;)] HttpRequestData req)
{
    _logger.LogInformation(&quot;C# HTTP trigger function processed a request.&quot;);

    // This is to persist some data to the database
    var result = await _someService.SubmitSomeData(someData);

    // This is to create an HttpResponseData object
    var response = await req.CreateResponseAsync(result);

    return new TestFunctionResult
    {
        OutputMessage = new TestTopic(&quot;First Last&quot;, &quot;My Company&quot;),
        HttpResponse = response
    };
}

This is the definition of TestFunctionResult

public class TestFunctionResult
{
    [ServiceBusOutput(&quot;TestTopic&quot;, Connection = &quot;ServiceBus&quot;, EntityType = ServiceBusEntityType.Topic)]
    public TestTopic OutputMessage { get; set; }

    public HttpResponseData HttpResponse { get; set; }
}

答案1

得分: 1

我已经使用您的代码复现了问题,并且它对我有效。

要在无法将消息发送到Service Bus时进行重试,我已根据文档host.json 文件中添加了以下代码。

host.json 文件-

{
  "version": "2.0",
  "logging": {
    "applicationInsights": {
      "samplingSettings": {
        "isEnabled": true,
        "excludedTypes": "Request"
      }
    }
  },
  "extensions": {
    "serviceBus": {
      "clientRetryOptions": {
        "mode": "exponential",
        "tryTimeout": "00:01:00",
        "delay": "00:00:00.80",
        "maxDelay": "00:01:00",
        "maxRetries": 3
      }
    }
  }
}

function.cs 文件-

using System;
using System.Net;
using System.Text;
using Azure.Messaging.ServiceBus;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker.Extensions.ServiceBus;
    
namespace FunctionApp2
{
    public class TestTopic
    {
        public string Name { get; set; }
        public string Company { get; set; }

        public TestTopic(string name, string company)
        {
            Name = name;
            Company = company;
        }
    }

    public static class Function1
    {
        [Function("TestFunction")]
        public static async Task<TestFunctionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequestData reqs, FunctionContext executionContext)
        {

            var logger = executionContext.GetLogger("TestFunction");

            // This is to create an HttpResponseData object
            var response = reqs.CreateResponse(HttpStatusCode.OK);

            return new TestFunctionResult
            {
                OutputMessage = new TestTopic("First Last", "My Company"),
                HttpResponse = response
            };
        }
    }

    public class TestFunctionResult
    {
        [ServiceBusOutput("TestTopic", Connection = "ServiceBusConnection", EntityType = ServiceBusEntityType.Topic)]
        public TestTopic? OutputMessage { get; set; }
        public HttpResponseData? HttpResponse { get; set; }
    }
}

local.settings.json 文件-

{
    "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
    "ServiceBusConnection": "您的连接字符串"
  }
}

输出-

重试在 Azure Functions 中的服务总线消息发送失败时。

门户-
之前-

重试在 Azure Functions 中的服务总线消息发送失败时。

之后-

重试在 Azure Functions 中的服务总线消息发送失败时。

重试在 Azure Functions 中的服务总线消息发送失败时。

英文:

I have used your code to reproduce the issue and it worked for me.

To retry on failing to send a message to Service Bus, I have added the below code in host.json file as per documentation

host.json file-

{
  &quot;version&quot;: &quot;2.0&quot;,
  &quot;logging&quot;: {
    &quot;applicationInsights&quot;: {
      &quot;samplingSettings&quot;: {
        &quot;isEnabled&quot;: true,
        &quot;excludedTypes&quot;: &quot;Request&quot;
      }
    }
  },
  &quot;extensions&quot;: {
    &quot;serviceBus&quot;: {
      &quot;clientRetryOptions&quot;: {
        &quot;mode&quot;: &quot;exponential&quot;,
        &quot;tryTimeout&quot;: &quot;00:01:00&quot;,
        &quot;delay&quot;: &quot;00:00:00.80&quot;,
        &quot;maxDelay&quot;: &quot;00:01:00&quot;,
        &quot;maxRetries&quot;: 3
      }
    }
  }
}

function.cs file-

using System;
using System.Net;
using System.Text;
using Azure.Messaging.ServiceBus;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker.Extensions.ServiceBus;
    
namespace FunctionApp2
{
    public class TestTopic
    {
        public string Name { get; set; }
        public string Company { get; set; }

        public TestTopic(string name, string company)
        {
            Name = name;
            Company = company;
        }
    }

    public static class Function1
    {
        [Function(&quot;TestFunction&quot;)]
        public static async Task&lt;TestFunctionResult&gt; Run(
            [HttpTrigger(AuthorizationLevel.Function, &quot;get&quot;)] HttpRequestData reqs, FunctionContext executionContext)
        {

            var logger = executionContext.GetLogger(&quot;TestFunction&quot;);

            // This is to create an HttpResponseData object
            var response = reqs.CreateResponse(HttpStatusCode.OK);

            return new TestFunctionResult
            {
                OutputMessage = new TestTopic(&quot;First Last&quot;, &quot;My Company&quot;),
                HttpResponse = response
            };
        }
    }

    public class TestFunctionResult
    {
        [ServiceBusOutput(&quot;TestTopic&quot;, Connection = &quot;ServiceBusConnection&quot;, EntityType = ServiceBusEntityType.Topic)]
        public TestTopic? OutputMessage { get; set; }
        public HttpResponseData? HttpResponse { get; set; }
    }
}

local.settings.json file-

{
    &quot;IsEncrypted&quot;: false,
  &quot;Values&quot;: {
    &quot;AzureWebJobsStorage&quot;: &quot;UseDevelopmentStorage=true&quot;,
    &quot;FUNCTIONS_WORKER_RUNTIME&quot;: &quot;dotnet-isolated&quot;,
    &quot;ServiceBusConnection&quot;: &quot;your connection string&quot;
  }
}

Output-

重试在 Azure Functions 中的服务总线消息发送失败时。

Portal-
Before-

重试在 Azure Functions 中的服务总线消息发送失败时。

After-

重试在 Azure Functions 中的服务总线消息发送失败时。

重试在 Azure Functions 中的服务总线消息发送失败时。

huangapple
  • 本文由 发表于 2023年6月8日 03:29:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/76426549.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定