将消息定向到消费者

时间:2019-11-24 04:28:16

标签: c# azure azure-eventhub

我的客户端正在尝试向接收者发送消息。但是我注意到接收器有时不能接收到客户端发送的所有消息,因此丢失了一些消息(不确定问题出在哪里?客户端还是接收器)。 关于为什么可能发生的任何建议。这是我目前正在做的

在接收方,这就是我正在做的。

这是事件处理器

        async Task IEventProcessor.ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
        {
            foreach (var eventData in messages)
            {
                var data = Encoding.UTF8.GetString(eventData.Body.Array, eventData.Body.Offset, eventData.Body.Count);
            }
        }

这是客户端连接到事件中心的方式

var StrBuilder = new EventHubsConnectionStringBuilder(eventHubConnectionString)
{
 EntityPath = eventHubName,
};
this.eventHubClient = EventHubClient.CreateFromConnectionString(StrBuilder.ToString());

我如何将邮件定向到特定的消费者

3 个答案:

答案 0 :(得分:2)

仅当从同一使用者组读取2个或更多事件处理器主机时,才会发生这种情况。

如果您有具有32个分区的事件中心和从同一使用者组读取的2个事件处理器主机。然后每个事件处理器主机将从16个分区中读取数据,依此类推。

类似地,如果4个事件处理器主机从同一使用者组并行读取,则每个将从8个分区读取。

检查在同一使用者组上是否运行2个或更多事件处理器主机。

答案 1 :(得分:2)

我正在使用来自eventhub官方文档的示例代码,分别用于sendingreceiving

我有2个消费者组: $ Default newcg 。假设您有2个客户端,client_1使用默认的使用者组($ Default),client_2使用另一个使用者组(newcg)

首先,在创建发送客户端之后,在SendMessagesToEventHub方法中,我们需要添加一个带值的属性。该值应为使用者组名称。示例代码如下:

    private static async Task SendMessagesToEventHub(int numMessagesToSend)
    {
        for (var i = 0; i < numMessagesToSend; i++)
        {
            try
            {
                var message = "444 Message";
                Console.WriteLine($"Sending message: {message}");
                EventData mydata = new EventData(Encoding.UTF8.GetBytes(message));

                //here, we add a property named "cg", it's value is the consumer group. By setting this property, then we can read this message via this specified consumer group.
                mydata.Properties.Add("cg", "newcg");

                await eventHubClient.SendAsync(mydata);

            }
            catch (Exception exception)
            {
                Console.WriteLine($"{DateTime.Now} > Exception: {exception.Message}");
            }

            await Task.Delay(10);
        }

        Console.WriteLine($"{numMessagesToSend} messages sent.");
    }

然后在client_1中,创建接收者项目后,该项目将使用默认使用者组($ Default) ->在SimpleEventProcessor类中-> ProcessEventsAsync方法中,我们可以过滤掉不必要的事件数据。 ProcessEventsAsync方法的示例代码:

        public Task ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
        {
            foreach (var eventData in messages)
            {
                //filter the data here
                if (eventData.Properties["cg"].ToString() == "$Default")
                {                    
                    var data = Encoding.UTF8.GetString(eventData.Body.Array, eventData.Body.Offset, eventData.Body.Count);

                    Console.WriteLine($"Message received. Partition: '{context.PartitionId}', Data: '{data}'");
                    Console.WriteLine(context.ConsumerGroupName);
                }
            }

            return context.CheckpointAsync();
        }

在另一个使用另一个使用者组的客户端(例如client_2)中,例如其名称为 newcg ,我们可以按照client_1中的步骤进行操作,只需对ProcessEventsAsync方法进行一些更改,如下所示:

            public Task ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
            {
                foreach (var eventData in messages)
                {
                    //filter the data here, using another consumer group name
                    if (eventData.Properties["cg"].ToString() == "newcg")
                    {  
                       //other code
                    }
                   }

                 return context.CheckpointAsync();
               }

答案 2 :(得分:0)

我已经测试了您的代码并对其进行了一些修改(EventProcessorHost构造函数的不同重载,并且在使用消息后添加了CheckpointAsync),然后进行了一些测试。

通过使用默认实现和默认EventProcessorOptions(EventProcessorOptions.DefaultOptions),我可以说在使用消息时确实遇到了一些延迟,但是所有消息均已成功处理。 因此,有时候好像我没有从某个分区中获取消息,但是在一段时间后,所有消息到达

enter image description here

Here,您可以找到对我有用的实际修改后的代码。这是一个简单的控制台应用程序,如果有东西出现,则会打印到控制台。

        string processorHostName = Guid.NewGuid().ToString();
        var Options = new EventProcessorOptions()
        {
            MaxBatchSize = 1, //not required to make it working, just for testing
        };
        Options.SetExceptionHandler((ex) =>
        {
            System.Diagnostics.Debug.WriteLine($"Exception : {ex}");
        });
        var eventHubCS = "event hub connection string";
        var storageCS = "storage connection string";
        var containerName = "test";
        var eventHubname = "test2";
        EventProcessorHost eventProcessorHost = new EventProcessorHost(eventHubname, "$Default", eventHubCS, storageCS, containerName);
        eventProcessorHost.RegisterEventProcessorAsync<MyEventProcessor>(Options).Wait();

为了将消息发送到事件中心并进行测试,我使用了此message publisher app

enter image description here