很多时候我们在考虑遇到问题后首先要关注问题的场景,技术类问题是否有具体的异常日志,对于服务超时问题即存在几种情况,一种是能够获取到具体的超时异常信息,一种是根本没有异常信息返回。超时问题影响方面太多,包括一个recv time out的异常,Oracle官方文档就有6-7个场景和设置检查点。
超时问题困扰我们很久,包括各种技术资料的查找,测试环境测试和模拟验证,Oracle官方的技术支持,修改代码增加日志记录等各方面的尝试,从最终暴露问题到最终解决跨度超过1年。到问题真正解决后再回顾,一个重要结论就是任何技术性问题,只要足够重视,科学分析,足够测试和验证,都可以得到快速解决。要知道每朝前面走一步,就是将问题的范围缩小一步。最终需要的就是一个质变的突破。
当拿到服务超时问题的时候,我们仍然先分析问题场景,涉及到我们的导入和查询服务,有些有返回信息,有些无返回信息。对于有返回信息的进一步进行分析,对于无返回的进一步查询应用服务器本身的log日志。通过最终日志的分析,最终定位到java.net.SocketTimeoutException: Read timed out上面,在这个之前Oracle技术顾问尝试多种方法,包括对recv time out尝试,基本都没有踩到点。Oracle给的尝试方法:
方法一、可以在 Java代码中加入:
1、System.setProperty("sun.net.client.defaultConnectTimeout", String.valueOf(10000));//
2、System.setProperty("sun.net.client.defaultReadTimeout", String.valueOf(10000)); //
方法二、在Apache中增大客户端连接超时的设置
在 httpd.conf 加入了,再看看反馈情况如何。
#Timeout:接收和发送数据的超时设置,秒数 Timeout 600!
好了,根据SocketTimeoutException进一步对问题进行跟踪查询,查到的最多方法即是增加客户端超时时间设置,根据这点我们又对客户端框架超时时间设置,BPEL超时时间设置,服务提供端超时时间设置多个方面进行了检查,都没有发现明显的问题。
BPEL服务的超时设置是否出问题?我们又详细的对两处transaction-timeout,一处syncMaxWaitTime超时时间设置进行了检查,没有明显发现问题。同时进一步了解到各个超时设置的具体应用。比如同步最大等待时间设置的作用和控制点等。很多时候查询问题都带来意外知识点学习和收获,大家不要忽视这点。对于BPEL超时设置查询到该文章:
http://docs.oracle.com/cd/B31017_01/integrate.1013/b28981/app_trblshoot.htm
该超时问题一直以来只有一个业务系统反馈,另外业务系统在消费服务时候没有出现,一个系统用axis框架,一个是用的cxf框架。是否会和使用的客户端框架有关系。有问题的场景和无问题的场景对比很重要,帮助我们确定需要逐个排除的点。最终我们查到这篇文章:
http://tech.ddvip.com/2009-05/1242616837119630.html
由于报错异常完全一样,以为该问题能够得到解决,但是修改测试后仍然无效果,该路还是不通。
多次的无结果不断大家我们的信心,基于经验的提出假设逐个验证的解决方法往往很多时候并不能快速解决问题,特别是选择的问题分支本身错误,直接误入歧途。那接下来又需要回到全面的问题分析和诊断上,包括从根源上去理解问题,从全流程去分析问题。
对于根源理解问题,需要去理解的核心就是SocketTimeoutException: Read timed out的根源是什么?有哪些场景会出现该异常,一定要遍历所有场景逐个分析。对于全流程分析上,我们需要考虑从服务消费端发起调用,到完成调用的整个过程是如何的?中间经过了哪些关键环节,每个关键环节又做了哪些事情?
我们进一步对Axis和SocketTimeout的机制进行分析,在网上查询到一篇文章详细解释如下:
Axis在客户端和服务端之间设置两个分别的Socket连接,一个传输数据,一个用来查询客户端是否还在。在Axis中,默认的超时时间是60秒,所以在过了60秒后,它就会主动去查询一下服务端的状态,叫做GetUpdate操作,看服务端是否还有在更新操作(一般来说是读或写,一般异常抛出后会提示你Read time out或Write time out),如果没有,就会抛出相应的异常返回客户端,但是为了保持性能,因为不能频繁的去查询服务端的状态,为了避免这个,就会设置一个默认的频率去查询,在Axis中是5分钟一次。
说到这,有的人可能就想到了,如果恰好服务端刚刚从Socket连 接中读取了数据,然后去执行相应的操作,而此时Axis的客户端恰好来查询,一查发现服务端已经没有在更新了,所以此时就会抛出异常了,但是Axis并不 笨,它也考虑到了这种情况,所以它在抛出异常之后,仍会去循环中去重新GetUpdate操作,所以这就是为什么虽然抛出了异常,但是我的任务还一直在执 行的原因,任务确实执行完成之后呢,Axis也就知道此时服务端已经没有更新了,就会自动断开Socket连接,至此整个程序的周期也结束了。我们应如何修改呢,一般来说有两种方法,一是增加Axis的Socket Timeout的值,一是可以把捕捉SocketTimeOutException的Catch模块修改一下,让它不抛出异常,而是只打印提示语句,比如 说正在重新更新服务端状态等,这样的话就可以避开那个异常,让你老觉得不舒服,总之一句话,这个异常不是很重要的异常,你可以不Care它的。
看了这段有,有豁然开朗的感觉,首先对于耗时查询服务,在调用发生后,由于服务器端需要耗费大量时间查询结果,这个时候在连接上面是没有数据传输的。因此Axis需要每5分钟发出一个消息去确认连接是否断掉了?如果服务器端连接状态还在,那么应该就不会出问题。
那是否Axis每5分钟发出的消息都能够正常的访问到服务器端状态?或者说连接上没有数据传输是否就是引起超时的原因?再分析整个数据传输过程为服务消费端,四层交换,BPEL应用服务器,服务提供端。而且在结合测试环境从来没有报过服务超时错误,测试环境和生产环境的一个大差异就是生产环境启用了负载均衡设备。这个时候我们又提出假设是否问题出在四层交换上,负载均衡设备是否有相关超时设置。
为了进一步验证假设,我们重新对服务进行调用,不走负载均衡设备而直接访问生产应用服务器,经过多次测试没有发生服务超时问题。通过这个假设和验证,我们基本确定为负载均衡设备引起的问题。为了进一步分析论证,还得到百度文库查找负载均衡设备详细的用户手册和详细参数配置手册。在配置手册里面我们找到关键资料,如下:
在 farm table中的配置中,需要特别注意
aging time 设置会话的超时时间,缺省 60秒,对于 http业务,可以降低到10秒以下,
session mode 缺省是 entry per session. 基于三层 IP地址的会话保存方式
如果时 HTTP业务或者Mail业务,可以使用 sever per session方式:基于四层信息的会话保存方式
再对比我们的设置,首先是超时设置是默认值60秒没有修改,其次是session mode我们采用的是sever per session基于四层的会话保持而非默认值。对于aging time最终查找资料后明确为只要连接上没有任何数据流往来,超过规定的时间后会话即会超时,如何我们刚才所说的场景和情况。
走到这里,工作就基本完成,找厂家的技术支持工程师过来,当面沟通后最终确认前面分析完全正确。后面修改aging time 和 session mode 后,问题完全得到解决。相关资料参考:
Oracle知识库和Metalink
http://kr.forums.oracle.com/forums/thread.jspa?threadID=910389
https://forums.oracle.com/forums/thread.jspa?threadID=504956
http://kr.forums.oracle.com/forums/thread.jspa?threadID=648004
ORABPEL-02152
http://download.oracle.com/docs/cd/B31017_01/integrate.1013/b28981/app_trblshoot.htm
https://forums.oracle.com/forums/thread.jspa?threadID=622275 transaction time out
BPEL超时设置maxtimeout
http://vikrantbhardwaj.wordpress.com/2009/10/28/syncmaxwaittime-in-oracle-bpel/
http://vikrantbhardwaj.wordpress.com/2009/10/28/syncmaxwaittime-in-oracle-bpel/
http://www.samaxes.com/2009/04/axis-14-read-timed-out-and-http-11/
HA双机下面的超时设置
http://hi.baidu.com/djlin/blog/item/c00bd839ecf932ff3b87ceba .html
http://wenku.baidu.com/view/11ccdb41a8956bec0975e33c .html
超时问题困扰我们很久,包括各种技术资料的查找,测试环境测试和模拟验证,Oracle官方的技术支持,修改代码增加日志记录等各方面的尝试,从最终暴露问题到最终解决跨度超过1年。到问题真正解决后再回顾,一个重要结论就是任何技术性问题,只要足够重视,科学分析,足够测试和验证,都可以得到快速解决。要知道每朝前面走一步,就是将问题的范围缩小一步。最终需要的就是一个质变的突破。
当拿到服务超时问题的时候,我们仍然先分析问题场景,涉及到我们的导入和查询服务,有些有返回信息,有些无返回信息。对于有返回信息的进一步进行分析,对于无返回的进一步查询应用服务器本身的log日志。通过最终日志的分析,最终定位到java.net.SocketTimeoutException: Read timed out上面,在这个之前Oracle技术顾问尝试多种方法,包括对recv time out尝试,基本都没有踩到点。Oracle给的尝试方法:
方法一、可以在 Java代码中加入:
1、System.setProperty("sun.net.client.defaultConnectTimeout", String.valueOf(10000));//
2、System.setProperty("sun.net.client.defaultReadTimeout", String.valueOf(10000)); //
方法二、在Apache中增大客户端连接超时的设置
在 httpd.conf 加入了,再看看反馈情况如何。
#Timeout:接收和发送数据的超时设置,秒数
好了,根据SocketTimeoutException进一步对问题进行跟踪查询,查到的最多方法即是增加客户端超时时间设置,根据这点我们又对客户端框架超时时间设置,BPEL超时时间设置,服务提供端超时时间设置多个方面进行了检查,都没有发现明显的问题。
BPEL服务的超时设置是否出问题?我们又详细的对两处transaction-timeout,一处syncMaxWaitTime超时时间设置进行了检查,没有明显发现问题。同时进一步了解到各个超时设置的具体应用。比如同步最大等待时间设置的作用和控制点等。很多时候查询问题都带来意外知识点学习和收获,大家不要忽视这点。对于BPEL超时设置查询到该文章:
http://docs.oracle.com/cd/B31017_01/integrate.1013/b28981/app_trblshoot.htm
该超时问题一直以来只有一个业务系统反馈,另外业务系统在消费服务时候没有出现,一个系统用axis框架,一个是用的cxf框架。是否会和使用的客户端框架有关系。有问题的场景和无问题的场景对比很重要,帮助我们确定需要逐个排除的点。最终我们查到这篇文章:
http://tech.ddvip.com/2009-05/1242616837119630.html
由于报错异常完全一样,以为该问题能够得到解决,但是修改测试后仍然无效果,该路还是不通。
多次的无结果不断大家我们的信心,基于经验的提出假设逐个验证的解决方法往往很多时候并不能快速解决问题,特别是选择的问题分支本身错误,直接误入歧途。那接下来又需要回到全面的问题分析和诊断上,包括从根源上去理解问题,从全流程去分析问题。
对于根源理解问题,需要去理解的核心就是SocketTimeoutException: Read timed out的根源是什么?有哪些场景会出现该异常,一定要遍历所有场景逐个分析。对于全流程分析上,我们需要考虑从服务消费端发起调用,到完成调用的整个过程是如何的?中间经过了哪些关键环节,每个关键环节又做了哪些事情?
我们进一步对Axis和SocketTimeout的机制进行分析,在网上查询到一篇文章详细解释如下:
Axis在客户端和服务端之间设置两个分别的Socket连接,一个传输数据,一个用来查询客户端是否还在。在Axis中,默认的超时时间是60秒,所以在过了60秒后,它就会主动去查询一下服务端的状态,叫做GetUpdate操作,看服务端是否还有在更新操作(一般来说是读或写,一般异常抛出后会提示你Read time out或Write time out),如果没有,就会抛出相应的异常返回客户端,但是为了保持性能,因为不能频繁的去查询服务端的状态,为了避免这个,就会设置一个默认的频率去查询,在Axis中是5分钟一次。
说到这,有的人可能就想到了,如果恰好服务端刚刚从Socket连 接中读取了数据,然后去执行相应的操作,而此时Axis的客户端恰好来查询,一查发现服务端已经没有在更新了,所以此时就会抛出异常了,但是Axis并不 笨,它也考虑到了这种情况,所以它在抛出异常之后,仍会去循环中去重新GetUpdate操作,所以这就是为什么虽然抛出了异常,但是我的任务还一直在执 行的原因,任务确实执行完成之后呢,Axis也就知道此时服务端已经没有更新了,就会自动断开Socket连接,至此整个程序的周期也结束了。我们应如何修改呢,一般来说有两种方法,一是增加Axis的Socket Timeout的值,一是可以把捕捉SocketTimeOutException的Catch模块修改一下,让它不抛出异常,而是只打印提示语句,比如 说正在重新更新服务端状态等,这样的话就可以避开那个异常,让你老觉得不舒服,总之一句话,这个异常不是很重要的异常,你可以不Care它的。
看了这段有,有豁然开朗的感觉,首先对于耗时查询服务,在调用发生后,由于服务器端需要耗费大量时间查询结果,这个时候在连接上面是没有数据传输的。因此Axis需要每5分钟发出一个消息去确认连接是否断掉了?如果服务器端连接状态还在,那么应该就不会出问题。
那是否Axis每5分钟发出的消息都能够正常的访问到服务器端状态?或者说连接上没有数据传输是否就是引起超时的原因?再分析整个数据传输过程为服务消费端,四层交换,BPEL应用服务器,服务提供端。而且在结合测试环境从来没有报过服务超时错误,测试环境和生产环境的一个大差异就是生产环境启用了负载均衡设备。这个时候我们又提出假设是否问题出在四层交换上,负载均衡设备是否有相关超时设置。
为了进一步验证假设,我们重新对服务进行调用,不走负载均衡设备而直接访问生产应用服务器,经过多次测试没有发生服务超时问题。通过这个假设和验证,我们基本确定为负载均衡设备引起的问题。为了进一步分析论证,还得到百度文库查找负载均衡设备详细的用户手册和详细参数配置手册。在配置手册里面我们找到关键资料,如下:
在 farm table中的配置中,需要特别注意
aging time
session mode
如果时 HTTP业务或者Mail业务,可以使用 sever per session方式:基于四层信息的会话保存方式
再对比我们的设置,首先是超时设置是默认值60秒没有修改,其次是session mode我们采用的是sever per session基于四层的会话保持而非默认值。对于aging time最终查找资料后明确为只要连接上没有任何数据流往来,超过规定的时间后会话即会超时,如何我们刚才所说的场景和情况。
走到这里,工作就基本完成,找厂家的技术支持工程师过来,当面沟通后最终确认前面分析完全正确。后面修改aging time 和 session mode 后,问题完全得到解决。相关资料参考:
Oracle知识库和Metalink
http://kr.forums.oracle.com/forums/thread.jspa?threadID=910389
https://forums.oracle.com/forums/thread.jspa?threadID=504956
http://kr.forums.oracle.com/forums/thread.jspa?threadID=648004
ORABPEL-02152
http://download.oracle.com/docs/cd/B31017_01/integrate.1013/b28981/app_trblshoot.htm
https://forums.oracle.com/forums/thread.jspa?threadID=622275
BPEL超时设置maxtimeout
http://vikrantbhardwaj.wordpress.com/2009/10/28/syncmaxwaittime-in-oracle-bpel/
http://vikrantbhardwaj.wordpress.com/2009/10/28/syncmaxwaittime-in-oracle-bpel/
http://www.samaxes.com/2009/04/axis-14-read-timed-out-and-http-11/
HA双机下面的超时设置
http://hi.baidu.com/djlin/blog/item/c00bd839ecf932ff3b87ceba
http://wenku.baidu.com/view/11ccdb41a8956bec0975e33c