2010-09-02 98 views
0

在SaaS應用程序的情況下,同一臺服務器將主機播放到多個應用程序。會話屬性如何維護?爲了詳細說明問題: AppA和AppB託管在同一臺機器上,現在我爲AppA創建用戶AppA和UserB。 AppA和AppB屬於不同的組織,因此它們沒有鏈接。關於用戶的一些細節存儲在http會話級別(直到會話超時)。所以,現在如果我使用不同的選項卡從同一瀏覽器登錄到AppA和AppB,我最終可能會在UserB/AppB屏幕上看到一些UserA/AppA詳細信息,反之亦然。如何解決這個問題? 我能想到的一個解決方案是創建像appa.example.org和appb.example.org這樣的子域。有沒有其他更好的方法?如何在多租戶架構中維護會話屬性?

+0

如果這些應用程序屬於不同的組織,是否會有真實的場景可以從*相同的瀏覽器訪問它們* – JoseK 2010-09-02 11:04:32

+0

@JoseK是的,會有。這些應用程序確實屬於不同的組織,但它們可以通過互聯網訪問,而不僅限於組織的內部網絡。如果用戶註冊了兩個組織,他們可能會同時打開它們。 – saugata 2010-09-02 12:14:38

回答

1

通常情況下,您不會在另一個應用程序中看到來自一個應用程序的詳細信息。

創建會話時,會在Web應用程序內部創建並通過密鑰進行標識。此會話標識是存儲在cookie中或以其他方式傳遞的標識,以標識在下一個請求中引用哪個會話對象。

如果您將此會話ID顯示給另一個Web應用程序,它將不會找到屬性,因爲它們位於另一個Web應用程序中。

現在,這是'正常'。實際上,這可以在所有方向上進行配置,例如將所有屬性存儲在cookie中(在極端故障轉移場景中非常有用),將會話存儲在共享memcached層或共享數據庫表中(然後您將在另一個對象中獲得相同的對象當然應用)等等。

+0

也許我不清楚,這兩個「應用程序」在同一個網絡應用程序,他們提供相同的功能,但爲不同的組織。由於瀏覽器找到現有域的cookie,它總是發送相同的cookie,包括打開兩個不同的選項卡時。 – saugata 2010-09-02 09:47:49

+0

我認爲這個問題的答案解釋了這一點:http://stackoverflow.com/questions/595872/under-what-c​​onditions-is-a-jsessionid-created – 2010-09-02 12:12:40

1

我想出的最佳解決方案受this question的啓發。我指着多個上下文到同一個WAR文件:

<Service ...> 
    <Engine ...> 
     <Host ... autoDeploy="false"> 
      <Context docBase="myapp.war" path="/tenant1"/> 
      <Context docBase="myapp.war" path="/tenant2"/> 
     </Host> 
    </Engine> 
</Service> 

這是基本相同,使得myapp.war稱爲tenant1.war,tenant2.war等每個租戶的拷貝技術上運行thier自己的web應用程序即使它們都運行相同的代碼。 如果您的用戶擁有兩個或更多租戶的憑據,他們可以同時登錄到兩者,並且每個webapp都將獲得自己的會話,因爲包含會話ID的JSESSIONID cookie每個都綁定到特定的上下文路徑。

這種方法存在缺陷。首先,戰爭檔案中的所有班級都會爲每個租戶重新加載,因此我必須密切關注PermGen空間。另一方面,每當新的租戶出現時,我都必須編輯server.xml。你有沒有找到更好的解決方案?

+0

我添加了一個間接的級別。我所有的(Spring)控制器都擴展了一個BaseController,它公開了一個像Context getContext(租戶)這樣的方法{如果租戶在會話中有一個上下文,檢查上次訪問時間在租戶會話超時內,否則清理舊的上下文(如果有)新的上下文,更新訪問時間,將會話服務器會話超時更新爲會話中所有租戶的最大值並返回}。上下文只是一個字符串,對象的映射。所有其他servlet/controllers/jsps讀取/寫入上下文而不是會話。 – saugata 2012-06-11 07:24:46

+0

租戶名稱本身源自請求的URL。網址類似於http://host/warname/tenantname/resource.htm – saugata 2012-06-11 07:31:30