加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Axis2 webservice中close_wait,java heap space错误

发布时间:2020-12-17 00:37:45 所属栏目:安全 来源:网络整理
导读:客户端伪代码如下 //主线程方法 while(true){ ? ?? ?test.TestGetServiceStatus();//客户端连接服务端的测试方法 ?try{ ?Thread.sleep(23 * 1000);//每隔23秒执行下webservice客户端方法 ?}catch(Exception e){ ?e.printStackTrace(); ?} } private String w
客户端伪代码如下
//主线程方法
while(true){
? ?? ?test.TestGetServiceStatus();//客户端连接服务端的测试方法
?try{
?Thread.sleep(23 * 1000);//每隔23秒执行下webservice客户端方法
?}catch(Exception e){
?e.printStackTrace();
?}
}

private String wsUrl = "http://127.0.0.1:8080/axis2/services/webservice/";
?public void TestGetServiceStatus(){
?WebserviceStub stub = null;
?stub = new WebserviceStub(wsUrl);//实例华客户端
?System.out.println("new a stub");
?Thread.sleep(5000);//5秒钟后执行客户端向服务端的请求
?String result = stub.queryServiceStatus(request).getResult();//请求服务端
?System.out.println("result: " + result);
//清除客户端
?stub._getServiceClient().cleanupTransport();
?stub._getServiceClient().cleanup();
?stub.cleanup();
?stub = null;
步骤解释:
1、主线程每隔23秒调用方法,来实现客户端对服务端的调用
2、客户端在对服务段进行借口调用时:
?2.1、实例化客户端对象
?2.2、睡5秒钟
?2.3、调用服务端接口,得到结果
?2.4、清除客户端
3、服务端的相应接口,收到请求后,睡眠25秒,给出结果。
4、webservice服务端配置文件里,加入连接的存活时间,为20s,如下(axis2.xml):
<transportReceiver name="http"
?class="org.apache.axis2.transport.http.SimpleHTTPServer">
?<parameter name="port">8080</parameter>
?<parameter name="threadKeepAliveTime">20</parameter>
</transportReceiver>
基于以上的调用,用ethereal抓包得到下图:

Axis2?<wbr>webservice中close_wait,java?<wbr>heap?<wbr>space错误


注意两个绿色框的内容,详细过程分析如下:
1、new stub的时候,客户端与服务端并没有连接;
2、5秒钟后,客户端向服务端发送请求,连接建立,如 图的1—7个数据包;
3、测试客户端做出处理,即睡眠25秒,之后返回数据,如图的8—23个数据包;
4、客户端收到数据后,cleanup,方法退出,但是此时看到连接并没有关闭;
5、服务端在20秒后(设置的连接存活时间),断开连接,如图的24,25个数据包;
6、由于客户端这边在25秒的时候(23个数据包所示)退出了方法,过23秒后重新调用测试方法,于是应该在48秒的时候,重新new stub,这个时候,看图知道,在第26个数据包的时候(也就是48秒的时候)客户端发出了先前连接的断开包,至此前一个连接完全释放,开始下一轮的连接循环。
由此可以得出:
1、客户端new stub的时候,并没有与服务端建立连接,而只是释放之前的连接;
2、连接是由服务端先发起的;
3、客户端发送服务端请求的时候,连接由客户端发起,并建立;
由上面的结论可以分析出一个问题:客户端在调用服务端接口方法,并退出后,连接还存在,直到连接存活时间达到服务端设置的连接存活时间后,才被服务端所关闭,这个时候,如果客户端不再重新发起请求,或者客户端出错(内存溢出,无法new stub等) ,那么之前 的那个连接就一直会处在close_wait状态,而无法清除。这就是为什么有些webservice客户端这边,跑了一段时间后,会出现很多close_wait状 态的连接的缘故。
?再来看,是什么原因导致了new stub的时候出错的呢?上面也讲到了,虽然可能性有很多,但是有一个却是大家经常犯的,那就是客户端这边内存溢出了。
?很多webservice客户端,在跑了很长时间后,发现内存就不够用了,抛出java heap space的错误,随之而来的就是类似Read Timeout阿等错误,这样close_wait就越 来越多,这些错误也会越抛越多……直到整个客户端都无法与服务端取得任何连接,而进入“假死”状态。那么如何避免客 户端内存持续走高呢?
?通过jdk自带的jconsole和eclipse提供 的memory analyzer可以看到,客户端这边的内存在不断上升,java的gc根本无法释放使用过的内存,而通过memory analyzer可以看到,很多堆内存都在客户端调用服务端的方法里,无法释放(图就不上了)。也就是说,这不是我们实现某功能时自己的原因导致的内存溢出,而是axis2本身的内存溢出。那是不是就没有办法解决了呢?不是的!
?细心的你有没有注意到开篇的时候我提供的客户端的伪代码?里 面有四句:
stub._getServiceClient().cleanupTransport();

当时加这四句代码,只是为了验证客户端时候能把连接主动关闭,可是结果是否定的,但是,恰好是这几句解决了内存溢出的问题!只要在每次客户端调用后,都执行以上四句代码,那么客户端new出来的堆内存资源就可以被java的gc所回收掉了。


本文转载自:http://blog.sina.com.cn/s/blog_4ab52f1e0100dmfp.html

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读