问题描述
我正在使用带有服务总线触发器的 Azure 函数应用来读取服务总线并处理服务总线消息的内容.服务总线接收 JSON 序列化对象,然后我将 JSON 消息反序列化回函数应用程序中的对象.但是,由于某种原因,每当有东西被发送到服务总线时,触发器就会触发两次,一次是 JSON 消息,另一次是包含文本服务总线消息"的消息.
I'm using Azure Function Apps with a service bus trigger to read a service bus and do stuff with the contents of the service bus message. The service bus receives a JSON serialized object and then I de-serialize the JSON message back to the object in the Function App. However, for some reason whenever something gets sent to the service bus, the trigger fires twice with one being the JSON message and one being a message containing text "Service Bus Message".
我不知道是什么导致了第二条消息,所以我想出的只是反序列化服务总线消息,当它因服务总线消息"而失败时,我将捕获异常并忽略它.但是,我认为这不是处理此问题的正确方法,并且 JSON 反序列化中的实际错误将被忽略.处理第二条消息的正确方法是什么?
I have no idea what causes the second message, so what I came up with is just de-serializing the service bus message and when it fails with the "Service Bus Message", I'll just catch the exception and ignore it. However, I don't think this is the right way to handle this issue and actual errors in JSON de-serialization will be ignored. What is the correct way to handle the second message?
示例代码:
using Newtonsoft.Json;
public static void Run(string myQueueItem, ILogger log, out SendGridMessage mailMessage)
{
MyClass myObject = null;
try
{
myObject = JsonConvert.DeserializeObject<MyClass>(myQueueItem);
// do stuff
}
catch (JsonException je)
{
// ignore this exception
}
catch (Exception e)
{
// handle the other exceptions and send an alert
}
}
我在原帖中遗漏的一件事是我也有一个 SendGrid 输出.我不明白为什么这会对触发器产生任何影响,这就是我忽略它的原因.但是,我现在添加它以防万一它可能是出于某种奇怪的原因.
One thing I did leave out in the original post is that I do have a SendGrid output too. I don't see why that would have any effect on the trigger which is why I left it out. However, I'm adding it now just in case it might be the cause for some weird reason.
编辑 2:添加了突出问题的完整工作代码
Edit 2: Added full working code that highlights the issue
// Sender
using System;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.ServiceBus;
using Newtonsoft.Json;
namespace myapp
{
class Program
{
static void Main(string[] args) => MainAsync().GetAwaiter().GetResult();
static async Task MainAsync()
{
string serviceBusConnectionString = "<your servicebus connectionstring>";
string queueName = "<your queue name>";
IQueueClient queueClient = new QueueClient(serviceBusConnectionString, queueName);
string messageBody = JsonConvert.SerializeObject(new Test());
var message = new Message(Encoding.UTF8.GetBytes(messageBody));
await queueClient.SendAsync(message);
await queueClient.CloseAsync();
}
class Test
{
public string Text { get; set; } = "test";
}
}
}
// Receiver
#r "Newtonsoft.Json"
using System;
using System.Threading.Tasks;
using Newtonsoft.Json;
public static void Run(string myQueueItem, ILogger log)
{
try
{
Test test = JsonConvert.DeserializeObject<Test>(myQueueItem);
log.LogInformation($"C# ServiceBus queue trigger function processed message: {test.Text}");
}
catch (Exception e)
{
log.LogInformation($"Exception: {e.Message}");
}
}
class Test
{
public string Text { get; set; } = "test";
}
结果:
2019-11-04T08:38:10.544 [Information] Executing 'Functions.test' (Reason='This function was programmatically called via the host APIs.', Id=06e10006-baa6-430f-b5db-9a5eae5c154c)
2019-11-04T08:38:10.659 [Information] Exception: Unexpected character encountered while parsing value: S. Path '', line 0, position 0. // This here is caused by "Service bus message"
2019-11-04T08:38:10.659 [Information] Executed 'Functions.test' (Succeeded, Id=06e10006-baa6-430f-b5db-9a5eae5c154c)
2019-11-04T08:39:02.582 [Information] Executing 'Functions.test' (Reason='New ServiceBus message detected on 'test'.', Id=5d7622a7-cc8d-44c9-8720-626fdbb8cabb)
2019-11-04T08:39:02.583 [Information] Trigger Details: MessageId: 13bba779fd524fa1a0098acd6634aded, DeliveryCount: 1, EnqueuedTime: 11/4/2019 8:39:02 AM, LockedUntil: 11/4/2019 8:39:07 AM
2019-11-04T08:39:02.584 [Information] C# ServiceBus queue trigger function processed message: test // This here is the actual message
2019-11-04T08:39:02.584 [Information] Executed 'Functions.test' (Succeeded, Id=5d7622a7-cc8d-44c9-8720-626fdbb8cabb)
推荐答案
根据我的测试,触发器不会被触发两次.
Based on my test, the trigger will not be triggered twice.
namespace ServiceBusTrigger
{
public static class Function1
{
[FunctionName("Function1")]
public static void Run([ServiceBusTrigger("myqueue", Connection = "ServiceBusConnection")]string myQueueItem, ILogger log)
{
log.LogInformation($"C# ServiceBus queue trigger function processed message: {myQueueItem}");
var myMessage = JsonConvert.DeserializeObject<MyMessage>(myQueueItem);
log.LogInformation($"ID: {myMessage.id} Content:{myMessage.content}");
}
}
}
手动发送消息,得到如下输出:
Send a message manually, and get the following output:
Pause Clear Expand
2019-11-04T08:18:56.837 [Information] Executing 'Function1' (Reason='New ServiceBus message detected on 'myqueue'.', Id=7fb37483-b9a3-4c19-baa3-235b419bb585)
2019-11-04T08:18:56.837 [Information] Trigger Details: MessageId: c00a8e41-d883-4620-992f-6b9b4fdae320, DeliveryCount: 1, EnqueuedTime: 11/4/2019 8:18:56 AM, LockedUntil: 11/4/2019 8:19:26 AM
2019-11-04T08:18:56.838 [Information] C# ServiceBus queue trigger function processed message: {"id":"1","content":"abc"}
2019-11-04T08:18:56.838 [Information] ID: 1 Content:abc
2019-11-04T08:18:56.839 [Information] Executed 'Function1' (Succeeded, Id=7fb37483-b9a3-4c19-baa3-235b419bb585)
<小时>
那么,请您检查一下您的服务总线生产商,看看是否发送了任何其他消息.
So, could you please check your service bus producer to see if any additional message was sent.
你可以停止你的函数应用,手动发送消息并在门户上查看:
Of you can just stop your function app, send a message manually and check on the portal:
如果一切正常,那么应该只有 1 条活动消息.
If everything was fine, then there should only be 1 active message.
更新
这篇关于Azure Function App Azure Service Bus 触发器触发两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!