4

我的应用程序基本上是一个基于内容的路由器,它将路由 MMS 事件。

我使用的记录器是SASL模式下OTP框架自带的“ error_logger

问题是::

我正在使用客户端生成具有默认值的 MMS 事件。这个客户端(在 Java 中)能够在多个线程中发送高负载的事件

我在 10 个线程中发送 100 个事件(每个线程发送 10 个 MMS 事件)到我用 Erlang/OTP 编写的路由器。

问题是,当我的路由器收到如此高的负载时,我的 Logger 挂起,即它停止更新我的日志文件。但是路由器仍然能够路由事件。

我得出的结论是::

  1. 当接收到如此高的事件负载(每个事件的单独进程)时,Erlang 中的调度问题。

  2. 一个非常不可能的死锁状态。

  3. 可能是由于在多个线程中发送事件而不是按顺序发送它们。但是我猜一个路由器会连接到多个服务提供者盒子,所以我想到了在线程中发送事件。

任何人都可以帮助 mw 揭开这个问题的神秘面纱吗?

4

2 回答 2

2

您使用的是哪个版本的 Erlang?在 R14A(可能是 R13B4?)之前,当消息队列包含大量消息时调用选择性接收会降低性能。这种行为意味着在接收大量消息的进程中(error_logger作为典型示例),如果它几乎无法跟上负载,那么负载中的一个小峰值可能会导致处理成本飙升并保持在那里作为新的处理成本高于工艺所能承受的范围。这个问题已经在 R14A 中解决了。

其次 - 你为什么要向文本记录器发送大量事件/通话/日志?格式化字符串以输出到人类可读的日志文件比使用二进制文件要昂贵得多disk_log。降低日志记录的成本会有所帮助,但减少日志量会更有帮助。也许调查一下为什么你需要记录这些东西,看看你是否不能用另一种(更便宜的)方式记录它们。

问题error_logger通常是其他一些过载问题的症状。发生此问题时,请尝试查看所有进程的消息队列大小,并查看是否还备份了其他内容。以下 erlang shellcode 可能会有所帮助:

[ { P, element(2, process_info(P, message_queue_len)) } 
  || P <- erlang:processes(), is_process_alive(P) ]
于 2010-08-30T19:48:58.600 回答
2

你已经有了一个很好的答案,但我会加入讨论。

默认情况下,error_logger 使用缓存的磁盘写入操作。因此,一种可能性是您在低负载下并没有真正注意到这一点,但在高负载下,您的写入会在缓存中卡住一段时间。

附带说明:多个线程调用 Erlang 应该没有问题。

另一种测试方法是将你自己的记录器添加到error_logger,看看会发生什么。可能打印到外壳或其他“快速”的东西。

于 2010-09-01T06:52:09.760 回答