John: 現在測試環境8月16號的發布分支用的是哪個MQ?(看來這家伙被指派了一個缺陷修復 )Jane: 我看看……(一小會之后),是tcp://192.168.1.13:61617過了一會……
Andy:現在測試環境8月28號的發布分支用的是哪個MQ?Jane: 我看看……(一小會之后),是tcp://192.168.1.14:61617事實上,有時不同的開發人員會向配置管理員詢問同一個發布分支的broker地址。由于它們不容易與對應的環境聯系起來而且多少還是需要占用一些硬件資源的,于是我們決定裁剪ActiveMQ實例。
首先改造的是集成測試。我們原來為流水線的commit階段準備了一臺Server mode的ActiveMQ,但其實在集成測試中,我們更關心的是集成的代碼和相關的配置。這時可以使用embedded mode的ActiveMQ替代,這樣它們就變為了環境不敏感了,而且由于不需要持久化,每次集成測試都可以運行在一個“干凈”的環境中。
runtime.properties:
runtime.messaging.broker.url=vm://localhost:61616?broker.persistent=false
不過embedded mode不能解決所有問題,當流水線晉級到自動部署后的自動化驗收測試或手工驗收測試時,還是server mode的ActiveMQ在排查問題時更方便。我們發現,應用程序并不是對整個消息中間件依賴,而是對消息中間件中的某個隊列依賴,而不同的隊列之間是不需要相互通信的,所以其實我們只需要一臺server mode的ActiveMQ,讓不同的環境依賴于不同的隊列就可以了。這就要求不同環境使用不同的隊列名字,但是隊列的名字一般是通過代碼中硬編碼 /properties文件配置或是通過JNDI查找的,我們也不想因此增加配置負擔。因此使用了使用環境名+固定隊列名的隊列名字拼接辦法,比如:
notificationReceivedQueue --> commit.notificationReceivedQueue --> uat.notificationReceivedQueue --> pre.notificationReceivedQueue --> pro.notificationReceivedQueue
于是我們引入了一個Configurations類,它有點類似于一個Facade,提供易用的接口:
public class Configurations {
private String jmsEnvironment = "commit";
public String getNotificationReceivedQueueName() {
return jmsEnvrironmentSpecified("notificationReceivedQueue");
}
private String jmsEnvrironmentSpecified(String destinationName) {
return jmsEnvironment + "." + destinationName;
}
}
而配置中,可以使用spring el來注入隊列名稱
xml
queue-name="#{configurations.getNotificationReceivedQueueName() }"
這樣,開發人員可以只訪問一個broker,而通過隊列名稱來查找他的目標,uat0816.notificationReceivedQueue的可讀性可要好多了。
實踐持續交付是一個長期的漸進式的過程,往往會遇到各種個性化的問題。有的組織硬件資源不足,有的組織硬件資源充足,但還不能做到自動化環境管理。于是許多準備嘗試部署流水線的團隊會在流水線環境準備上遇到困難,希望這個故事能對這樣的團隊有幫助。有時候,外部環境或自身資源的限制也不完全是件壞事,這使我們停下細細思考,到底流水線的方案還有哪些可以改進的余地,辦法總比困難多。
[1] 《持續交付——發布可靠軟件的系統方法》by Jez Humble & David Farley
[2] 雖然hsqldb提供了與oracle不錯的兼容性,但團隊需要留意一些細節上的差別。
[3] 即不修改數據庫,只增加新的數據庫對象或是在現有對象上新增字段等,一般情況下應用程序比較容易做到對此的兼容性
[4] 據我所知創建一個新的用戶所消耗的硬件資源很少,主要是其本身數據的存儲空間,如果團隊對測試數據進行管理的話,這個測試數據集應該不會太大。
[5] 輕易的使用數據庫集成很容易抵消你所做的解耦努力。各個模塊和子系統表面上看來還不錯,但當數據結構改動時牽一發而動全身。
原文轉自:http://www.kuqin.com/shuoit/20131215/336973.html