1、服務器集群
服務器集群就是指將很多服務器集中起來一起進行同一種服務,在客戶端看來就像是只有一個服務器集群可以利用多個計算機進行并行計算從而獲得很高的計算速度,也可以用多個計算機做備份,從而使得任何一個機器壞了整個系統還是能正常運行。
使用集群服務器構建的集群系統優點在于:
(1)統集群系統可解決所有的服務器硬件故障,當某一臺服務器出現任何故障,如:硬盤、內存、CPU、主板、I/O板以及電源故障,運行在這臺服務器上的應用就會切換到其它的服務器上。
(2)集群系統可解決軟件系統問題,我們知道,在計算機系統中,用戶所使用的是應用程序和數據,而應用系統運行在操作系統之上,操作系統又運行在服務器上。這樣,只要應用系統、操作系統、服務器三者中的任何一個出現故障,系統實際上就停止了向客戶端提供服務,比如我們常見的軟件死機,就是這種情況之一,盡管服務器硬件完好,但服務器仍舊不能向客戶端提供服務。而集群的最大優勢在于對故障服務器的監控是基于應用的,也就是說,只要服務器的應用停止運行,其它的相關服務器就會接管這個應用,而不必理會應用停止運行的原因是什么。
(3)集群系統可以解決人為失誤造成的應用系統停止工作的情況,例如:當管理員對某臺服務器操作不當導致該服務器停機,因此運行在這臺服務器上的應用系統也就停止了運行。由于集群是對應用進行監控,因此其它的相關服務器就會接管這個應用,提高了應用系統的穩定性。
2、常見問題
應用系統升級到集群服務器環境下,碰到的主要問題是Hibernate代理的主鍵在插入時,主鍵重復異常信息明顯增多。通過對應用系統源代碼進行分析,發現出現的問題主要為以下兩方面。
2.1 Hibernate的Generator配置為increment
increment方式為Hibernate提供的一種內置的常用的主鍵生成器策略,此方式的實現機制為在當前應用實例中維持一個變量,以保存著當前的最大值,之后每次需要生成主鍵的時候將此值加1作為主鍵。這種方式可能產生的問題是:如果當前有多個實例訪問同一個數據庫,那么由于各個實例各自維護主鍵狀態,不同實例可能生成同樣的主鍵,從而造成主鍵重復異常。因此,如果同一數據庫有多個實例訪問,此方式必須避免使用。
目前我們的應用系統環境為最簡單的集群方式:兩臺was,一臺數據庫的方式。所以當有并發情況訪問系統且兩個請求又被分發給兩臺was時,假設當前數據庫id最大為40,兩臺was分別會產生兩條id為41的數據導致插入失敗(Duplicate entry主鍵重復)。
Increment主鍵生成器的org.hibernate.id.IncrementGenerator類里面,是使用select max(columnName)from tableName的方式來獲取。原來的程序一直運行很好,但是在用兩個was來負載均衡后卻出現問題。為什么?IncrementGenerator類里面的generate()方法雖然被聲明成了synchronized,但現在兩個Tomcat分別運行在兩臺服務器的兩個獨立的Java虛擬機里,顯然問題在這里,synchronized只能在一個獨立的Java虛擬機內部有效。所以,在兩個Tomcat中用select max同時取主鍵,就相當于在沒有synchronized的保護下,并發時就會取出相同的值,再insert就會發生dumplicate entry的錯誤。
2.2 Hibernate的cache配置策略問題
Hibernate的cache是他提高效率的主要原因,比如我lOAd,save的各種數據都會在緩存起來,用id標識,當我下次再次查詢的時候,它會把id的集合都查出來,然后在緩存中遍歷,如果都遍歷到了,將不再訪問數據庫。顯然這在集群環境下,也是小概率事件,但是這不影響數據正確完整,真正影響數據的是read-write cache。
Hibernate的緩存分為一級緩存和二級緩存,二級緩存需要特殊配置,通常情況下不用,一級緩存就包括上一個段落說的情況,分為read-only cache和read-write cache。Read-only cache只讀的緩存會導致性能上的波動,卻不影響數據,在上一段落已經舉例說明。Read-write cache讀寫緩存則會影響數據邏輯,比如我在緩存里放入一個值名對叫flag=1來標識我已經具有操作權限,放入was1了但是下次請求可能發到was2上去了,結果我找不到這個值,導致我認為自己沒權限,或者我想修改他卻找不到它的值了。
3、解決方案
3.1針對自增字段問題
Hibernate的主鍵生成雖然支持很多種數據庫獨有的increment方式,還有他自己的select max實現的increment方式,其實這些都不是很好,假如將來真的要切換數據庫,并且是在集群下運行程序,某種數據庫獨有的increment和select max方式的increment都會帶來問題。
Hibernate中唯一一種最簡單通用的主鍵生成器就是uuid-hex。雖然是個32位難讀的長字符串,但是它沒有跨數據庫的問題,將來切換數據庫極其簡單方便,推薦使用。有不少項目使用identity,就是引用數據庫自有的序列機制,雖然保證了唯一,但是數據庫遷移的時候需要做初始值重置的工作,也不很看好。
3.2針對緩存問題
在配置時,
4、結語
Hibernate框架為0R轉換帶來了方便,在單獨服務器環境下只有單實例訪問數據庫,因此不存在并發不一致問題;在集群環境下,多實例訪問數據庫,因此應注意并發一致性問題。
核心關注:拓步ERP系統平臺是覆蓋了眾多的業務領域、行業應用,蘊涵了豐富的ERP管理思想,集成了ERP軟件業務管理理念,功能涉及供應鏈、成本、制造、CRM、HR等眾多業務領域的管理,全面涵蓋了企業關注ERP管理系統的核心領域,是眾多中小企業信息化建設首選的ERP管理軟件信賴品牌。
轉載請注明出處:拓步ERP資訊網http://www.guhuozai8.cn/
本文標題:服務器集群環境下Hibernate使用問題和解決方案
本文網址:http://www.guhuozai8.cn/html/consultation/1083934687.html