使用 Microsoft.Azure.WebJobs.QueueAttribute 迁移 NET 8 隔离进程

问题描述 投票:0回答:1

我在将 Azure Functions 迁移到 .NET 8 独立进程模型时遇到多个触发错误。我一直在尽我所能排除故障,但无法查明确切原因。

为了提供更多背景信息,这里有一些附加信息(如果适用):

  • 使用 Microsoft.Azure.WebJobs; (隔离模式不支持)已用于以下参数 [Queue("%SaveClientStorageQueue%", Connection = "StorageQueueConnectionString")] CloudQueue cloudQueue 更改为下面的解决了编译上述代码的错误,但导致了多个错误触发器,我认为我犯了错误,它不应该是触发器,但不确定如何实现正确的触发器。 -[QueueTrigger("%SaveClientStorageQueue%", Connection = "StorageQueueConnectionString")] CloudQueue cloudQueue

如果您能提供任何见解或建议来帮助我解决这些触发错误并成功完成迁移,我将不胜感激。

using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Azure.Functions.Worker.Extensions.Storage;
//using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using Microsoft.WindowsAzure.Storage.Queue;

namespace ClientService
{
    public static class ClientService
    {

 [Function("SaveClientToQueue")]
 [OpenApiOperation("saveclient", "SaveClient")]
 [OpenApiRequestBody("application/json", typeof(SaveClientQueueRequest))]
 [OpenApiResponseWithBody(HttpStatusCode.OK, "application/json", typeof(void))]
 public static async Task SaveClientToQueue([Queue("%SaveClientStorageQueue%", Connection = "StorageQueueConnectionString")] CloudQueue cloudQueue, ILogger log)
 {
    
      try
  {

      var saveClientRequest = await req.ReadFromJsonAsync<SaveClientQueueRequest>();
 
      var saveClientMessageAsJson = JsonConvert.SerializeObject(saveClientRequest);
      log.LogInformation($"HTTP Trigger Save client request received : {saveClientMessageAsJson}");

      var cloudQueueMessage = new CloudQueueMessage(saveClientMessageAsJson);
      await cloudQueue.AddMessageAsync(cloudQueueMessage);

      log.LogInformation($"Message added to Queue: {cloudQueue.Name} , SaveClientMessage: {saveClientMessageAsJson}");

      return req.CreateResponse(HttpStatusCode.OK);
  }
  catch (Exception ex)
  {
      
      log.LogError("An error happened while adding message to save client queue: " + JsonConvert.SerializeObject(await req.ReadFromJsonAsync<SaveClientQueueRequest>()), ex);

      throw;
  }

 
        [Function("SaveClientFromQueue")]
        public static async Task SaveClientFromQueue([QueueTrigger("%SaveClientStorageQueue%", Connection = "StorageQueueConnectionString")] CloudQueueMessage saveClientQueueMessage, ILogger log)
        {
            
            try
            {
                var saveClientMessage = JsonConvert.DeserializeObject<SaveClientQueueRequest>(saveClientQueueMessage.AsString);
                log.LogInformation($"C# QueueTrigger SaveClientFromQueue function processing started for message: {saveClientQueueMessage.AsString}.");                
            }            
            catch (CustomerRegistrationException ex)
            {
                var messageJSON = saveClientQueueMessage.AsString;
                log.LogError($"Error processing SaveClientFromQueue Message: {messageJSON}, DequeueCount: {saveClientQueueMessage.DequeueCount }, Exception Message: { ex.Message}, Exception: {ex}");
                throw;
            }            
            catch (Exception ex)
            {                
                var messageJSON = saveClientQueueMessage.AsString;               
                log.LogError($"Error processing SaveClientFromQueue Message: {messageJSON}, DequeueCount: {saveClientQueueMessage.DequeueCount }, Exception Message: { ex.Message}, Exception: {ex}");
            }
        }

 }

 [Function("KeepAliveFunction")]
 public static void KeepAliveFunction([TimerTrigger("%KeepAliveSchedule%")] TimerInfo timerInfo,  FunctionContext functionContext)
 {
     if (timerInfo.ScheduleStatus is not null)
     {
         var log = functionContext.GetLogger("KeepAliveFunction");
         log.LogInformation("Keep alive triggered for client service");
     }
 }

    }
}

未能找到正确的解决方案,需要有关如何在 NET 8 隔离进程中迁移和正确实现此解决方案的指导。

azure azure-functions migration
1个回答
0
投票
  • 必须安装软件包
    Microsoft.Azure.WebJobs.Extensions.DurableTask

dotnet 8.0 隔离模型必须有以下包:

.cs 项目:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <AzureFunctionsVersion>v4</AzureFunctionsVersion>
    <OutputType>Exe</OutputType>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.20.1" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.DurableTask" Version="1.1.2" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.1.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="1.2.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.16.4" />
    <PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.21.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.1.0" />
  </ItemGroup>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
  <ItemGroup>
    <Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext" />
  </ItemGroup>
</Project>
  • 不要使用
    CloudQueue
    ,而是使用表示消息负载的参数类型,例如
    string
    CloudQueueMessage
    ,或表示队列消息的自定义类。
  • 更改函数参数以匹配您期望从队列中获得的消息类型。如果您想直接处理消息负载,请使用代表消息负载的类型,例如
    string
    或自定义类。

以下代码是隔离迁移到dotnet 8.0。检查如下: 代码:

using System;
using System.Net;
using System.Threading.Tasks;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;

namespace ClientService
{
    public static class ClientService
    {
        [Function("SaveClientToQueue")]
        public static async Task SaveClientToQueue(
            [HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestData req,
            [QueueOutput("%SaveClientStorageQueue%", Connection = "StorageQueueConnectionString")] IAsyncCollector<string> outputQueue,
            FunctionContext context)
        {
            var logger = context.GetLogger("SaveClientToQueue");

            try
            {
                var requestBody = await req.ReadAsStringAsync();
                var saveClientRequest = JsonConvert.DeserializeObject<SaveClientQueueRequest>(requestBody);
                var saveClientMessageAsJson = JsonConvert.SerializeObject(saveClientRequest);

                await outputQueue.AddAsync(saveClientMessageAsJson);

                logger.LogInformation($"HTTP Trigger Save client request received: {saveClientMessageAsJson}");

                var response = req.CreateResponse(HttpStatusCode.OK);
                await response.WriteStringAsync("Client saved successfully.");
            }
            catch (Exception ex)
            {
                logger.LogError("An error occurred while processing the save client request.", ex);
                throw;
            }
        }

        [Function("SaveClientFromQueue")]
        public static void SaveClientFromQueue(
            [QueueTrigger("%SaveClientStorageQueue%", Connection = "StorageQueueConnectionString")] string saveClientQueueMessage,
            ILogger log)
        {
            try
            {
                var saveClientRequest = JsonConvert.DeserializeObject<SaveClientQueueRequest>(saveClientQueueMessage);
                log.LogInformation($"C# QueueTrigger SaveClientFromQueue function processing started for message: {saveClientQueueMessage}");

                // Your processing logic here
            }
            catch (Exception ex)
            {
                log.LogError("An error occurred while processing the message from the save client queue.", ex);
                throw;
            }
        }

        [Function("KeepAliveFunction")]
        public static void KeepAliveFunction(
            [TimerTrigger("%KeepAliveSchedule%")] TimerInfo timerInfo,
            ILogger log)
        {
            if (timerInfo.ScheduleStatus is not null)
            {
                log.LogInformation("Keep alive triggered for client service");
            }
        }
    }

    public class SaveClientQueueRequest
    {
        // Define your request properties here
    }
}

  • SaveClientToQueue
    中,将
    CloudQueue
    参数替换为
    IAsyncCollector<string>
    以将消息输出到队列。
© www.soinside.com 2019 - 2024. All rights reserved.