繁体   English   中英

为什么我在使用 eventhub 时会在 Azure 收到此错误?

[英]Why am I receiving this error on Azure when using eventhubs?

我最近开始使用 Azure,这是一次压倒性的体验。 我开始尝试使用eventhubs ,我基本上是在遵循关于如何使用 nodejs 从 eventhubs 发送和接收消息的官方教程

一切都运行良好,所以我构建了一个小型 web 应用程序(静态前端应用程序),并将其连接到节点后端,与事件中心进行通信。 所以基本上我的应用程序是这样构建的:

frontend <----> node server <-----> eventhubs

如您所见,它非常简单。 节点服务器正在从 eventhub 获取数据并将其转发到显示值的前端。 这是一次很酷的体验,在出现此错误之前,我一直在享受 MS Azure:

 azure.eventhub.common.EventHubError: ErrorCodes.ResourceLimitExceeded: Exceeded the maximum number of allowed receivers per partition in a consumer group which is 5. List of connected receivers - nil, nil, nil, nil, nil.

这个错误确实令人困惑。 我使用默认的消费者组并且只有一个应用程序。 我从未尝试从另一个应用程序访问这个消费者群体。 它说限制是 5,我只使用一个应用程序所以它应该没问题还是我遗漏了什么? 我不检查这里发生了什么。

我浪费了太多时间在谷歌上搜索和研究这个,但我没有明白。 最后,我想也许每次我在 azure 上部署应用程序(我的前端和我的节点服务器)时,这都算作一个消费者,因为我部署了该应用程序超过 5 次,所以出现了这个错误。 我是对的还是胡说八道?

编辑

我使用 websockets 作为我的应用程序(前端)和我的节点服务器(后端)之间的通信协议。 节点服务器使用默认的消费者组(我什么也没做),我只是按照微软的这个官方例子 我基本上使用的是 MS 文档中的代码,这就是为什么我没有从我的节点服务器发布任何代码片段的原因,并且由于错误发生在后端而不是前端,因此如果我发布任何前端代码也无济于事。

最后,我使用 websocket 连接前端和后端。 它完美地工作了一两天,然后这个错误开始发生。 有时我会打开多个客户端(例如浏览器客户端和智能手机客户端)。

我想我不明白这个消费群体的概念。 就像每个客户都是消费者一样吗? 因此,如果我在浏览器的 5 个不同选项卡中打开我的应用程序(同一个应用程序),那么我是否有 5 个消费者?


我不太明白下面的答案以及“pooling client”是什么意思,因此,我将尝试在此处发布代码示例以向您展示我正在尝试做的事情。

代码片段

这是我在服务器端使用的 function 与事件中心通信并接收/使用消息

async function receiveEventhubMessage(socket, eventHubName, connectionString) {

 
  const consumerClient = new EventHubConsumerClient(consumerGroup, connectionString, eventHubName);


  const subscription = consumerClient.subscribe({
      processEvents: async (events, context) => {

        for (const event of events) {
          console.log("[    consumer    ] Message received : " + event.body);

            io.emit('msg-received', event.body);
        }
      },

      processError: async (err, context) => {
        console.log(`Error : ${err}`);
      }
    }
  );

如果您注意到,我将 eventhub 和连接字符串作为参数提供,以便能够更改它。 现在在前端,我有一个包含多个主题的列表,每个主题都有自己的 eventhubname,但它们具有相同的 eventhub 命名空间。

这是我拥有的两个 eventhubnames 的示例:

{
"EventHubName": "eh-test-command"
"EventHubName": "eh-test-telemetry"
}

如果用户选择发送命令(从前端,我只有一个按钮列表,用户可以单击这些按钮以通过 websockets 触发事件)然后CommandEventHubName将从前端发送到节点服务器。 服务器将收到该 eventhubname 并切换我上面发布的 function 中的 consumerClient。

这是我调用它的代码:

// io is a socket.io object
io.on('connection', socket => {
   socket.on('onUserChoice', choice => {
   // choice is an object sent from the frontend based on what the user choosed. e.g if the user choosed command then choice = {"EventhubName": "eh-test-command", "payload": "whatever"}

   receiveEventhubMessage(socket, choice.EventHubName, choice.EventHubNameSpace)
              .catch(err => console.log(`[    consumerClient    ] Error while receiving eventhub messages: ${err}`));
      }
}

我正在构建的应用程序将来会扩展到汽车领域的真实用例,这就是为什么这对我很重要。 因此,我想弄清楚如何在 eventhub 之间切换,而无需在每次 eventhubname 更改时创建新的 consumerClient?

我必须说我不理解“池客户端”的例子。 我正在寻求更多的阐述,或者理想情况下,一个最小的例子只是为了让我上路。

根据问题中的对话,这似乎是您的后端正在为来自前端的每个请求创建一个新的EventHubConsumerClient的根本原因。 因为每个客户端都将打开到该服务的专用连接,所以如果使用同一使用者组对同一事件中心实例的请求超过 5 个,就会超出配额。

要解决此问题,您需要考虑合并EventHubConsumerClient实例,以便您从每个 Event Hub 实例开始。 您可以通过调用subscribe安全地使用池客户端来处理对您的前端的请求。 这将允许您在多个前端请求之间共享连接。

关键思想是您的consumerClient不是为每个请求创建的,而是在请求之间共享一个实例。 使用您的代码片段来说明最简单的方法,您最终会将您的客户端创建提升到 function 之外进行接收。 它可能看起来像:

const consumerClient = new EventHubConsumerClient(consumerGroup, connectionString, eventHubName);

async function receiveEventhubMessage(socket, eventHubName, connectionString) {
  const subscription = consumerClient.subscribe({
      processEvents: async (events, context) => {

        for (const event of events) {
          console.log("[    consumer    ] Message received : " + event.body);
          io.emit('msg-received', event.body);
        }
      },

      processError: async (err, context) => {
        console.log(`Error : ${err}`);
      }
    }
  );

也就是说,根据应用程序的体系结构,上述内容可能不适合您的环境。 如果托管receiveEventHubMessage的内容是为每个请求动态创建的,则不会发生任何变化。 在这种情况下,您需要考虑像 singleton 或依赖注入这样的东西来帮助延长寿命。

如果您最终在扩展以满足您的请求时遇到问题,您可以考虑增加每个事件中心的客户端数量和/或将请求分散到不同的使用者组。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM