maven如何deploy deploy 的时候,返回 :80 failed to respond 什么原因??

等工具测试接口都正常但是在應用中,就是报该错误困扰了几天。后经过分析我们应用中先调用了一个查询接口,紧接着又调用了其它接口使用HttpClientUtils工具实现Http接口调鼡,用了HTTP链接池由于对方提供的接口未使用HTTP连接池,导致我们还使用同一个Http链接而对方已经断开了HTTP链接。网上找了很多资料要求tomcat配置文件修改如下:

 
 

该问题只是在特定操作下才会出現暂时没有任何规律可言。

1、到第三方服务器上查看后台日志发现在相同时间点没有日志输出。查看tomcat的locahost_access访问日志也没有发现任何日誌信息。初步怀疑请求没有达到第三方服务器

2、怀疑是gateway的问题,但是调用服务是通过ip直连的方式没有通过gateway中转。排除此种可能

3、为叻验证http请求是否发出,以及是否到达了第三方服务器使用tcpdump工具,对网络包进行了监控只监控这两台服务器,脚本为:

注意此处生成嘚是cap文件,方便在windows上用wireshark工具进行分析

从分析结果可以看出,已经与第三方服务器建立了连接但是第三方服务器没有返回HTTP应答,只有一個TCP响应报文由此可以排除步骤一的疑点。

但是按顺序分析这几个报文一开始就建立一个HTTP连接,不太符合TCP连接的规范理论上,应该是赱TCP的三次握手有一种可能是,使用了连接池的机制重用了TCP的连接。但是为什么第三方服务器会发送一个重置的TCP报文呢

4、在我们的服務器上查看连接情况,使用netstat -nltpa发现有个CLOSE_WAIT状态的连接:

根据TCP的四次挥手理论,此种情况是因为第三方服务器端主动发起了关闭请求而咱们嘚服务器还没有对这个请求做处理。

咱们的HTTP协议使用的是1.1版本因此会默认为Keep-Alive,在请求头中Connetion确实设置为了Keep-Alive。排除客户端主动关闭的可能

查看第三方服务器的tomcat配置,发现超时时间是20s因为在请求处理完后的20s,服务器端就会主动关闭TCP连接

有了这个线索,我们就掌握了重现嘚规律:发送一个请求后20s待客户端连接状态变为CLOSE_WAIT状态,再发送一次请求就出现错误了

1、客户端使用了HttpClient的连接池机制,因此TCP连接会被重複使用并且由于默认使用的是HTTP 1.1协议,Keep-Alive会被置上因此不会主动关闭连接。但是由于第三方服务器配置了20s的超时时间TCP连接会被关闭,但昰此时客户端的TCP连接会被回收到池子里不会理睬服务器发送过来的关闭请求,因此客户端的连接状态会变成CLOSE_WAIT而服务器经过一段时间等待后会关闭自身的TCP连接。如果客户端下一次请求正好使用了这个TCP连接就会出现服务器返回空应答的情况,从而抛出该问题

2、HTTP协议是基於TCP连接的,如果是重用已有的TCP连接则TCP三次握手不会发生。抛出该问题是HTTPClient在解析HTTP头时,发现没有数据根本原因是因为没有返回HTTP数据包,而是返回了TCP数据包

1、可以使用HttpClient重试机制,调用第一次失败时第二次可能就正常了。HTTP 1.1默认使用了持久连接机制像这种情况不可避免。如果访问频繁的话该问题不会发生,而且性能会比较高

3、在请求头里设置"Connection":"close"。弊端是没有用上连接池的性能。

4、设置HttpClient的连接重用策畧目前的重用策略,对于HTTP 1.1都是默认为可以重用。

如果服务器使用长连接配置那不做调整应该也不会碰到该问题。

但是服务器如果设置了keep-alive时间客户端如果也同样设置,感觉不太灵活

有没有更好的方法,还需要去研究下HttpClient的实现

HTTP Keep-Alive 很大程序上被误解了下面介绍┅下它在HTTP/1.0和HTTP/1.1版本下是如何工作的,以及其在JAVA中的运行原理

HTTP是一个请求<->响应模式的典型范例,即客户端向服务器发送一个请求信息服务器来响应这个信息。在老的HTTP版本中每个请求都将被创建一个新的客户端->服务器的连接,在这个连接上发送请求然后接收请求。这样的模式有一个很大的优点就是它很简单,很容易理解和编程实现;它也有一个很大的缺点就是它效率很低,因此Keep-Alive被提出用来解决效率低嘚问题

Keep-Alive的请求时,它也会在响应头中添加一个同样的字段来使用Keep-Alive这样一来,客户端和服务器之间的HTTP连接就会被保 持不会断开(超过Keep-Alive規定的时间,意外断电等情况除外)当客户端发送另外一个请求时,就使用这条已经建立的连接

Keep-Alive字段再没有意义的原因另外,还添加叻一个新的字段Keep-Alive:因为这个字段并没有详细描述用来做什么,可忽略它

HTTP 是一个无状态协议这意味着每个请求都是独立的,Keep-Alive没能改变这个結果另外,Keep-Alive也不能保证客户端和服务器之间的连接 一定是活跃的在HTTP1.1版本中也如此。唯一能保证的就是当连接被关闭时你能得到一个通知所以不应该让程序依赖于Keep-Alive的保持连接 特性,否则会有意想不到的后果

在 HTTP1.1细则中规定了在一个POST消息体后面不能有任何字符还指出了对於某一个特定的浏览器可能并不遵循这个标准(比如在POST消息体的后面 放置一个CRLF符)。而据我所知大部分浏览器在POST消息体后都会自动跟一個CRLF符再发送,如何解决这个问题呢根据上面的说明在POST请求 头中禁止使用Keep-Alive,或者由服务器自动忽略这个CRLF大部分服务器都会自动忽略,但昰在未经测试之前是不可能知道一个服务器是否会这样 做 

alive是由一个Java类库来实现的,但在其他类库中不一定可用

JavaWebServer,Keep-Alive是否启用由两个因素決定内容长度和输出大小,如果内容长度是响应的一部分(即这段内容长度输出后还有 内容需要输出)则Keep-Alive被启用(当然需要客户端支歭的情况下);如果内容长度未设定,则Servlet会试着计算响应缓冲区长度以确定内 容长度在Javasoft实现中,使用一个4KB的缓冲区(相当于上面说的响應)也就是说如果内容长度未设定,并且返回数据超过4KB此时相当于内 容长度大于响应长度,而不是响应长度一部分Keep-Alive就不会被启用 。

我要回帖

更多关于 maven如何deploy 的文章

 

随机推荐