Node.js自動導航模式在docker的應用
自動導航模式使得當程序被部署的時候自能夠自動根據配置構建應用程序變得非常簡單(容易在開發和測試的時候獲得一個拷貝),當應用程序更新或者由于故障需要擴展或者縮減的時候。接下來我們將通過兩個Node.js模塊如何使用自動導航模式更容易地構建app。
這兩個模塊分別是 consulite 和 piloted ,使用 npm 安裝和如何為自動導航模式程序提供常用功能,其中包含使用Consul進行交互以及因為拓撲結構變更而重新加載配置文件的內容。這些雖然不是自動導航模式所必需,但是提供了更加便捷的方式。
讓我們看看這兩個模塊是如何工作的。
為Node.js提供容器導航
在我們演示這些模塊如何使用之前,讓我們先快速瀏覽下 容器導航 是如何與在Docker容器中運行的Node.js應用程序進行整合的。下面的圖片說明了通常情況下一個應用程序的生命周期在 容器導航 中配置的要點。
如圖所示,容器導航配置通常會發送一個 SIGHUP 信號給Node.js應用程序。一旦發送完畢,不論這個應用程序是否依賴后臺的變更。當 容器導航 通知這些后臺依賴變更的時候,他不會發送應用程序的后臺主機名以及端口信息。這個任務留著給應用開發人員決定如何去實現它。下圖演示一個類似 Consul 的典型數據流,從應用程序到 容器導航 再到服務注冊的過程。
上面的模塊是設計被用來解決上圖所示的經常遇到的問題 ,比如處理后臺地址由于 onChange 事件而需要重新加載的情況。當后臺服務變更的時候 onChange 事件觸發。這有可能是因為某個后臺服務突然不健康或者新的后臺地址通過Consul注冊而造成的。無論是哪種方式,容器導航都會執行已經配置好的命令通知Node.js應用。
保存一份應用依賴的健康的后臺地址清單對[自動導航模式]( https://www.joyent.com/blog/category:Autopilot Pattern)而言影響重大。其中一個原因是最初的設計就是為了能夠提前了解應用的健康情況,為了確保請求不會被發送到那些不健康的后臺服務。這也意味著負載均衡器對部署一個應用及后臺服務而言不再那么重要了。
Consulite
另一個對于 容器導航 目標而言,[自動導航模式]( https://www.joyent.com/blog/category:Autopilot Pattern)顯著的收益是我們不需要注冊你的應用到服務發現上了。服務導航為你管理這些常用任務,當出現中斷或者任何應用依賴的服務發生變更的時候它會第一時間通知應用這一消息。
你無需再為服務注冊和從注冊訂閱的消息擔心,你需要知道的只是如何與注冊者通信并定位應用依賴的主機及端口信息。 Consulite 有助于使得獲取這些應用依賴的服務信息變得便捷。正如Consul的名字一樣,它實現了如何與 consulite 進行通訊的注冊實現。
實現注冊路由
讓我們通過一個實例來演示consulite是如何使得這一切變得便捷和有意義的。這個例子源自 Autopilot workshop ,一個標準的 銷售者 服務。
const Consulite = require('consulite');
const Wreck = require('wreck');
Consulite.getService('customers', (err, host) => {
if (err) {
return console.error(err);
}
Wreck.get(`http://${host.address}:${host.port}/data`, (err, res, customers) => {
// Handle error or respond with relevant customer data
});
});
在上面的例子中,沒有任何消費者服務被緩存,那么Consul將使得一個請求獲取到所有健康的服務地址列表。通常情況,會為一個特定服務提供多功能后臺地址列表。為了建立這個服務, consulite 將會循環遍歷這個地址列表。循環的邏輯從當前地址列表的第一個還沒有被使用的地址直到最后一個地址完全被使用。這些在一個模塊中實現功能的結果有助于減少使用Consul保持與這個地址列表通訊的資源消耗。
管理注冊變更
Consulite 使得保持與緩存后的健康服務列表通訊變得異常容易,當服務器更新的時候也同時更新了這個服務列表。之前的例子中,已經演示了容器導航是如何當一個后臺服務變更的時候通過向配置好的Node.js應用發送一個 SIGHUP 信號通知。下面的實例演示了在 容器導航 中如何使用 consulite 管理可配置的 onChange 行為來統一管理這些信號,目的是刷新這些本地服務緩存。
process.on('SIGHUP', () => {
Consulite.refreshService('customers', (err) => {
if (err) {
console.error(err);
}
});
});
就算是一個應用開發人員都可以通過 consulite 很容器的調試 容器導航 ,他們的職責僅僅只需計算一直保持通信的初始化服務列表來管理進程事件而以。為了解決這個問題我們創建了 piloted 項目.
Piloted 項目
為了代替應用程序開發人員去實現管理 SIGNUP 事件以及初始化服務地址列表加載,我們決定用 piloted 模塊來處理這些工作。所有應用依賴的后臺和服務們都已經配置在了 containerpilot.json 的配置文件中。因此應用開發人員可以通過 piloted 來替換這些配置信息,且它會自動加載,并為應用保存一份健康的后臺地址信息列表。下面的例子演示了如何發送已經 piloted 的配置文件信息并取回 customers 服務的后臺服務地址列表。
Usage
const Piloted = require('piloted');
const Wreck = require('wreck');
const ContainerPilot = require('/etc/containerpilot.json');
Piloted.config(ContainerPilot, () => {
const host = Piloted('customers');
Wreck.get(`http://${host.address}:${host.port}/data`, (err, res, customers) => {
// Handle error or respond with relevant customer data
});
});
上面的例子中 容器導航 的配置文件被加載到 piloted 中.在這之后, piloted 將會維護一份本地的應用依賴健康服務器列表。在這個事件中,一旦這些服務中有變更發生, piloted 將會通過Consul更新這個列表信息到最新版本。
來自:http://dockone.io/article/1694