<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 42,comments - 83,trackbacks - 0

            這幾天碰到個問題:在weblogic中調用async webservice,如果客戶端不等待結果(比如服務器端因為某些原因,web service需要執行很長時間),直接退出的話,weblogic server是否保存調用結果,結果保存多長時間? 如果這樣的異常客戶端很多,對服務器有什么負面影響,比如連接資源、內存開銷等。

            首先我們先闡述一下異步的概念 在weblogic webservice中,有兩處異步的概念:
            1:Synchronous request-response (the default behavior) means that every time a client application invokes a Web Service operation, it receives a SOAP response, even if the method that Choosing RPC-Oriented or Document-Oriented Web Services Programming WebLogic Web Services 4-3 implements the operation returns void. Asynchronous one-way means that the client never receives a SOAP response, even a fault or exception.
            默認情況下,weblogic webservice是請求-應答模式的,即客戶端會block當前線程,直到server端處理完該請求(即使該請求沒有任何返回值,void)。當web service不返回結果,客戶端只是提交請求,不需要知道執行結果的時候,可以采用異步單向模式。這種情況下,客戶端線程為非阻塞的,它只負責提交請求,而不需要返回結果。定義這樣的異步web service時,需要遵循如下的兩個原則:
              1.1:The back-end component that implements the operation must explicitly return void.
              1.2:You cannot specify out or in-out parameters to the operation, you can only specify inparameters.

            2:This section describes how to invoke an operation asynchronously. In this context, asynchronously means you invoke an operation and then optionally get the results of the invoke in a later step.
            這種情況下雖然也是異步調用的,但這種調用方式客戶端需要返回值。需要返回結果,但客戶端又不樂意阻塞在服務器端請求處理上(可能服務器端處理該請求需要很長時間)。客戶端希望繼續執行它的其他業務邏輯,需要執行結果的時候,我在過來取這個結果。這樣可以提高客戶端的響應速度。

            這篇文章,我們主要看看2這種情況。

            2.1: web service開發
            開發web service不存在任何區別,但在build client jar的時候,需要在調用clientgen的時候加上generateAsyncMethods = true, 這樣clientgen生成的JAX-RPC stub中會多出兩個方法,如下:
            FutureResult startMethod (params, AsyncInfo asyncInfo);
            result endMethod (FutureResult futureResult);
    其中:Method對應于web service中的方法名,如sayHello---->startSayHello(params, AsyncInfo asyncInfo)。這兩個方法就是我們客戶端代碼中異步調用的時候需要的。

            2.2:客戶端代碼
            客戶端代碼有兩種寫法,一種是客戶端線程主動調用FutuerResult.isCompleted()來檢查web service請求是否執行完成,另一種方式是通過Listenter來處理服務器端的返回結果。

    //client thread checking

     1     public void runUnblock(){
     2         initializeEnv();
     3         try{
     4             System.out.println(port.getClass().getName());
     5             FutureResult result = port.startSayHello(3"test"null);
     6             //you other business logic here
     7             if(result.isCompleted())
     8             {
     9                 String ret = port.endSayHello(result);
    10                 System.out.println("result from remote HelloWorld web service: ");
    11                 System.out.println(ret);
    12             }
    13         }catch(Exception e){
    14             e.printStackTrace();
    15         }
    16     }
    17 
    18     public void initializeEnv(){
    19         try{
    20             helloService = new HelloWorld_Impl();
    21             port = helloService.getHelloWorldPort();
    22         }catch(Exception e){
    23             e.printStackTrace();
    24         }
    25     }


    //listener

     1 AsyncInfo asyncInfo = new AsyncInfo();
     2 asyncInfo.setResultListener( new ResultListener(){
     3     public void onCompletion( InvokeCompletedEvent event ){
     4         SimpleTestSoap source = (SimpleTestSoap)event.getSource();
     5         try{
     6             String result = source.endEchoString ( event.getFutureResult() );
     7         } catch ( RemoteException e ){
     8             e.printStackTrace ( System.out );
     9         }
    10     }
    11 });
    12 echoPort.startEchoString( "94501", asyncInfo );

     

            現在回頭看看開篇的問題,客戶端線程退出時,如果服務器端還沒有處理完,請求結果會怎么辦?是否會保存下來?如果這樣的客戶端很多,服務器內存開銷豈不是很大?

            要解釋這個問題,我們先來看看這種調用方式的流程。對于服務器而言,異步、同步調用是一樣的,它只負責接收、處理請求,web service的處理,在服務器端是由weblogic.webservice. server.servlet. WebServiceServlet .serverSideInvoke(WebService webservice, Binding binding, HttpServletRequest request, HttpServletResponse response)。同步、異步的處理完全是在客戶端完成的,下面就看看客戶端的調用流程。

    FutureResult result = port.startSayHello(3"test"null);
    //it's a JAX-RPC stub, and it extends StubImpl.java
    ====>
    weblogic.webservice.core.rpc.StubImpl._startAsyncInvoke( String method, Map args, AsyncInfo wsAsyncContext )
    //in this method, Operation is retrieved from Port
    ====>
    weblogic.webservice.core.DefaultOperation.asyncInvoke( Map outParams, Object[] args, AsyncInfo wsContext, PrintStream logStream )
    //a ClientDispatcher is created here and then we dispatch our requst with this dispatcher
    ====>
    weblogic.webservice.core.ClientDispatcher.asyncDispatch(final Object[] args, final AsyncInfo async)
    //in this method, FutureResultImpl is created and it will be returned to client. It's responsible to send message and
    //receive response from server in another. For receiving response, it's will be discussed later.
    ====>
    weblogic.webservice.core.ClientDispatcher.send(Object[] args)
    //MessageContext is set(for example, BindInfo is set) here and the request will be handle by a handler chain.
    ====>
    weblogic.webservice.core.handler.ClientHandler.handleRequest(MessageContext ctx)
    //it check bind info and the delegate the request to binding
    ====>
    weblogic.webservice.binding.http11.Http11ClientBinding.send(MessageContext ctx)
    //it retrieve endpoint from bindinfo and then open a HttpURLConnection with the URL created basing on endpoint.
    //Reqeust is sent to server with this HttpURLConnection.

    1 connection = (HttpURLConnection)url.openConnection();
    2 
    3 outputStream = connection.getOutputStream();
    4 request.writeTo( outputStream );


            請求發送完了,交給服務器去執行,下面我們再來看看客戶端是如何處理response的。weblogic.webservice. core.ClientDispatcher.asyncDispatch()中,請求發送結束后,weblogic將啟用一個新線程來接受服務器的response,如下:

    1       getThreadPool().addTask(new Runnable() {
    2         public void run() {
    3           callReceive(messageContext);
    4         }
    5       });

    注意:這個線程是在客戶端啟動的。該接收線程啟動后,FutureResultImpl實例會返回給客戶端,客戶端由此可以繼續他的業務邏輯,而不必block在等待response上。response由接收線程負責處理,收到response,處理后的結果會被植入FutureResultImpl,客戶端執行它的其他邏輯,需要處理處理該結果時,只需要檢查請求是否處理結束,如果結束,處理請求結果,如果請求依然沒有結束,則由客戶端決定繼續等待,還是放棄(主線程退出),如下:

    1 //you other business logic here
    2 if(result.isCompleted())
    3 {
    4     String ret = port.endSayHello(result);
    5     System.out.println(ret);
    6  }


            客戶端接受流程:

    weblogic.webservice.core.ClientDispatcher.asyncDispatch(final Object[] args, final AsyncInfo async)
    ====>
    weblogic.webservice.core.ClientDispatcher.callReceive(WLMessageContext ctx)
    //call receive() here, and if response was received, set it to FutureResultImpl that owned by the client and if Listener is configured, trigger the listner.

    1       if (listener != null) {
    2         InvokeCompletedEvent event = new InvokeCompletedEvent(
    3             async.getCaller());
    4 
    5         event.setFutureResult(futureResult);
    6         listener.onCompletion(event);
    7       }

    ====>
    weblogic.webservice.core.ClientDispatcher.receive(WLMessageContext ctx)
    //resoponse is handled by a handler chain
    ====>
    weblogic.webservice.core.handler.ClientHandler.handleResponse(MessageContext ctx)
    ====>
    weblogic.webservice.binding.http11.Http11ClientBinding.receive( MessageContext context )
    //read response from the input stream of connect that we send request with, and the thread will be blocked in
    //waiting data from server.


            好了,基本流程都列出來了。下面據此回答開篇的問題:

    1:如果客戶端不等待結果(比如服務器端因為某些原因,web service需要執行很長時間),直接退出的話,weblogic server是否保存調用結果,結果保存多長時間? 
         不會。如果客戶端退出前,請求已處理,保存在FutureResultImpl將會因為客戶端的退出而銷毀。如果沒有處理結束,服務器端回寫response的時候,雖然指向客戶端的連接已經因為客戶端退出而close了,但服務器端從該connection中拿到的output stream還在,服務器仍然會將response寫入到該output stream中(這是寫入的數據是沒有接收者的),response寫完后,weblogic會關閉output stream, 并close socket。

    2:如果這樣的異常客戶端很多,對服務器有什么負面影響,比如連接資源、內存開銷等。
            不會。如果客戶端退出前,請求已處理,則連接已經釋放。如果連接保持的時間略大于web service請求在服務器段的處理時間。請求處理結束后,服務器會在回寫完response后,主動斷開連接(可以看到客戶端至server端的連接為TIME_WAIT)。如果客戶端退出時,請求依然在服務器端上處理,客戶端的退出會導致連接的CLOSE。兩種情形都不會因為異常客戶端而導致連接浪費。至于內存開銷,服務器不會保存執行結果,請求處理結束后,直接回寫客戶端,所以也不會造成內存資源leak。

            對于那些web service執行時間較長,客戶端又希望其他業務并行的應用,這種異步調用是個不錯的選擇。

    posted on 2008-11-24 22:38 走走停停又三年 閱讀(2791) 評論(1)  編輯  收藏 所屬分類: Weblogic

    FeedBack:
    # re: 關于在weblogic中異步調用webservice
    2008-11-25 16:26 | @@@
    主站蜘蛛池模板: 日本亚洲成高清一区二区三区 | 亚洲影视一区二区| 亚洲成a人片7777| 香蕉免费一区二区三区| 国产黄色免费网站| 国产免费黄色大片| 亚洲欧洲日产国码无码网站 | 亚洲一区二区三区免费| 无码日韩精品一区二区三区免费 | 亚洲精品中文字幕无码蜜桃| 亚洲三级在线播放| 成人午夜影视全部免费看| 91青青国产在线观看免费| 四虎影视大全免费入口| 亚洲人成网亚洲欧洲无码久久| 黄色视频在线免费观看| 美女被免费视频网站a国产| 久久精品国产亚洲AV高清热| 立即播放免费毛片一级| ww4545四虎永久免费地址| 亚洲av无码乱码国产精品| 色天使色婷婷在线影院亚洲| 亚洲成年人免费网站| 亚洲大成色www永久网站| 2021国内精品久久久久精免费| 亚洲国产精品综合久久20| 免费观看久久精彩视频| 免费播放春色aⅴ视频| 亚洲另类无码专区首页| 84pao强力永久免费高清| 亚洲乱码日产精品BD在线观看| 日韩插啊免费视频在线观看| 国产精品亚洲αv天堂无码| 亚洲AV无码专区在线观看成人| 三年片在线观看免费观看高清电影| 亚洲福利视频一区| 久久精品国产这里是免费| 亚洲精品美女久久久久99| 国产精品爱啪在线线免费观看| 四虎影视久久久免费观看| 亚洲美女色在线欧洲美女|