
Java 调用 webservice 接口,为什么这么慢,有没有好的优化方案,本人目前改成 http 方式发 soap 消息调用,速度依旧很慢,维持在平均 100ms 下不来。 之前用 cxf 的 JaxWsDynamicClientFactory 速度更加慢,400ms 、500ms 都出现过。
这是现在使用 httpClient 的调用代码
public static String callWebSV(String urlWsdl,String soap,String soapAction){ String result=null; try { CloseableHttpClient httpClient = HttpClients.createDefault(); HttpPost httpPost = new HttpPost(urlWsdl); httpPost.setHeader("Content-Type", "text/xml;charset="); httpPost.setHeader("SOAPAction", soapAction); InputStreamEntity entity = new InputStreamEntity(new ByteArrayInputStream(soap.getBytes())); httpPost.setEntity(entity); CloseableHttpResponse respOnse= httpClient.execute( httpPost); if (response.getStatusLine().getStatusCode() == org.apache.http.HttpStatus.SC_OK) { HttpEntity respOnseEntity= response.getEntity(); String back = EntityUtils.toString(responseEntity); //log.info("httpClient 返回 soap:" + back); result=parseResult(back); log.info("httpClient 返回结果:" + result); } else { log.error("HttpClinet 返回状态码:" + response.getStatusLine().getStatusCode()); } } catch (Exception e) { log.error("调用错误:",e); } return result; } 1 opengps 2021-01-08 13:47:18 +08:00 本地调用慢,还是公网调用慢?还是接口逻辑慢? |
2 changeTheGame OP @opengps 同一网段服务器之间调用,我也不知道为啥慢 |
3 Aidenboss 2021-01-08 13:55:31 +08:00 用链接复用了吗? |
4 changeTheGame OP @Aidenboss 链接复用是什么 |
5 tmackan 2021-01-08 15:07:50 +08:00 @changeTheGame tcp 长连接?不太懂 |
6 tmackan 2021-01-08 15:10:01 +08:00 @Aidenboss 是指异步阻塞的调用?这个只有在比较大并发的情况下有用。单次 url 请求,没啥用,类似的可以参考 gevent,只有在很多 url 请求的时候比较有效果 |
8 yamasa 2021-01-08 15:26:15 +08:00 wireshark 把整个会话抓出来,按时间戳定位问题出在哪里。问题不一定在你代码里,说不定就是 peer 端响应慢。 soap 这种玩意儿真的该淘汰掉了,废话比 json 和 yml 都多,也没有压缩。考虑搞成 grpc 之类的吧。 |
9 djj0809 2021-01-08 15:27:39 +08:00 via iPhone httpclient 复用了么? |
10 yamasa 2021-01-08 15:33:55 +08:00 @changeTheGame 你的这个方法 callWebSV 如果是从多个 thread 大量并发调用,写法就是有问题的,httpClient 应该复用,而不是每次都 create 出来。这是比较重的资源。 |
11 changeTheGame OP @yamasa 我就是多个线程并发调用这个方法的,httpClient 可以复用吗 |
12 yamasa 2021-01-08 15:41:46 +08:00 @changeTheGame 那肯定得复用。而且还应该考虑配置 connPooling,连接池,以及 dead conn scanner 。一步一步优化。 |
13 securityCoding 2021-01-08 15:42:36 +08:00 持续的用 arthas trace 看一下 ,输出到文件,先把性能瓶颈范围确定下来 |
14 php8 2021-01-08 15:49:34 +08:00 via Android 先在你这边压测一下对方 |
15 wucao219101 2021-01-08 15:54:54 +08:00 首先,你这边的 HttpClient 明显没有复用,每次都重新 create,HttpClient 是线程安全的可复用的,具体可以参考: https://hc.apache.org/httpcomponents-client-ga/tutorial/html/fundamentals.html#d5e213 > HttpClient implementations are expected to be thread safe. It is recommended that the same instance of this class is reused for multiple request executions. 另外,可以在调用过程中加一下链路跟踪,最简单的方式就是加一个 Zipkin 观察一下,到底是客户端问题还是服务端问题。 |
16 wucao219101 2021-01-08 16:00:35 +08:00 另外,基本的 close 操作都没有做,CloseableHttpClient 、CloseableHttpResponse 这些都是用过后要关闭的资源,你都没 close,资源用过后都不关闭肯定有问题,当然 CloseableHttpClient 如果复用了就不需要 close,但是 CloseableHttpResponse 肯定是要 close 的。 参考官方案例: https://hc.apache.org/httpcomponents-client-ga/quickstart.html |
17 wysnylc 2021-01-08 17:03:53 +08:00 org.apache.http.client.fluent |
18 hantsy 2021-01-08 17:42:49 +08:00 @changeTheGame 1,你的代码有点晕,看代码姑且说是 SOAP,SOAP 那一套可是国际标准的。 调用 SOAP WebService,太简单了。一般的 SOAP 服务只要从公开的 WSDL 生成客户端代码就可以像本地代码一样的用了。 这类工具很多,比如 NetBeans IDE 中集成了。https://netbeans.org/kb/docs/websvc/client.html 如果项目在本地,NetBeans 自动识别 Soap,拖放操作就可以生成。 另外还有 maven wsdl plugin 也可以生客户端代码。 2, 如果普通的 Http 操作,ApacheHttpClient 太笨重了,操作麻烦,当然功能比较全面。可以尝试 Okhttp 等。 另外 Java 11 自带的 HttpClient 直接用更简单: https://github.com/hantsy/quarkus-sandbox/blob/master/restclient-java11/src/main/java/com/example/PostResourceClient.java. |
19 changeTheGame OP @tmackan 我就是有很多数据网一个 webservice 接口推 |
20 changeTheGame OP @wucao219101 谢谢大佬,有空我看看 zipkin 去 |
21 changeTheGame OP @hantsy 谢谢大佬,我是用 soapui 测试工具生成的 soap 消息,目前放弃使用 http client 了,改回 cxf 调用了,领导急着要没时间改了,有空在看吧 |
22 Kirsk 2021-01-09 10:22:00 +08:00 via Android 这不是你的问题 是对方做了状态存储以至于越来越慢 真的吗这个问题需要链路分析? |
23 hantsy 2021-01-09 11:19:04 +08:00 @changeTheGame SOAP WebService 调用还是用 SOAP Client 比较好,操作上一般可以将 SOAP WSDL 操作,直接映射到本地接口,然后直接调用。 NetBeans 集成应该最智能的,Metro 是 SUN 当年与 MS 和解后,在 Web Service 上合作的产物, 也是应用很广泛的。 生成 Client 代码的例子网上大把,花几分配置一下就完了。 其他也 SOAP Client 也不难,Apache CXF 个人我也不喜欢,但它的确应用很广。 |
24 changeTheGame OP @hantsy 嗯嗯,知道了,谢谢 |