2013-05-06 76 views
3

我們有一個webapp應用場景,作爲一個OSGi捆綁包。我們希望執行捆綁更新以將錯誤修正等透明地部署到正在運行的系統中。假設刷新和軟件包重新啓動的更新週期,當重新加載類的對象已存儲在導致ClassCastExceptionHttpSession上時,這會導致問題。如何處理有狀態的OSGi服務以跨包更新維護會話狀態?

我們正在尋找幾種不同的方法來使捆綁更新成爲可能,而不會在登錄的會話中丟失狀態。爲了簡化我們正在考慮設置以下限制會話狀態的訪問依賴關係圖:

  • 捆綁只能訪問自己的會話狀態,即由另一捆設置狀態不能直接訪問(力量,改爲調用包API以間接訪問其狀態)
  • 添加到會話狀態的對象的Java類應該來自包本身(以避免我們的會話狀態受其他包的更新影響,而不是我們自己) 這些限制實際上只是一些下面的替代方案。

所以,這些都是最大的寓意訂單,我們已經提出了替代方案在某種至少:

  1. 存儲所有狀態java.*類型(StringList等)
    - >狀態類永遠不會重新加載。
  2. 鎖定會話將其狀態與創建的服務版本(通過使用proxying solutions˚F前即着該屆會議之前使用的版本)
    - >新會話將搭載更新包的版本,而現有的會議將留在舊版本。
  3. 序列化更新捆綁包時的會話狀態並將其反序列化爲新捆綁版本(如應用服務器會話序列化,但粒度更細)
    - >所有會話都會提取更新的捆綁包,但要求序列化狀態是兼容的。
  4. 只要有活動的會話,避免更新有狀態的服務,利用傳統的負載平衡器技術一次更新一個應用服務器
    - >更長的部署週轉時間,可能需要更多的資源。
  5. 完全避免狀態OSGi服務,並保持狀態別處
    - >不處理在OSGi問題...

我錯過任何有趣的選擇?
你推薦什麼解決方案?

[雖然這篇文章明確地談到了同樣的討論也適用於其他領域,如通話狀態,應用程序狀態等會話狀態]

+0

如何將會話中存儲的實際對象保存在自己的包中?這不會避免類拋出異常嗎? – ilikeorangutans 2013-05-06 17:55:05

+0

是的,我正在考慮增加一個單獨的選擇,但我沒有,因爲我們仍然回到其他選擇,如果那些與「國家班」的捆綁更新。 – mikewse 2013-05-06 22:07:57

回答

3

在我看來,正確的答案是不是一個簡單的規則,而是一組規則如:

  • 如有必要,僅在應用程序的入口點使用有狀態對象。入口點可以是IO設備的Servlet,套接字監聽器,監聽器類(從外部向外發送請求並需要狀態的東西)...
  • 僅存儲會話中的對象,這些對象是通過來自java的類實例化的。*; (您的第一個選項)
  • 如果您認爲您需要存儲複雜的數據結構,請再考慮一下。您的動機是否更快地返回持續數據?
  • 儘可能在會話中存儲更少的信息(沒有實體對象,但只有它們的ID)
  • 在服務包中使用緩存來加快響應時間。我建議使用支持集羣和XA事務的鍵值對緩存實現。這兩個要求稍後可能很重要。在鍵中只使用java。*類。如果讀取的密集數據使用率(在Web應用程序中佔很大比例)使用失效緩存。

更多的緩存和持久性數據的關係:

  • 把你的持久性數據邏輯集合,其中一組具有相同的生命週期。
  • 只能從一個包中修改和緩存一個邏輯數據集。如果你沒有這個規則,如果有人改變了一個包的代碼(這會影響另一個包中的一個緩存),緩存可能會被破壞。

這就是我們如何在我的公司設計Web應用程序的方式,它似乎是一種好方法。但是,可以有其他方法。