簡體   English   中英

Eclipse生成的Web服務客戶端非常慢

[英]Eclipse Generated Web Service Client Extremely Slow

一些前期信息:

我有一個SOAP服務(使用JAX-WS(端點類)托管,但是我認為這並不重要)。

通過Visual Studio生成客戶端(C#),我可以連接並使用Web服務。

我使用Eclipse Web Tools(新->其他-> Web服務-> Web服務客戶端)生成了一個Java客戶端。

然后,我編寫了一個JUnit測試來測試客戶端。 測試通過了,但是運行時間非常長。 每個服務呼叫需要300秒(給定或花費幾秒鍾)。 此外,計算機的速度也無關緊要。 如果我在工作速度非常慢的筆記本電腦上運行此程序,則與在快速家用計算機上運行該程序所花費的時間相同。

我已經在org.apache.axis.encoding.DeserializationContext中調試了以下功能的軸代碼:

public void parse() throws SAXException
    {
        if (inputSource != null) {
            SAXParser parser = XMLUtils.getSAXParser();
            try {
                parser.setProperty("http://xml.org/sax/properties/lexical-handler", this);
                parser.parse(inputSource, this);

                try {
                    // cleanup - so that the parser can be reused.
                    parser.setProperty("http://xml.org/sax/properties/lexical-handler", nullLexicalHandler);
                } catch (Exception e){
                    // Ignore.
                }

沒有驚喜,但是對parser.parse()的調用占用了300秒。 來自網絡的服務非常短,因此不需要花費很多時間來解析。

如果有人想知道,解析器的實際類型是com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl

我無法調試它,因為我沒有源代碼(並且我已經厭倦了在常用庫中深入調試50個調用)。

我當前正在運行探查器,以包括來自Sun的軟件包。 完成后,我將發布我的調查結果(添加所有這些軟件包會大大降低測試速度)

我正在運行Eclipse 3.5.1並且正在使用axis 1.4

編輯:

這是JUnit測試:

@Test
public void testExecuter() throws IOException, InterruptedException, RemoteException, ServiceException
{
    //Listener l = new Listener(3456);
    //l.start();
    Executer exec = new ExecuterServiceLocator().getExecuterPort();
    //Executer exec = new ExecuterProxy("http://localhost:3456/Executer");
    System.out.println("executer created");
    _return remote = exec.execute("perl -e \"print 5\"", new EvAction[0]);
    System.out.println("after call 1");
    assertEquals("5", remote.getStdout());
    assertEquals("", remote.getStderr());
    assertEquals(0, remote.getReturnCode());
}

注意:兩種創建執行者的方式都會發生相同的事情

編輯2:

這是我用來啟動服務的代碼:

public static void main(String[] args) {
    Endpoint.create(new Executer()).publish("http://localhost:3456/Executer");
}

我無法發布URL,因為我現在只是在一台機器上開發它。 但是,如果我轉到http:// localhost:3456 / Executer?WSDL ,這是生成的WSDL。

<!--
 Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.6 in JDK 6. 
-->
−
<!--
 Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.6 in JDK 6. 
-->
−
<definitions targetNamespace="http://executer/" name="ExecuterService">
−
<types>
−
<xsd:schema>
<xsd:import namespace="http://executer/" schemaLocation="http://localhost:3456/Executer?xsd=1"/>
</xsd:schema>
</types>
−
<message name="Execute">
<part name="parameters" element="tns:Execute"/>
</message>
−
<message name="ExecuteResponse">
<part name="parameters" element="tns:ExecuteResponse"/>
</message>
−
<message name="IOException">
<part name="fault" element="tns:IOException"/>
</message>
−
<message name="InterruptedException">
<part name="fault" element="tns:InterruptedException"/>
</message>
−
<portType name="Executer">
−
<operation name="Execute">
<input message="tns:Execute"/>
<output message="tns:ExecuteResponse"/>
<fault message="tns:IOException" name="IOException"/>
<fault message="tns:InterruptedException" name="InterruptedException"/>
</operation>
</portType>
−
<binding name="ExecuterPortBinding" type="tns:Executer">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
−
<operation name="Execute">
<soap:operation soapAction=""/>
−
<input>
<soap:body use="literal"/>
</input>
−
<output>
<soap:body use="literal"/>
</output>
−
<fault name="IOException">
<soap:fault name="IOException" use="literal"/>
</fault>
−
<fault name="InterruptedException">
<soap:fault name="InterruptedException" use="literal"/>
</fault>
</operation>
</binding>
−
<service name="ExecuterService">
−
<port name="ExecuterPort" binding="tns:ExecuterPortBinding">
<soap:address location="http://localhost:3456/Executer"/>
</port>
</service>
</definitions>

編輯:

我認為這可能會引起問題:

我使用TCPMonitor查看SOAP請求,並且注意到客戶端正在使用HTTP / 1.0,而服務器正在使用HTTP / 1.1,但是我不知道這是否引起了問題。 我目前正在嘗試弄清楚如何使客戶端使用HTTP / 1.1。

如果有人在想,以下是SOAP消息:

POST /Executer HTTP/1.0
Content-Type: text/xml; charset=utf-8
Accept: application/soap+xml, application/dime, multipart/related, text/*
User-Agent: Axis/1.4
Host: USENBOONETL1C:2222
Cache-Control: no-cache
Pragma: no-cache
SOAPAction: ""
Content-Length: 354

<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><Execute xmlns="http://executer/"><arg0 xmlns="">perl -e &quot;print 5&quot;</arg0></Execute></soapenv:Body></soapenv:Envelope>

和響應:

HTTP/1.1 200 OK
Content-type: text/xml;
charset="utf-8"
Content-length: 266

<?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><ns2:ExecuteResponse xmlns:ns2="http://executer/"><return><stdout>5</stdout><stderr></stderr><returnCode>0</returnCode></return></ns2:ExecuteResponse></S:Body></S:Envelope>

編輯:

最后! 原來將HTTP客戶端更改為CommonsHTTPClient並使用HTTP / 1.1解決了該問題:

這是我添加到客戶端中修復它的代碼:

BasicClientConfig basicClientConfig = new BasicClientConfig();
SimpleChain simpleChain = new SimpleChain();

simpleChain.addHandler(new CommonsHTTPSender());
basicClientConfig.deployTransport("http", simpleChain);

ExecuterServiceLocator l = new ExecuterServiceLocator(basicClientConfig);
...

注意:您必須將common-httpclient.jarcommon.codec.jar添加到類路徑。

我遇到了同樣的問題,並解決了修改http版本的問題。

一種更簡單的方法是在存根類內部,在Call實例上調用setProperty方法:

_call.setProperty(MessageContext.HTTP_TRANSPORT_VERSION,HTTPConstants.HEADER_PROTOCOL_V11);

1)驗證C#和Java客戶端正在向服務器發送完全相同的請求。 如果您使用的是Jetty,則打開請求日志記錄可能會為您提供所需的數據。

2)一旦SAX解析器開始在客戶端上運行,它將進行回調,這些回調將直接或間接地在生成的客戶端中調用方法。 您應該能夠在生成的客戶端方法的開始和結束(和/或return s)處設置斷點,並使用這些斷點來確定延遲發生的位置。

(順便說一句,在SAX API中,本地使用http://xml.org/sax/properties/lexical-handler類的URL來標識屬性名稱;在該地址什么也找不到。請參見http:// xerces.apache.org/xerces2-j/properties.html了解更多信息。)

您的問題正是我現在所面臨的。 有趣的是,我經歷了幾乎相同的周期(端點服務,.net客戶端工作正常,而eclipse生成的客戶端花費了5分鍾的處理時間)。 的確,感謝您發布更新和解決方案。 我不是精通Java的人,所以請問您是否將解決方案應用於相同的Eclipse生成的客戶端代碼? 還是您做了完全不同的事情? 如果您修改了eclipse生成的客戶端代碼,那么您到底在哪里添加了這些行?

謝謝,我也非常感謝您的幫助:)

干杯,阿拉什

最有可能是超時。 可能是該解析器試圖從Internet(DTD,XSD等)下載內容,但您位於代理/防火牆的后面。

在運行測試時嘗試獲取服務器的堆棧跟蹤信息,以查看發生了什么事情(例如jps / jstat)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM