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