我的客户端 - 服务器应用程序有问题。因为我几乎已经用尽了解决它的想法,我正在寻求帮助。我现在偶然发现了三到四次描述的情况。提供的数据来自上次故障,当我转换所有可能的日志记录,消息转储等等。
系统说明
1)客户端。在Windows下运行。我假设其工作没有问题(从日志判断)
2)服务器。在Linux下运行(RHEL 5)。这是我遇到问题的服务器
3)在客户端和服务器之间维护两个连接:一个命令和一个用于数据发送。两者都异步工作。两个连接都存在于一个线程和一个boost::asio::io_service
上
4)要从客户端发送到的数据是由'\ 0'分隔的消息。
5)数据加载大约50 Mb /小时,一天24小时
6)使用boost::asio::async_read_until
和相应的分隔符
问题
- 两天系统按预期工作
- 在18:55
服务器的第三天,从客户端读取最后一条消息,然后停止读取它们。关于新数据的日志中没有信息
- 从18:55
到09:00
(14小时),客户报告没有错误。因此它成功发送了数据(大约700 Mb)并且没有出现错误
- 在08:30
我开始调查问题。服务器进程还活着,服务器和客户端之间的连接也都存在
- 在09:00
我使用gdb
附加到服务器进程。服务器处于休眠状态,等待来自系统的某些信号。我相信我不小心碰到了Ctrl + C,可能会有一些消息
- 后来在日志中我发现了像'系统调用中断'这样的消息。之后,与客户端的两个连接都被删除了。客户端重新连接,服务器开始正常工作
- 服务器处理的第一条消息在客户端18:57
加上时间戳。因此,在重新启动正常工作后,服务器不会将所有消息丢弃到09:00
,它们存储在某处,然后在此之后对其进行相应处理。
我尝试过的事情
- 上面的模拟场景。当服务器转储所有传入的消息时,我写了一个小脚本,它将自己呈现为客户端并再次将所有消息发送回服务器。服务器丢失时出现out of memory
错误,但不幸的是,这是因为数据负载很高(这次约为3 Gb /小时),而不是因为同样的错误。因为是星期五晚上我没有时间正确地重复实验
- 尽管如此,我通过Valgrind运行服务器来检测可能的内存泄漏。没有发现任何严重的事情(除了服务器由于高负载而被丢弃的事实),没有巨大的内存泄漏。
问题
- 客户端发送的这些700 Mb数据和服务器没有得到的数据在哪里?当服务器重新启动连接时,为什么它们是持久的并且没有丢失?
- 在我看来,问题与服务器无关,无法从boost::asio::io_service
收到消息。缓冲区充满了数据,但没有调用读取处理程序。这可能是OS方面的问题吗?异步调用有问题吗?如果是这样,怎么检查呢?
- 我该怎么做才能发现问题的根源?正如我所说的那样,我已经没有理智的想法,而且每个实验在时间上花费很多(系统需要大约两三天的时间来描述状态),所以我需要运行尽可能多的实验检查。我可以。
非常感谢我可以用来解决错误的任何想法。
更新:好的,似乎错误是在异步客户端 - 服务器交互中间的同步write
中。由于两个连接都存在于一个线程中,因此某个同步write
阻塞了线程,并且命令和数据连接上的所有交互都停止了。因此,我将其更改为异步版本,现在它似乎正常工作。
答案 0 :(得分:0)
正如我所说,我的想法已经用完了,每个实验的成本都很高 在时间方面(需要大约两三天才能获得) 系统描述状态)
简化此问题调查的一种方法是在某个Virtual Machine内运行服务器,直到达到此损坏状态。然后,您可以制作整个系统的snapshot,并在每次调查期间出现问题时恢复原状。至少你不必等待3天再次获得这种状态。