簡體   English   中英

異步服務器停止從客戶端獲取數據,沒有明顯的原因

[英]Asynchronous server stopping getting data from client with no visible reason

客戶服務器應用程序出現問題。 由於解決它的理智想法幾乎用光了,我在尋求幫助。 我現在偶然發現了大約三到四次的情況。 當我關閉所有可能的日志記錄,消息轉儲等等時,所提供的數據來自上一次故障。

系統描述
1) 客戶。 在Windows下工作。 我假設它的工作沒有問題(從日志來看)
2) 服務器。 在Linux(RHEL 5)下工作。 這是我有問題的服務器。
3)客戶端和服務器之間保持兩個連接 :一個命令和一個用於數據發送。 兩者都是異步工作的。 兩種連接都在一個線程中,並在一個boost::asio::io_service
4)從客戶端發送到服務器的數據是由'\\ 0'修飾的消息。
5) 數據負載約為每天24小時50 Mb /小時。
6)使用boost::asio::async_read_until和相應的分隔符在服務器端讀取數據

問題
-為期兩天的系統按預期工作
-第三天18:55服務器從客戶端讀取了最后一條消息,然后停止讀取它們。 日志中沒有有關新數據的信息。
-從18:5509: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正在阻塞線程,並且命令和數據連接上的所有交互都停止了。 因此,我將其更改為異步版本,現在似乎可以使用了。

正如我說的那樣,我用盡了理智的想法,並且每個實驗都花費大量的時間(使系統達到描述狀態大約需要兩到三天)

一種簡化對此問題進行調查的方法是在某個虛擬機中運行服務器,直到達到此故障狀態為止。 然后,您可以制作整個系統的快照 ,並在調查過程中每次出現問題時都將其還原。 至少您不必等待3天即可再次獲得此狀態。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM