一、前言
测试环境发现有一个操作一直没有进行,排查后发现是rabbitmq队列卡住了。
接收的后端代码已经加了完备的try-catch
了,但是队列仍然卡住了,并且日志没有报错,就很奇怪。
二、排查过程
1.找到@RabbitListener
,先把其中的所有代码删掉,只打印下消息日志,然后发测试,发现这样就可以清空mq队列。
2.恢复测试代码,手写一个controller,入参mq消息json,调用mq处理逻辑,准备打断点测试。
3.查看消息日志,传入手写的controller,打断点测试,发现到一个方法卡住了:
try {JaxWsDynamicClientFactory dcf=JaxWsDynamicClientFactory.newInstance();Client client= dcf.createClient("http://128.0.0.1/A/services/BService?wsdl");//这个是对面系统的webservice方法名,与入参,<xml>格式的入参报文//就是这里卡住了Object[] resultObj = client.invoke("createOrenableAccount", new Object[] { accountToXML(userName) });String retXML = resultObj[0].toString();StringReader read = new StringReader(retXML);InputSource source = new InputSource(read);SAXBuilder sb = new SAXBuilder();Document doc = sb.build(source);Element root = doc.getRootElement();LOGGER.info(root.getChildText("code"));// 0 成功LOGGER.info(root.getChildText("code") + ", " + root.getChildText("message"));} catch (Exception e) {LOGGER.error((new StringBuilder("invokeWS Exception:")).append(e).toString(),e);}------------------public static String accountToXML(String userName) {Document document = null;Element et = new Element("account");document = new Document(et);document = addNode(document, "appname", "AI");document = addNode(document, "uid", userName);document = addNode(document, "eruid", userName);return documentStr(document);}
看来是调用其它系统的webservice接口,长时间未响应,接口超时时间>mq超时时间,导致mq消息处理失败,队列就卡住了。
三、解决方法
需要设置webservice请求超时时间,要注意小于mq消息处理超时时间才行。
找到了这个,不过还没有测试:https://www.yii666.com/blog/169638.htmlrequestContext.put("com.sun.xml.internal.ws.connection.timeout", 10 * 1000);//建立连接的超时时间为10秒
requestContext.put("com.sun.xml.internal.ws.request.timeout", 15 * 1000);//指定请求的响应超时时间为15秒//在调用接口方法时,内部会发起一个HTTP请求,发起HTTP请求时会从BindingProvider的getRequestContext()返回结果中获取超时参数,
//分别对应com.sun.xml.internal.ws.connection.timeout和com.sun.xml.internal.ws.request.timeout参数,
//前者是建立连接的超时时间,后者是获取请求响应的超时时间,单位是毫秒。如果没有指定对应的超时时间或者指定的超时时间为0都表示永不超时。
如果不设置,会永不超时,坑。