我的应用程序基本上是基于内容的路由器,它将路由MMS事件。
我使用的记录器是SASL模式下的OTP框架附带的记录器“ error_logger ”
问题是::
我正在使用客户端生成默认值的MMS事件。此客户端(使用Java)能够在 多个THREADS
中发送大量事件我在10个线程中发送100个事件(每个线程发送10个MMS事件)到我用erlang / OTP编写的路由器。
问题是,当我的路由器收到如此高的负载时, 我的Logger挂起 ,但它会停止更新我的日志文件。但是路由器仍然能够路由事件。
我提出的结论是::
1)当收到如此高的事件负载时,在erlang中调度问题(每个事件的单独的erlang进程)。
2)一个非常不可能的死钱状态。
3)可能是由于在多个线程中发送事件而不是按顺序发送它们。但我想路由器将连接到多个服务提供商盒,所以我想到了在线程中发送事件。
有人可以帮助解决这个问题的神秘面纱吗?
答案 0 :(得分: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) ]
答案 1 :(得分:1)
你已经有了一个很好的答案,但我会加入讨论。
默认情况下,error_logger使用对磁盘的缓存写入操作。所以有一种可能性是你在低负载时没有注意到这一点,但是在高负载下你的写入会暂时停留在缓存中。
旁注:让多个线程调用Erlang应该没问题。
另一种测试方法是将自己的记录器添加到error_logger,看看会发生什么。可能打印到外壳或其他“快速”的东西。