哪些Azure.NET SDK EventHubClient实例方法是线程安全的?

哪些Azure.NET SDK EventHubClient实例方法是线程安全的?,azure,azure-sdk-.net,azure-eventhub,Azure,Azure Sdk .net,Azure Eventhub,我正在编写代码,将消息从多个线程发布到C#中的。EventHubClient的文档包含相当标准的锅炉板 “此类型的任何公共静态(在Visual Basic中共享)成员都是 线程安全。不保证任何实例成员都是线程 安全的。” 没有关于以下任何一种螺纹安全性的附加文档: 我最希望的是线程安全。如果我相信send方法不是线程安全的,那么每次我希望发送消息时,我都会创建一个新的EventHubClient实例。由于底层tcp连接是重用的,除非采取步骤,这可能不会有太多的开销。类似的问题也会出现,尽管有一个

我正在编写代码,将消息从多个线程发布到C#中的。EventHubClient的文档包含相当标准的锅炉板

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

没有关于以下任何一种螺纹安全性的附加文档: 我最希望的是线程安全。如果我相信send方法不是线程安全的,那么每次我希望发送消息时,我都会创建一个新的EventHubClient实例。由于底层tcp连接是重用的,除非采取步骤,这可能不会有太多的开销。类似的问题也会出现,尽管有一个异步方法来创建一个,但它们可能有自己的AMQP连接

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


对于任何Azure用户来说,有可能在文档中对此进行澄清吗?这种文档问题(假设它似乎是错误的)也出现在Azure表中,并且通常在MSDN文档中很常见。关于EventHub,这与的clear thread safety声明相反,至少没有明确地将所有内容标记为不安全。我在SDK的开源部分没有找到EventHub,因此无法检查自己。

TLDR

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

    ServiceBus SDK公开了两种模式来创建发件人:

  • 基本的
  • 先进的
  • 对于基本版本-开发人员将直接使用
    EventHubClient.CreateFromConnectionString()
    API,不必担心管理
    MessagingFactory
    对象(连接)。SDK将处理跨所有
    EventHubClient
    实例重用
    MessagingFactory
    ,只要
    连接字符串相同(所有键和值的文字匹配)在SDK中完成此重用

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

    EventHubClient
    -发送到EventHubs的所有实例方法都是线程安全的。通常,所有数据平面操作都是。。。 然而,在从EventHubs读取时,API针对这种模式进行了优化。
    
    while(true){
    var events=eventHubPartitionReceiver.receive(100);
    事件(事件);
    }
    
    因此,对于ex:properties,例如,
    EventHubReceiver.RuntimeInformation
    ,在每次
    receive
    调用后填充,而不进行任何同步。因此,尽管实际的
    receive
    API是线程安全的,但对运行时信息的后续调用却不是线程安全的,因为在
    PartitionReceiver
    的实例上停驻多个
    receive
    调用是很少见的

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

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


    另外,如果您使用的发送模式是分区发件人,那么它们也将使用相同的底层MessagingFactory,如果您从相同的eventHubClient(.CreatePartitionedSender())实例创建所有发件人。

    您能否提供有关分区发件人案例的更多详细信息?它是否可以直接创建到分区的AMQP连接,或者它的唯一目的是覆盖基于哈希的分区器?如果后者是异步调用,有什么原因吗?我不希望该库是完全线程安全的,但如果Send当前是线程安全的,并且是在线程安全消息传递工厂的基础上构建的,那么它是否只是标记为非线程安全以保持未来选项的开放性?这是一个很好的问题。PartitionedSender不创建到分区的直接amqp连接。每个ServiceBus发送方将首先与网关svc对话,并解析其对话的后端角色。我想象的分区发送器的唯一优点/优化是,网关不需要打开amqp消息(msg annotations-->反序列化成本——如果操作正确)并提取分区键和计算哈希来找到正确的分区。异步-为了保持它的可扩展性(为了将来的优化在客户机和fwd上找到分区)-服务器已经有4个主题了。我不得不说这是一个足够好的答案。当需要修改producer API或提供更友好的API时,我会要求您查看Kafka>0.8.2 producer,看看它们的范例是否合适。我自己需要(而不是有选择地)处理批处理,这导致我的代码中出现了一些令人沮丧的评论。