4

我正在编写代码,使用EventHubClient将消息从多个线程发布到C# 中的Azure 事件中心。EventHubClient 的文档包含相当标准的样板。

“这种类型的任何公共静态(在 Visual Basic 中为共享)成员都是线程安全的。不保证任何实例成员都是线程安全的。”

在我最希望是线程安全 四种 发送 方法中,没有关于线程安全的附加文档。如果我相信发送方法不是线程安全的,那么每次我希望发送到消息时,我最终都会创建一个新的 EventHubClient 实例。由于底层的 tcp 连接显然被重用,除非采取措施,这可能不会有太多的开销。分区发件人也会出现类似的问题,尽管有一种异步方法可以创建一个,但它们很可能有自己的 AMQP 连接。

尽管有文档,但 EventHubClient 线程的某些(如果不是全部)实例方法是否安全?

对于任何 Azure 人员,是否有可能在文档中对此进行澄清?此类文档问题(假设它看起来可能是错误的)似乎也会影响Azure Table,并且通常在 MSDN 文档中很常见。关于 EventHub,这与KafkaAWS Kinesis明确的线程安全声明形成对比,至少没有明确将所有内容标记为不安全。我没有在 SDK 的开源部分找到 EventHubs,所以无法检查自己。

4

1 回答 1

7

TLDR

  1. .NET SDK 中的所有关键运行时操作(也称为数据平面)都是线程安全的。
  2. 创建EventHubClient对象一次并重复使用

故事

ServiceBus SDK 公开了两种模式来创建发送者:

  1. 基本的
  2. 先进的

Basic 版本 - 开发者将直接使用EventHubClient.CreateFromConnectionString()API,无需担心管理MessagingFactory对象(连接 gu's)。SDK 将处理MessagingFactory所有EventHubClient实例的重用,只要connection string相同 - 所有键和值的文字匹配 - 在 SDK 中完成此重用。

对于需要在连接级别进行更多控制的高级开发人员,SB SDK 提供MessagingFactory.CreateFromConnectionString()并且可以从该开发人员创建EventHubClient实例。

EventHubClient- 发送到 EventHubs 的所有实例方法都是严格线程安全的。一般来说,所有数据平面操作都是......但是,在从 EventHubs 读取时,API 已针对此模式进行了优化。 while(true) { var events = eventHubPartitionReceiver.receive(100); processMyEvents(events); } 因此,例如:像EventHubReceiver.RuntimeInformation- 这样的属性在每次receive调用后填充,没有任何同步。因此,即使实际的receiveAPI 是线程安全的——对 RuntimeInformation 的后续调用不是——因为很少有人将多个receive调用停放在PartitionReceiver.

在每个组件中创建一个新实例EventHubClient以开始发送消息是默认模式 - ServiceBus SDK 将负责重用底层 MessagingFactory - 它重用相同的物理套接字(如果连接字符串相同)。

如果您正在寻找真正的高吞吐量场景,那么您应该设计一种策略来创建多个 MessagingFactory 对象,然后分别创建一个 EventHubClient。但是 - 在尝试此操作之前,请确保您已经在 Portal 上增加了 EventHub 的吞吐量单位,因为默认值仅为 1 MBPS - 所有 16 个分区的累积。

此外,如果您使用的发送模式是分区发件人——如果你从同一个eventHubClient (.CreatePartitionedSender()) 实例创建所有发件人,它们都将使用相同的底层 MessagingFactory。

于 2014-11-13T23:07:07.120 回答