4

我正在尝试评估 ZeroMQ 以获得更大的监控和数据收集系统。在较小的规模上,一切都很好,但增加负载和规模似乎有点棘手。

现在我正在使用 C# 包装器(clrzmq,3.0.0-rc1)来创建发布者和订阅者应用程序。我将发布者套接字(1 个套接字,1 个上下文)绑定到 1000 个端点(本地主机 + 一系列端口),并让订阅者应用程序套接字(同样是 1 个套接字,1 个上下文)绑定到发布者端点。

这有时有效,有时无效(我想这与进程以某种方式处理的最大套接字数有关)。这似乎取决于我启动应用程序的顺序,但我无法确定。我唯一看到的是讨厌的 SEHExceptions,根本不包含任何细节。如果我创建简单的控制台应用程序,我有时会看到低级 C++ 断言,例如:

  • 断言失败:fds.size () <= FD_SETSIZE (......\src\select.cpp:70)
  • 断言失败:权限被拒绝 (......\src\signaler.cpp:281)
  • 断言失败:对等方重置连接 (......\src\signaler.cpp:124)

对我不是很有帮助。在 C# 包装器中,上下文创建失败。它甚至没有机会开始连接甚至创建套接字。我希望通过抛出异常来处理低级别的 ZeroMQ 错误,也许我只是还不明白如何处理错误。

我现在的问题是:

  • 如何创建(有点)真实的测试设置来模拟单台机器上的 1000 个单独的发布者(在现实世界中 1 个发布者 = 1 台机器)和另一台机器上的几个订阅者,所有这些都使用 C#。这甚至可能吗?
  • 更重要的是,我如何在 C# 代码中捕获 ZeroMQ 错误以了解问题所在?

由于 ZeroMQ 看起来相当稳定和成熟,我很难相信 1000 个发布者应该是一个问题。但是,为了在 C# 上使用 ZeroMQ,我需要比目前可用的更好的错误支持(除非我在这里完全错过了一些东西)。

更新:

在深入研究源代码后,我最终得到zmq_assert(...)RaiseException (0x40000015, EXCEPTION_NONCONTINUABLE, 1, extra_info);. 这将在将原始断言语句转储到控制台后突然终止应用程序。这似乎有点苛刻,但考虑到它确实无法恢复,这可能是最好的选择。但是,更好的错误消息不会受到伤害。不是每个人都知道是什么fds.size () <= FD_SETSIZE意思。源代码中的评论提供了一些线索,如果在错误消息中包含该评论会很好。无论如何,鉴于我的应用程序不是控制台应用程序,这只会给我留下一个未处理的 SEHException,它似乎甚至不包含断言语句或行/文件信息。我想知道我将创建多少其他错误会导致其他类似的神秘错误。

4

3 回答 3

3

在进一步研究之后,似乎默认的套接字数设置为 1024。C# 包装器在Context对象上有一个属性,应该能够更改此设置,但它不起作用,至少不像预期的那样。此外,本机zmqlib在上下文对象上没有此设置。

运行描述中的设置似乎是不可能的,至少不使用clrzmqC# ZeroMQ 包装器。我通过在一台单独的机器上运行 500 个发布者并在另一台机器上运行另外 500 个加 1000 个订阅者来解决它。这很好用,没有任何错误。

另一个话题也有点令人失望。当达到最大套接字数时,ZeroMQ 会简单地抛出一个无法捕获的异常,导致应用程序突然崩溃。这是一种快速失败的方法,可以避免任何进一步的数据/状态损坏,但不幸的是,对于导致应用程序死机的原因也几乎没有留下任何线索。从其他帖子来看,当这种情况发生时,似乎很难为事后收集数据。在 C# 代码中捕获异常似乎是不可能或非常困难的,并且挂钩到标准输出以捕获打印的断言似乎也很难实现(如果我们不是从命令提示符运行,在这种情况下,断言消息会在之前打印应用程序死亡)。

总而言之,当 ZeroMQ 通过 zmq_assert(...) 调用终止时,这使得在非控制台 C# 设置中进行低级故障排除和事后分析非常困难。希望这是一个极端的例子。并非所有故障模式似乎都会以这种突然的方式导致终止。

于 2012-12-04T19:11:29.137 回答
2

默认的 FD_SETSIZE 是 1024(在 MSVC libzmq 项目中定义),因此您将在测试用例的中途遇到这个问题。另一个断言由此而来。

在您的 libzmq 项目中将其增加到 4K 或 8K,事情应该会更好。

至于 assert() 调用,肯定在 Windows 上太残酷了。在 Linux 上,这提供了一个不错的堆栈转储和足够的信息来跟踪问题。随意改进 assert 宏,让它做一些更智能的事情,例如启动调试器。无论如何,如果您遇到断言,您将无法合理地继续。

当 FD 集已满时断言,可以更好地处理。如果您对 C/C++ 有所了解,请随时查看代码。我们确实依赖于人们的补丁。

另外,如果您觉得 1024 太小,请随时在项目中提出此问题并将补丁发送给我们。

于 2012-12-11T12:56:58.007 回答
1

快速而肮脏地查看此问题表明您为计算机创建了太多套接字连接。查看此链接,了解MSDN的最大套接字数。你得到的错误看起来非常相关,这可能是你的错误的来源。

老实说,拥有 1000 个独立的发布者似乎您在使用 zmq 时处理的问题有点不正确。为什么不拥有 1 个发布者并使用“命名空间”并让订阅者订阅它需要拆分订阅者获得的消息的内容。

于 2012-12-03T18:36:01.390 回答