2013年7月3日 星期三

謹慎使用 Stateful Web Services!

今天同事遇到了一個 Stateful Web Services 把 LDAP Server Connection 吃光光的案例。

一般我們很常使用 Stateless 的 Web Services ,Client 端對 Service 的一次呼叫,Session 就結束了。但其實 Web Services 也可以是 Stateful。例如 WebLogic官網舉的購物車的例子,對購物車 addItem,在 Server 端將 item 存到了 session 中。

今天遇到問題的這個系統是這樣的,它提供了一些對 LDAP 查詢的 Web Services,包裝了 high level API,一些 method 如下:


 
    //Client指定為 Stateful
    call.setProperty(Call.SESSION_MAINTAIN_PROPERTY, Boolean.TRUE);

    //Client端要用時,要先登入。
    call.setOperationName("connect");   
    call.invoke($account, $passwd);
 
    call.setOperationName("queryUserByDepartment");
    call.invoke($department);

    call.setOperationName("queryUserById");
    call.invoke($uid);

    ... 其他一大堆 method ...

    //Client 不用時,必須 Close
    call.setOperationName("close");
    call.invoke();


看到了嗎? Client應用程式,真的會乖乖 close 嗎?
一旦Client 沒下 close,Session 裡便殘留了一堆 LDAP Connection。
最終把 LDAP Server 資源耗盡。

Session 裡存了 Connection ,沒有其他資料會在呼叫 WS 時加進 Session。
這樣的應用不適合以 Stateful 方式 implement,如果有用 connection pool 也就罷了,
再加上沒用 Connection Pool,Server的死活,全看 Client 開發人員有沒有良心小心了


沒有留言: