V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
changeTheGame
V2EX  ›  程序员

Java 调用 webservice 接口,为什么这么慢

  •  
  •   changeTheGame ·
    starsky1 · 2021-01-08 13:45:00 +08:00 · 3462 次点击
    这是一个创建于 1394 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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 条附言  ·  2021-01-08 15:39:19 +08:00
    刚才看了一下,对方重启服务器后,我这重启代码,刚开始一段时间,大概半小时,速度维持在 20ms 左右。然后半个小时之后,速度下降到 100ms 到 1000ms 之间,也不知道是什么原因
    24 条回复    2021-01-09 13:00:11 +08:00
    opengps
        1
    opengps  
       2021-01-08 13:47:18 +08:00
    本地调用慢,还是公网调用慢?还是接口逻辑慢?
    changeTheGame
        2
    changeTheGame  
    OP
       2021-01-08 13:48:50 +08:00
    @opengps 同一网段服务器之间调用,我也不知道为啥慢
    Aidenboss
        3
    Aidenboss  
       2021-01-08 13:55:31 +08:00
    用链接复用了吗?
    changeTheGame
        4
    changeTheGame  
    OP
       2021-01-08 13:59:34 +08:00
    @Aidenboss 链接复用是什么
    tmackan
        5
    tmackan  
       2021-01-08 15:07:50 +08:00
    @changeTheGame tcp 长连接?不太懂
    tmackan
        6
    tmackan  
       2021-01-08 15:10:01 +08:00
    @Aidenboss 是指异步阻塞的调用?这个只有在比较大并发的情况下有用。单次 url 请求,没啥用,类似的可以参考 gevent,只有在很多 url 请求的时候比较有效果
    tmackan
        7
    tmackan  
       2021-01-08 15:10:20 +08:00
    @Aidenboss 异步非阻塞 说错了
    yamasa
        8
    yamasa  
       2021-01-08 15:26:15 +08:00
    wireshark 把整个会话抓出来,按时间戳定位问题出在哪里。问题不一定在你代码里,说不定就是 peer 端响应慢。

    soap 这种玩意儿真的该淘汰掉了,废话比 json 和 yml 都多,也没有压缩。考虑搞成 grpc 之类的吧。
    djj0809
        9
    djj0809  
       2021-01-08 15:27:39 +08:00 via iPhone
    httpclient 复用了么?
    yamasa
        10
    yamasa  
       2021-01-08 15:33:55 +08:00
    @changeTheGame 你的这个方法 callWebSV 如果是从多个 thread 大量并发调用,写法就是有问题的,httpClient 应该复用,而不是每次都 create 出来。这是比较重的资源。
    changeTheGame
        11
    changeTheGame  
    OP
       2021-01-08 15:37:38 +08:00
    @yamasa 我就是多个线程并发调用这个方法的,httpClient 可以复用吗
    yamasa
        12
    yamasa  
       2021-01-08 15:41:46 +08:00
    @changeTheGame 那肯定得复用。而且还应该考虑配置 connPooling,连接池,以及 dead conn scanner 。一步一步优化。
    securityCoding
        13
    securityCoding  
       2021-01-08 15:42:36 +08:00
    持续的用 arthas trace 看一下 ,输出到文件,先把性能瓶颈范围确定下来
    php8
        14
    php8  
       2021-01-08 15:49:34 +08:00 via Android
    先在你这边压测一下对方
    wucao219101
        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 观察一下,到底是客户端问题还是服务端问题。
    wucao219101
        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
    wysnylc
        17
    wysnylc  
       2021-01-08 17:03:53 +08:00
    org.apache.http.client.fluent
    hantsy
        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.
    changeTheGame
        19
    changeTheGame  
    OP
       2021-01-09 07:05:55 +08:00 via iPhone
    @tmackan 我就是有很多数据网一个 webservice 接口推
    changeTheGame
        20
    changeTheGame  
    OP
       2021-01-09 07:07:26 +08:00 via iPhone
    @wucao219101 谢谢大佬,有空我看看 zipkin 去
    changeTheGame
        21
    changeTheGame  
    OP
       2021-01-09 07:12:59 +08:00 via iPhone
    @hantsy 谢谢大佬,我是用 soapui 测试工具生成的 soap 消息,目前放弃使用 http client 了,改回 cxf 调用了,领导急着要没时间改了,有空在看吧
    Kirsk
        22
    Kirsk  
       2021-01-09 10:22:00 +08:00 via Android
    这不是你的问题 是对方做了状态存储以至于越来越慢 真的吗这个问题需要链路分析?
    hantsy
        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 个人我也不喜欢,但它的确应用很广。
    changeTheGame
        24
    changeTheGame  
    OP
       2021-01-09 13:00:11 +08:00
    @hantsy 嗯嗯,知道了,谢谢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2728 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 12:24 · PVG 20:24 · LAX 05:24 · JFK 08:24
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.