日期:2014-05-17  浏览次数:20678 次

HTTP首包时延问题 200分急求高手解答!顶者就有分。
[code=Java][/code]我是linux的服务器上 部署的java程序,公网客户端访问系统,在服务器上测试 www.189.cn,www.youku.com网站都正常,而且速度还挺快,测试结果如下:
Java code
-bash-3.2$ wget 'www.189.cn'
--2012-05-07 09:17:32--  http://www.189.cn/
正在解析主机 www.189.cn... 118.85.207.18
Connecting to www.189.cn|118.85.207.18|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:41881 (41K) [text/html]
Saving to: `index.html.13'

100%[==========================================================================================>] 41,881       217K/s   in 0.2s    

2012-05-07 09:17:32 (217 KB/s) - `index.html.13' saved [41881/41881]

-bash-3.2$ wget 'www.youku.com'
--2012-05-07 09:19:26--  http://www.youku.com/
正在解析主机 www.youku.com... 121.9.204.234
Connecting to www.youku.com|121.9.204.234|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:390160 (381K) [text/html]
Saving to: `index.html.14'

100%[==========================================================================================>] 390,160      120K/s   in 3.2s    

2012-05-07 09:19:29 (120 KB/s) - `index.html.14' saved [390160/390160]


但是为啥我java程序就不能获取到这2个网站的首包时延的,获取首包时延代码如下:希望高手给予解答,是服务器环境问题呢还是代码问题 还是其网站端口 协议不对呢?
Java code
String ip = "1.1.1.1";//此处为dns解析出来的网站IP地址
Socket socket = new Socket();
socket.connect(new InetSocketAddress(ip, 80), 15000);
boolean autoflush = true;
PrintWriter out = new PrintWriter(socket.getOutputStream(), autoflush);
BufferedReader in = new BufferedReader(new InputStreamReader(socket
        .getInputStream()));
// send an HTTP request to the web server
out.println("GET / HTTP/1.1");
out.println("Accept: */*");
out.println("User-Agent: cdut-boy");
out.println("Host: " + load_url);//此处为网站网址
out.println();
logger.info("获取HTTP页面首包时延发包结束,网站网址:load_url=" + load_url);
boolean loop = true;
while (loop)
{
    if (in.ready())//此处 优酷 189 从来就读取不到首包,高手解答
    {
        //..........do something...under...
        loop = false;
    }
}


------解决方案--------------------
这个不清楚,顶一下
------解决方案--------------------
web开发学到这程度,不一般了
------解决方案--------------------
真的很高深。。。顶下!
------解决方案--------------------
所谓首包延时,也就是自你发送完请求后,到服务器返回给你第一个信息中间的耗时。是这个意思吧?

我建议考虑换个思路:
1、在out.println();之后,记录 long timer = System.currentTimeMillis();
2、然后直接in.readLine(),再记录下 timer = System.currentTimeMillis() - timer;

这个其实相当于你的首包延时,片段如下:

out.println("Host: " + load_url);//此处为网站网址
out.println();
out.flush();
long timer = System.currentTimeMillis();
logger.info("获取HTTP页面首包时延发包结束,网站网址:load_url=" + load_url);
String lineFirst = in.readLine();
timer = System.currentTimeMillis() - timer;
logger.info("获取HTTP页面首包时延:" + timer + "ms");

------解决方案--------------------
我拿你的代码试过了,没问题的。不管是in.ready(),in.readLine()都可以的,延时都在10ms左右。
估计是你的网络问题
------解决方案--------------------
其实问题在于 ready() 这个函数,在InputStream中并没有定义,是在 中才有的,而且本身是借助:sun.nio.cs.StreamDecoder 来实现的。所以具体是什么原因导致的,需要花时间研究下。API只是说,它会检查缓冲区中是否有数据,如果有才返回ready()

“获取首包时延 超出需求时限的话 我不好控制”
——嗯,确实会存在卡的问题,这种情况下,可能你需要采用NIO模型来开发,而不是IO模型;NIO提供无阻塞的各种实现。

“用in.readLine()这个时延怎么获得的为60984多”
——我想了下,可能是因为包装了BufferedReader的原因,它要先Buffer一段内容;这种情况下,需要直接使用 socket.getInputStream(),不做任何包装,然后直接 read 1个字节就好了。但是 60秒也太夸张了吧。。。感觉是服务器出错了吧?
------解决方案--------------------