我想以批处理方式接收来自Azure ServiceBus主题的消息。
阅读https://docs.microsoft.com/en-us/azure/azure-functions/functions-best-practices时指出:
对于C#函数,您可以将类型更改为强类型数组。例如,方法签名可以是EventData [] sensorEvent,而不是EventData sensorEvent。
我有一个方法:
public static void Run([ServiceBusTrigger("mytopic name", "MySubscription",
AccessRights.Listen, Connection = TopicService.ConnectionStringName)]
string messages, TraceWriter logger)
此方法有效,但一次需要1条消息。
根据Microsoft文档,我可以将其更改为:
public static void Run([ServiceBusTrigger("mytopic name", "MySubscription",
AccessRights.Listen, Connection = TopicService.ConnectionStringName)]
string[] messages, TraceWriter logger)
并将以下内容添加到host.json文件(https://docs.microsoft.com/en-us/azure/azure-functions/functions-host-json):
{
"aggregator": {
"batchSize": 10,
"flushTimeout": "00:00:30"
}
}
但是运行该函数时,出现异常:
mscorlib:执行函数MyFunction时发生异常。 Microsoft.Azure.WebJobs.Host:异常绑定参数“ messages”。 System.Runtime.Serialization:反序列化类型为System.String []的对象时出错。输入源的格式不正确。 System.Runtime.Serialization:输入源的格式不正确。
注意:主题和订阅已启用设置“启用批处理操作”。
我在这里想念什么?
答案 0 :(得分:0)
这是我尝试的代码。检查并查看是否有效。
//---------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
using Microsoft.Azure;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ServiceBusTriggers
{
class Settings
{
public const string TopicPath = "sbperftopicwithpartitions";
public const string Subscription = "sub_1";
public const string ContainerName = "sbperf-test-store2";
internal Settings()
{
ServiceBusConnectionString = GetSetting("ServiceBusConnectionString", UserSettings.ServiceBusConnectionString);
StorageAccountConnectionString = GetSetting("StorageAccountConnectionString", UserSettings.StorageAccountConnectionString);
AzureWebJobsDashboardConnectionString = GetSetting("AzureWebJobsDashboardConnectionString", UserSettings.AzureWebJobsDashboardConnectionString);
AzureWebJobsStorageConnectionString = GetSetting("AzureWebJobsStorageConnectionString", UserSettings.AzureWebJobsStorageConnectionString);
NLogDatabaseConnectionString = GetSetting("NLogDatabaseConnectionString", UserSettings.NLogDatabaseConnectionString);
PrefetchCount = GetSetting("PrefetchCount", 100);
MaxConcurrentCalls = GetSetting("MaxConcurrentCalls",100);
MetricsDisplayFrequency = new TimeSpan(0, 0, 30); //every 30 seconds
TokenSource = new CancellationTokenSource();
}
private int GetSetting(string name, int defaultValue)
{
int value;
string valueStr = CloudConfigurationManager.GetSetting(name);
if (!int.TryParse(valueStr, out value))
{
Console.WriteLine("Config missing for {0}. Using default.",name);
value = defaultValue;
}
return value;
}
private string GetSetting(string name, string defaultValue)
{
string valueStr = CloudConfigurationManager.GetSetting(name);
if (string.IsNullOrEmpty(valueStr))
{
Console.WriteLine("Config missing for {0}. Using default.", name);
valueStr = defaultValue;
}
return valueStr;
}
public string ServiceBusConnectionString { get; set; }
public string StorageAccountConnectionString { get; set; }
public int PrefetchCount { get; set; }
public int MaxConcurrentCalls { get; set; }
public TimeSpan MetricsDisplayFrequency { get; internal set; }
public CancellationTokenSource TokenSource { get; set; }
public string NLogDatabaseConnectionString { get; private set; }
public static string AzureWebJobsDashboardConnectionString { get; internal set; }
public static string AzureWebJobsStorageConnectionString { get; internal set; }
public void WriteSettings()
{
ProjectLogger.Info("1|None|{1}|DisplayFrequency|{0}|", MetricsDisplayFrequency, Thread.CurrentThread.ManagedThreadId);
ProjectLogger.Info("1|None|{1}|PrefetchCount|{0}|", PrefetchCount, Thread.CurrentThread.ManagedThreadId);
ProjectLogger.Info("1|None|{1}|MaxConcurrentCalls|{0}|", MaxConcurrentCalls, Thread.CurrentThread.ManagedThreadId);
}
}
}
这是我的程序文件
//---------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
//---------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.ServiceBus;
using Microsoft.ServiceBus.Messaging;
using Microsoft.Azure;
namespace ServiceBusTriggers
{
// To learn more about Microsoft Azure WebJobs SDK, please see https://go.microsoft.com/fwlink/?LinkID=320976
class Program
{
// Please set the following connection strings in app.config for this WebJob to run:
// AzureWebJobsDashboard and AzureWebJobsStorage
static void Main()
{
var config = new JobHostConfiguration();
if (config.IsDevelopment)
{
config.UseDevelopmentSettings();
}
Settings settings = new Settings();
config.DashboardConnectionString = Settings.AzureWebJobsDashboardConnectionString;
config.StorageConnectionString = Settings.AzureWebJobsStorageConnectionString;
ServiceBusConfiguration sbconfig = new ServiceBusConfiguration()
{
ConnectionString = settings.ServiceBusConnectionString,
PrefetchCount = settings.PrefetchCount,
MessageOptions = new OnMessageOptions
{
MaxConcurrentCalls = settings.MaxConcurrentCalls
}
};
config.UseServiceBus(sbconfig);
Functions.Initialize(settings);
var host = new JobHost(config);
// The following code ensures that the WebJob will be running continuously
host.RunAndBlock();
}
}
}
这是我的功能文件
public class Functions
{
static CloudStorageAccount storageAccount = null;
static Metrics metrics = null;
static Settings Settings = null;
internal static void Initialize(Settings settings)
{
Settings = settings;
Initialize();
}
static void Initialize()
{
ProjectLogger.Initialize(Settings);
storageAccount = CloudStorageAccount.Parse(Settings.StorageAccountConnectionString);
WriteMessageCount();
metrics = new Metrics(Settings);
metrics.StartMetricsTask(Settings.TokenSource.Token).Fork();
}
public static async Task ProcessTopicAsync(
[ServiceBusTrigger(Settings.TopicPath, Settings.Subscription )]
BrokeredMessage message)
{
Stopwatch sw = Stopwatch.StartNew();
await WriteToBlob(message);
sw.Stop();
metrics.IncreaseProcessMessages(1);
metrics.IncreaseProcessBatch(1);
metrics.IncreaseProcessLatency(sw.Elapsed.TotalMilliseconds);
}
private static async Task WriteToBlob(BrokeredMessage message)
{
var data = message.GetBody<byte[]>();
var blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference(Settings.ContainerName);
await container.CreateIfNotExistsAsync();
var blob = container.GetBlockBlobReference(Guid.NewGuid().ToString());
await blob.UploadFromByteArrayAsync(data, 0, data.Length);
}
static void WriteMessageCount()
{
var namespaceManager = NamespaceManager.CreateFromConnectionString(Settings.ServiceBusConnectionString);
var subscriptionDesc = namespaceManager.GetSubscription(Settings.TopicPath, Settings.Subscription);
long subMessageCount = subscriptionDesc.MessageCount;
ProjectLogger.Info("1|None|{1}|MessagesinSub|{0}|", subMessageCount, Thread.CurrentThread.ManagedThreadId);
}
}
有关更多信息,您可以浏览以下github存储库
https://github.com/tcsatheesh/samples/blob/master/ServiceBusTrigger/Functions.cs
希望有帮助。