我的客户端正在尝试向接收者发送消息。但是我注意到接收器有时不能接收到客户端发送的所有消息,因此丢失了一些消息(不确定问题出在哪里?客户端还是接收器)。 关于为什么可能发生的任何建议。这是我目前正在做的
在接收方,这就是我正在做的。
这是事件处理器
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());
我如何将邮件定向到特定的消费者
答案 0 :(得分:2)
仅当从同一使用者组读取2个或更多事件处理器主机时,才会发生这种情况。
如果您有具有32个分区的事件中心和从同一使用者组读取的2个事件处理器主机。然后每个事件处理器主机将从16个分区中读取数据,依此类推。
类似地,如果4个事件处理器主机从同一使用者组并行读取,则每个将从8个分区读取。
检查在同一使用者组上是否运行2个或更多事件处理器主机。
答案 1 :(得分:2)
我正在使用来自eventhub官方文档的示例代码,分别用于sending和receiving。
我有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),我可以说在使用消息时确实遇到了一些延迟,但是所有消息均已成功处理。 因此,有时候好像我没有从某个分区中获取消息,但是在一段时间后,所有消息到达:
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。