【问题标题】:Erlang/OTP framework's error_logger hangs under fairly high loadErlang/OTP 框架的 error_logger 在相当高的负载下挂起
【发布时间】:2011-04-05 10:19:51
【问题描述】:

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

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

问题是::

我正在使用客户端生成具有默认值的 MMS 事件。此客户端(在 Java 中)能够以多个线程

发送大量事件

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

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

我得出的结论是::

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

  2. 极不可能的死锁状态。

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

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

【问题讨论】:

  • 我尝试在 Erlang 14A 64 位版本上运行我的应用程序..但仍然面临同样的问题:(。我实际记录的是成功处理的事件的时间和一些额外细节通过我的应用程序..结果是完整行的 3/4。我需要这些日志,因为我的外部脚本将使用日志中的信息来显示给定时间段内成功事件的数量.. 直到现在我error_logger 只是挂起但从未崩溃。如果它崩溃了,它会将我的整个应用程序带到地面吗??

标签: erlang logging freeze erlang-otp


【解决方案1】:

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

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

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

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

【讨论】:

  • 我想要在日志中格式化输出,因为我正在解析它以显示成功事件的数量及其平均响应时间,但不是实时的。不会使用 io:format 在 shell 中打印日志消息会降低性能吗?在我的应用程序中,我将 Erlang 虚拟机作为守护进程运行。
  • 感谢您的回答丹尼尔。 :)
  • io:format 打印当然不会显示您是否将您的 erlang VM 作为守护程序运行。当然,除非您写入文件。 io:格式(Fd,Txt,Args)。我建议使用错误记录器而不是使用 io:format。当你的系统增长一点时,它有一堆你想要的很好的属性。
【解决方案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) ]

【讨论】:

  • 非常感谢archaelus。我将对您的解决方案进行更多调查。
猜你喜欢
  • 1970-01-01
  • 2011-11-16
  • 2011-04-16
  • 2011-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-26
  • 2020-06-13
相关资源
最近更新 更多