`

项目迁移:将 Java Web应用 从Windows迁移到AIX需注意问题(三)----套接字通信中没有读取过程问题

阅读更多
套接字通信中没有读取过程

本部分讨论在 AIX 平台上的套接字通信中经常遇到的一个问题。性能测试是一件好事情。它可以帮助您找出不如功能测试中找到的错误那么明显的错误。这些错误包括内存泄漏和多线程编程的争用条件。它们就像您代码中的捣蛋鬼,有时可能会使您的代码行为异常。

在这个性能测试场景中,测试客户端向运行于 Application Server 上的 Web 应用程序发送 Web 服务请求。该 Web 应用程序处理请求并构造一个新消息,然后将新构建的消息发送到一个网关。然后网关向该 Web 应用程序发回一个响应,该 Web 应用程序再向测试客户端发送一个响应。图 2 显示了该过程流。


图 2. Web 应用程序的性能测试



陷阱
上述场景非常常见,并且很容易在功能测试中验证。然而,在性能测试中,当企业应用程序经历很高的事务处理速度(Transaction Per Second,TPS)时,如果没有预先执行性能测试,您的应用程序很可能会引发异常。
异常发生在套接字通信中,其主要特征为:java.net.SocketException: There is no process to read data written to a pipe

“There is no process to read data written to a pipe”错误是一个特定于 AIX 的错误消息,位于对应的 Java 代码的本机方法实现中。它是由在 AIX 上实现套接字通信的 C 代码所引发的。

正如该消息所述,它是在写入某个管道的消息没有被任何进程读取时发生的。当向接收端发送大量请求时,接收端可能由于超时、线程被阻塞或其他原因而无法读取请求,然后就会引发此异常。

解决办法
大多数时候,此问题都是由潜在的错误引起的。例如:
该 Web 应用程序与网关建立一个 HTTP 连接,并尝试向它发送一个请求(图 2 中的步骤 2),如清单 6 所示。


清单 6. 向 Web 应用程序发送 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();




如果没有最后一行 InputStream is = conn.getInputStream,则会引发 java.net.SocketException: There is no process to read data written to a pipe 异常。如果没有 conn.getInputStream(),则根本不会将请求消息发送到接收端。因此,接收端不会收到任何消息,当然就没有任何进程读取写入连接套接字的请求数据了,所以就导致产生异常。

侦听响应时超时,如图 2 中的步骤4 所示。
性能测试可能预期测试客户端能够在五秒内获得响应。如果响应在五秒后返回,则发出请求的测试客户端将不再处理它。因此,测试客户端不会读取响应数据。对于套接字管道,数据是写入了,但是它缺少读取过程。

响应线程被另一个线程阻塞,如图 2 中的步骤 3 所示。
假设您在网关中管理线程池以响应 Web 应用程序发送的请求。当达到相当高的 TPS 时,由于低效的线程调度,很可能无法调度任何线程去处理新的请求。结果,该请求未由任何线程读取和处理。这还可能会导致错误。

提醒
对于基于输入或输出流的 API,应确保在不再需要时关闭所有打开的连接(打开的 InputStream(Reader) 或 OutputStream(Writer))。
总结

将 Java Web 应用程序从一个平台移植到另一个平台所需的精力虽然不是非常巨大,但也是相当可观的。需要记住的三个要点如下:

在编写操作系统相关的代码时,避免硬编码。使用 java.lang.System.getProtery(String name) 始终更为可靠。

使用 java.lang.Class.getResource(String filename) 来定位在 Application Developer V5.1.2、Rational Application Developer V6.0 和相关版本的 Application Server 上都有效的资源,无论它们是在 Windows 还是在 AIX 上。

对于容易出错的网络程序,应该成对地执行读取和写入操作。如果将数据写入某个套接字,则必须有某个进程去读取它们。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics