-- 本文出自sleest (感謝yangjj ^_^)
場景分析:
某天系統的數據庫維護方要求進行DG備庫容災演練,要把生產用RAC庫模擬宕機並轉移至DG備庫上,由於是failover而不是switchover演練,於是期間不對外開放apache訪問,要求服務啟動時間較緊.
數據庫的切換導致IP的變更,這樣導致ap上正在跑的系統不得不重新配置數據庫連接,基於目前的機制需要執行以下步驟:
a).停止服務群組
b).移除服務包
c).源服務包替換配置文件(這樣還要求服務包的當前版本備份完好)
d).重新上傳服務包
e).分發至群組,最后啟動群組
f).當源庫恢復正常時又得來一遍T T
這樣處理顯然比DG庫改IP花費更高,雖然DG要改相應監聽等操作,但據了解可以通過命令行即批處理減少每次的工作量.
於是引申如何在DB出現異常時服務快速恢復的問題
分析:
1.時間花費主要用在了重新部署服務包上,如何省略這個步驟,簡單想有兩個方案
a).重寫使用數據源初始化連接池的方案
b).使用容器托管數據源,服務包通過JNDI進行請求
其中a方案否決,一不通用,二重寫的話后面出問題又要重寫人負責= =
因此使用容器托管數據源的方案.
環境:
JBOSS EAP 6 domain集群
服務使用spring管理
數據庫oracle 11g
解決方案:
1.暫定使用ojdbc作為驅動,因此首先要有個ojdbc6.jar,傳說其他版本可能會有部分問題,如14不兼容jdk1.6,_gz不支持11g等
2.讓jboss加載該驅動:
建立如下圖所示的目錄結構:
其中module.xml的內容如下:
<?xml version="1.0" encoding="UTF-8"?> <module xmlns="urn:jboss:module:1.0" name="com.oracle"> <resources> <!-- Insert resources here --> <resource-root path="ojdbc6.jar"/> </resources> <dependencies> <module name="javax.api"/> <module name="javax.transaction.api"/> </dependencies> </module>
(扯淡:由於jboss6 使用了類maven的結構化管理,即不想4那樣jar基本都在一個lib目錄下,而是通過module的概念引入,並且module之間允許規定依賴和排除,也可以全局配置module引入和服務包中jar的優先級,當然最麻煩的是hibernate沖突,因為那是用石頭砸自己腳)
3.把這個目錄放到結點端 $JBOSS_HOME/modules下;
注意是所有的節點端,而不是放在控制端就完事,雖然具體的配置文件[domain.xml]是在控制端配的,要不在啟動服務時,注冊datasource就會失敗:
[org.jboss.as.controller.management-operation] (ServerService Thread Pool -- 59) JBAS014613: 操作("add") 失敗 -- 地址:([
("subsystem" => "datasources"),
("jdbc-driver" => "xxx.war")
4.啟動jboss控制端,並在其控制台進行相關配置:
[1].進入profiles選項
[2].選擇對應的配置文件,這里的profile和你對應群組指定的profile相對應,這里用的是domain下full-ha模式,目前沒有嘗試過full-ha工程的JNDI指向full配置的datasource,這也是為什么經常在改domain.xml的時候遇到很多相同的配置,實際是jboss划分了不同的配置域:
[3].Datasources選項卡
[4].add按鈕彈出新增頁面(這里奉勸先別刪默認的example配置- -)
5.配置數據源別名和JNDI
6.Detected Driver是只讀,給你看的
Specify Driver我在添加的時候報錯:
Internal Server Error
{
"outcome" => "failed",
"result" => undefined,
"failure-description" => "JBAS010839: 操作失敗或在所有服務器上回滾。",
"rolled-back" => true,
"server-groups" => {"main-server-group" => {"host" => {"slave1" => {"main-server33" => {"response" => {
"outcome" => "failed",
"result" => undefined,
"failure-description" => {"JBAS014771: 具有丟失/不可用依賴關系的服務" => ["jboss.driver-demander.java:jboss/datasources/oracleRacDS1 缺少 [jboss.jdbc-driver.xxxDs]"]},
"rolled-back" => true
}}}}}}
}
即這里似乎指定了jboss.jdbc-driver.的前綴,暫未了解何處指定;
7.配置數據庫鏈接:
8.完成后默認是disable狀態,具體的配置可以在其下的屬性框中進行相應調整,這里的xxx是driver的別名,在具體的xml中會指向一個具體的class
比較特殊的屬性在pool標簽中通過鍵值對配置
9.保存后可以在domain.xml中找到profile name="full-ha"下的<subsystem xmlns="urn:jboss:domain:datasources:1.1">標簽多了如下配置:
<datasource jta="true" jndi-name="java:jboss/datasources/oracleRacDS" pool-name="oracleRacDS" enabled="false" use-ccm="false" use-java-context="true"> <connection-url>[jdbc連接]</connection-url> <driver-class>com.oracle.jdbc.driver.OracleDriver</driver-class> <datasource-class>com.oracle</datasource-class> <driver>[別名A]</driver> <pool> <min-pool-size>10</min-pool-size> <max-pool-size>30</max-pool-size> </pool> <security> <user-name>[用戶名]</user-name> <password>[密碼]</password> </security> <validation> <validate-on-match>false</validate-on-match> <background-validation>false</background-validation> </validation> <timeout> <idle-timeout-minutes>60</idle-timeout-minutes> </timeout> <statement> <share-prepared-statements>false</share-prepared-statements> </statement> </datasource> <drivers> <driver name="[別名A]" module="com.oracle"> <xa-datasource-class>oracle.jdbc.xa.OracleXADataSource</xa-datasource-class> </driver> </drivers> </datasources>
其中仍需修改xa-datasource-class為如上紅色部分.
10.最后重啟控制端JBOSS再enable該數據源即可生效(服務端可以不用重啟).
11.服務包中的datasource配置改為JNDI調用即可:
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"> <value>java:jboss/datasources/oracleRacDS</value> </property> </bean>
12.重新部署服務包,啟動群組時,在節點段的日志中看到如下信息即說明注冊成功
[org.jboss.as.connector.subsystems.datasources] (MSC service thread 1-18) JBAS010400: 綁定數據源 [java:jboss/datasources/oracleRacDS]
實踐:
群組啟動完成后服務端可以從數據庫讀取數據.
這是修改正enable狀態的datasource會有如下錯誤:
說明無法修改.
此時如果將改datasource disable掉
服務端日志中將會出現如下異常:
javax.resource.ResourceException: IJ000451: The connection manager is shutdown: java:jboss/datasources/oracleRacDS
此時再enable也無法重連該連接;
結論:
通過使用JNDI指向jboss數據源的方式,可以將數據庫調整時服務段所做的調整降為如下步驟:
a).停止服務群組
b).移除服務包
c).源服務包替換配置文件(這樣還要求服務包的當前版本備份完好)
d).重新上傳服務包
e).分發至群組,最后啟動群組
f).當源庫恢復正常時又得來一遍T T
b).disable數據源
c).修改數據源配置保存並enable
d).啟動服務群組即可
e).源庫恢復后同上
但時間節省了,繁雜的替換文件步驟節省了,出錯率減小了.