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=UTF-8");
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 嗯嗯,知道了,谢谢
|