【问题标题】:Java socket timeout connection timeout by socket connect, but fine by UNIX ping tools套接字连接的Java套接字超时连接超时,但UNIX ping工具很好
【发布时间】:2014-07-08 11:05:45
【问题描述】:

我有 1 台机器,我使用以下脚本对其进行了 ping 操作

import java.io.PrintStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;

class SimplePing 
{
    static void connectAndPing(String host, int port, int loop, int pingLoop, int socketTimeout){
        if(loop>0){
            SocketAddress sAdress;
            Socket kkSocket;
            for(int i=0;i<loop;i++){
                sAdress = new InetSocketAddress(host, port);
                for(int j=0;j<pingLoop;j++){
                    try {
                      kkSocket = new Socket();
                      kkSocket.connect(sAdress, socketTimeout);
                      kkSocket.close();
                      Thread.sleep(1000L);
                    } catch (Exception e) {
                      System.out.println(e);        
                    }
                    System.out.print("!");
                }
            }
        }
    }


    public static void main(String[] args) 
    {

        String host = args[0];
        int port = Integer.parseInt(args[1]);
        int socketTimeout = Integer.parseInt(args[2]);
        int loop = 100000;
        int pingLoop = 100;

        System.out.println("Begin ping. . .");
        connectAndPing(host, port, loop, pingLoop, socketTimeout);
        System.out.println("End ping. . .");
    }
}

它给了我这样的结果(不要打扰标记,这只是我的评论)

然后我尝试使用 UNIX ping 工具 ping,然后得到

这是远程机器信息:

**SunOS msgbkrpapp18 5.10 Generic_138888-03 sun4v sparc SUNW,SPARC-Enterprise-T5120

java 版本“1.6.0_26”

Java(TM) SE 运行时环境(内部版本 1.6.0_26-b03)

Java HotSpot(TM) 服务器虚拟机(内部版本 20.1-b02,混合模式)**

为什么我得到不同的结果?哪个更有效?

我的消息应用程序正在使用端口 8000,它接受来自外部 IP 的连接,我的客户抱怨应用程序有时已关闭,他使用上述 java 程序读取系统健康状况。

如果我在app端检查,没有遇到异常情况,甚至连接的线程池也没有达到最大值。

有什么建议吗?? 谢谢

【问题讨论】:

  • 但是上面的代码不能运行,因为变量j是第二个for循环的本地变量。但是代码在int mark = i * j + 100 的范围之外使用它。你确定,这是正确的可编译示例:-)
  • 你说得对,我已经编辑了我的帖子:),

标签: java linux unix networking


【解决方案1】:

答案就在您的代码中:

int socketTimeout = 1000;
...
kkSocket.connect(sAdress, socketTimeout);

对方在 1 秒内没有响应,所以你得到了一个 SocketTimeoutException。尝试增加超时。还有处理异常的代码——比如增加一个计数器来处理未回答的 ping。

【讨论】:

  • 虽然这是真的,但我想知道这背后的罪魁祸首。:)
  • 好吧 ping 使用的是 ICMP 协议而不是 TCP。您正在尝试连接到 TCP 端口 8000。可能有防火墙。或者是其他东西。我的意思是 - 你不是在模拟 ICMP ping。
【解决方案2】:

几天后,我们终于找到了罪魁祸首,原来,操作系统级别的somaxconn属性,仍然是默认值(128),考虑到我们爆量大,建议客户端配置为1000;

现在,拒绝连接的数量下降了 98.15%,例如,我们可以在 1 天内获得近 400 次拒绝连接,现在,它可以下降到每天 6 - 9 个。

虽然我们仍在努力提供最佳调整配置,但我想感谢大家给我一些建议:)

谢谢

【讨论】:

    【解决方案3】:

    两个结果都有效,区别在于Unix ping 不需要连接到服务器的特定端口。而且看起来您的应用在给定的超时时间内根本没有发送任何响应。

    【讨论】:

    • 不,看起来服务器防火墙正在丢弃连接请求。
    • 你怎么能确定呢?尤其是被给予这么短的超时时间。
    • 连接超时意味着对等 TCP 没有响应。它与应用程序无关。
    • 我们还没有从网络方面进行检查,因为我的客户坚持认为问题出在我的应用程序上,如果我们不能给他们适当的证据,就不会让我们检查网络..是的,超时时间很短,实际上他们在实际生产中给了我们 0.01 秒的超时时间(从接受消息,解码并发送回响应,我认为这很疯狂..但我们做到了)..这只是一个简单的脚本虽然:),零点时间在消息应用程序中很有价值:D
    • 您的应用是否同时成功响应其他主机/网络的请求?如果是,很可能是防火墙/抗病毒软件,如上所述。
    猜你喜欢
    • 2013-05-23
    • 2011-05-11
    • 1970-01-01
    • 2014-05-04
    • 2013-09-08
    • 2012-11-17
    • 2011-02-05
    • 2018-11-26
    • 2020-06-02
    相关资源
    最近更新 更多