2016-03-01 82 views
2

我一直在我的cfml應用程序中使用session作用域來執行諸如存儲當前登錄的user對象之類的操作。這很棒!如何管理羣集環境中的cfcs狀態

user.isLoggedIn()user.hasPremiumAccess()user.hasRole('admin')

在試圖我的應用程序遷移到集羣(雲)的環境中,我認識到,依靠session範圍小於理想的,因爲正在運行的應用程序的每個實例都有自己的服務器記憶。我知道我可以使用「粘性會話」,但我寧可不要,因爲這會限制Amazon Elastic Beanstalk等應用程序的實例(基於負載)自由旋轉。

我也知道我可以使用client範圍以集羣友好的方式存儲簡單值,但是複雜數據如我描述的用戶對象呢?你將如何存儲用戶對象,或者我可以使用什麼其他方法?

我可以根據需要進行應用程序更改。

**編輯**要清楚,不是我不能使用粘性會話,而是我不想使用粘性會話(或會話複製)。原因是我可以充分利用不依賴服務器/實例內存來管理會話狀態的全部可擴展性優勢。這種方法允許諸如Elastic Beanstalk之類的服務自由地創建和拆除應用程序服務器實例,而不會影響用戶。使用粘性會話不允許這樣做。

一些可能的解決方案,我已經考慮的因素包括:

  1. 序列化用戶對象用戶/反序列化「狀態」來存儲客戶範圍並在每個頁面加載
  2. 序列化/反序列化「重新初始化」用戶用戶對象用戶的「狀態」在的NoSQL數據庫存儲和在每個頁面加載「重新初始化」用戶
+0

如果你試圖在Elastic Beanstalk上使用ColdFusion,然後閱讀此錯誤信息 - [AWS Elastic Beanstalk拒絕ColdFusion WARs](https://bugbase.adobe.com/index.cfm?event=bug&id=3365388)以及相關文章 - http:// stackoverflow .com/q/12217424/1636917 –

+0

有趣。我試圖在生產環境中運行Docker容器(是的,在Elastic Beanstalk上),所以如果所有的承諾都是真的,只要docker守護進程在EC2實例上運行(它就是這樣),lucee應用就在Docker內部容器也應該運行。肯定通過一些障礙,但手指交叉。 –

+0

Lucee(Railo)沒有這個問題,它只涉及Adobe CF我認爲。 –

回答

4

如果你不/不能使用「粘性會話「,那麼另一種選擇是實現會話複製。這實際上將存儲在內存中的會話複製到集羣中的每個節點。而且,是的,這樣做有開銷。

從文檔:

要實現對服務器實例的會話故障轉移羣集中,使每個服務器實例的會話複製。會話複製實時協調集羣中的服務器實例之間的會話信息。如果當前服務器不可用,啓用會話複製可讓Tomcat自動將請求路由到正在運行的服務器。

注意:當羣集使用會話複製時,會話數據會在每次修改時被複制到羣集中的其他服務器。如果將大量信息存儲在會話範圍內,這可能會降低性能。如果您打算在會話範圍內存儲大量信息,請考慮將此信息存儲在保存在數據庫中的客戶端變量中。

從 - Enabling clustering for load balancing and failover

被進一步提到那一頁另一個警告:

如果使用會話複製,到內存變量頁面,使J2EE會話。爲羣集中的所有服務器實例啓用J2EE會話。如果ColdFusion Administrator中未啓用J2EE會話,則會話複製將無法正常運行.CFC序列化使您可以在羣集中使用J2EE會話複製,並可以訪問羣集中所有實例的會話數據中的CFC。會話複製還可確保跨範圍變量在集羣中進行復制。但是,會話複製不支持在會話範圍CFC或變量中複製陣列。在會話故障切換的情況下,您還可以保留和訪問CFC中的數據。存儲在會話範圍內的ColdFusion結構在會話範圍內可用,即使在故障轉移後也是如此。例如,如果您運行多個ColdFusion實例來平衡服務器負載,則可以在會話中存儲有用的數據(包括CFC),以便可以訪問該會話中提供的所有頁面上的數據。

而且還要檢查這個答案同樣的問題而回(請注意,有早期版本的ColdFusion 10並沒有讓會話複製到工作中的錯誤) - https://serverfault.com/a/602373/135433

+0

謝謝你的迴應Miguel!我寧願讓事情變得更簡單,而不是更復雜,所以假設我願意修改我的應用程序以使其變爲無狀態。在無狀態環境中存儲複雜對象的最佳方法是什麼?以某種方式序列化和反序列化cfc狀態並將其作爲json存儲在數據庫中?在每個請求中「重新填充」該用戶?還有別的嗎? –

+0

我通常只在我們的負載平衡環境中使用粘性會話(以保持簡單)。所以不知道我能對你的問題提供很多幫助。但我最初的想法是,如果你的應用程序是無狀態的,那你爲什麼需要在它們之間共享任何東西? –

+0

謝謝米格爾。我可能會在一段時間內使用粘滯會話,但在一天結束時,必須存儲的是會話數據,只是爲了使應用程序「無狀態」,它應該以不會存儲的方式存儲取決於運行它的服務器實例的服務器內存。這是我見過的客戶端經常使用的範圍......問題是客戶端無法存儲複雜的數據,而且沒有一些駭客。只是在尋找創意。 –