英文:
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("TestFunction")]
public async Task<TestFunctionResult> Run([HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequestData req)
{
_logger.LogInformation("C# HTTP trigger function processed a request.");
// 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("First Last", "My Company"),
HttpResponse = response
};
}
This is the definition of TestFunctionResult
public class TestFunctionResult
{
[ServiceBusOutput("TestTopic", Connection = "ServiceBus", 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": "您的连接字符串"
}
}
输出-
门户-
之前-
之后-
英文:
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-
{
"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 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("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 file-
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
"ServiceBusConnection": "your connection string"
}
}
Output-
Portal-
Before-
After-
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论