正如該消息所述,它是在寫(xiě)入某個(gè)管道的消息沒(méi)有被任何進(jìn)程讀取時(shí)發(fā)生的。當向接收端發(fā)送大量請求時(shí),接收端可能由于超時(shí)、線(xiàn)程被阻塞或其他原因而無(wú)法讀取請求,然后就會(huì )引發(fā)此異常。
解決辦法 大多數時(shí)候,此問(wèn)題都是由潛在的錯誤引起的。例如:該 Web 應用程序與網(wǎng)關(guān)建立一個(gè) HTTP 連接,并嘗試向它發(fā)送一個(gè)請求(圖 2 中的步驟 2),如清單 6 所示。
清單 6. 向 Web 應用程序發(fā)送 HTTP 請求URL url = new URL(serverAddress);
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
PrintWriter writer = new PrintWriter(os);
writer.println("Hello, dude");
writer.flush();
writer.close();
InputStream is = conn.getInputStream();
如果沒(méi)有最后一行 InputStream is = conn.getInputStream,則會(huì )引發(fā) java.net.SocketException: There is no process to read data written to a pipe 異常。如果沒(méi)有 conn.getInputStream(),則根本不會(huì )將請求消息發(fā)送到接收端。因此,接收端不會(huì )收到任何消息,當然就沒(méi)有任何進(jìn)程讀取寫(xiě)入連接套接字的請求數據了,所以就導致產(chǎn)生異常。
偵聽(tīng)響應時(shí)超時(shí),如圖 2 中的步驟4 所示。
性能測試可能預期測試客戶(hù)端能夠在五秒內獲得響應。如果響應在五秒后返回,則發(fā)出請求的測試客戶(hù)端將不再處理它。因此,測試客戶(hù)端不會(huì )讀取響應數據。對于套接字管道,數據是寫(xiě)入了,但是它缺少讀取過(guò)程。
響應線(xiàn)程被另一個(gè)線(xiàn)程阻塞,如圖 2 中的步驟 3 所示。
假設您在網(wǎng)關(guān)中管理線(xiàn)程池以響應 Web 應用程序發(fā)送的請求。當達到相當高的 TPS 時(shí),由于低效的線(xiàn)程調度,很可能無(wú)法調度任何線(xiàn)程去處理新的請求。結果,該請求未由任何線(xiàn)程讀取和處理。這還可能會(huì )導致錯誤。
提醒 對于基于輸入或輸出流的 API,應確保在不再需要時(shí)關(guān)閉所有打開(kāi)的連接(打開(kāi)的 InputStream(Reader) 或 OutputStream(Writer))。
總結
將 Java Web 應用程序從一個(gè)平臺移植到另一個(gè)平臺所需的精力雖然不是非常巨大,但也是相當可觀(guān)的。需要記住的三個(gè)要點(diǎn)如下:
在編寫(xiě)操作系統相關(guān)的代碼時(shí),避免硬編碼。使用 java.lang.System.getProtery(String name) 始終更為可靠。
使用 java.lang.Class.getResource(String filename) 來(lái)定位在 Application Developer V5.1.2、Rational Application Developer V6.0 和相關(guān)版本的 Application Server 上都有效的資源,無(wú)論它們是在 Windows 還是在 AIX 上。
對于容易出錯的網(wǎng)絡(luò )程序,應該成對地執行讀取和寫(xiě)入操作。如果將數據寫(xiě)入某個(gè)套接字,則必須有某個(gè)進(jìn)程去讀取它們。
聯(lián)系客服