1. 程式人生 > >Node.js微服務 2 :基於Seneca和PM2構建Node.js微服務

Node.js微服務 2 :基於Seneca和PM2構建Node.js微服務

2.1 選擇Node.js的理由

    如今,Node.js已經成為國際上許多科技公司的首選方案。特別的,對於在伺服器端需要非阻塞特性(例如Web Sockets)的場景,Node.js儼然成了最好的選擇。

    安裝Node.js, npm, Seneca和PM2

    Node.js的執行緒模型

    SOLID設計原則:模組化歸結於以下設計原則,單一職責原則、開放封閉原則、里氏替換原則、介面分離原則、依賴倒置原則。

    在Node.js中,每個JavaScript檔案預設是一個模組。當然,也可以使用資料夾的形式組織模組。

    在Node.js中使用全域性變數是個讓人頭痛的事前。使用全域性變數會將各個模組耦合在一起,但是過度耦合是我們無論如何都要避免的。

function init(options) {
	function charToNumber(char) {
		return char.charCodeAt(0) - 96;
	}
	function StringManipulation() {

	}
}
module.exports = init;

2.2 微服務框架Seneca

    Seneca是一個用於構建微服務的框架。它使用完備的模式匹配介面來連線各個服務,從程式碼中將資料傳輸抽象出來,使編寫具有高可擴充套件性的軟體變得相當容易。

var seneca = require('seneca')()

seneca.add({role:'math', cmd:'sum'}, function (msg, respond) {
	var sum = msg.left + msg.right;
	respond(null, {answer: sum});
})
seneca.add({role:'math', cmd:'product'}, function (msg, respond) {
	var product = msg.left * msg.right;
	respond(null, {answer: product});
})
seneca.act({role:'math', cmd:'sum', left:1, right:2}, 
	function(err, data) {
	if (err) {
		return console.error(err);
	}
	console.log(data);
});
seneca.act({role:'math', cmd:'product', left:3, right:4}, console.log);
    實現控制反轉:一種軟體思想,它能代理建立或呼叫各元件及方法,使得模組本身不用關注建立它們所需要的依賴,這些通常是通過依賴注入完成的。

    Seneca的模式匹配: 統計單詞數的例子

var seneca = require('seneca')()

seneca.add({cmd:'wordcount'}, function (msg, respond) {
	var length = msg.phrase.split(' ').length;
	respond(null, {words: length});
})
seneca.add({cmd:'wordcount', skipShort: true}, function (msg, respond) {
	var words = msg.phrase.split(' ');
	var validWords = 0;
	for (var i=0; i<words.length; i++) {
		if (words[i].length > 3) {
			validWords++;
		}
	}
	respond(null, {words: validWords});
})
//處理器1
seneca.act({cmd:'wordcount', phrase: 'Hello world this is Seneca'}, 
	function(err, response) {
	console.log(response);
});
//處理器2
seneca.act({cmd:'wordcount', skipShort: true, phrase: 'Hello world this is Seneca'}, 
	function(err, response) {
	console.log(response);
});
    模式匹配庫Patrun:Seneca使用它來執行模式匹配,獲取最長匹配項和模式中元素的順序
{ x:1,     } -> A
{ x:1, y:1 } -> B
{ x:1, y:2 } -> C
    複用模式
    編寫外掛:通用的功能可以被模組化並抽象成可複用的元件。
function minimal_plugin( options ) {
	console.log(options);
}
require( 'seneca' )()
  .use( minimal_plugin, {foo: 'bar'})
    整合Web伺服器:Seneca預設通過TCP傳輸層進行資訊互動。

    討論一個更普遍的用例:服務的呼叫方是瀏覽器中的JavaScript。雖然通過普通JSON會話就能滿足需求,但是如果Seneca提供REST API來代替它會更簡單。這對於微服務之間的通訊來說是完美的選擇,除非你要求極低的延遲。

    Seneca並不是一個Web框架。它被定義為一個通用的微服務框架,因此它並不會對具體的某個應用場景做過多的支援。取而代之的是,Seneca能夠非常輕易地與其他框架進行整合。

    Express是基於Node.js構建Web應用的首選。

    將Seneca作為Express的中介軟體:Express也是基於API聚合原則構建的。在Express中,每個軟體模組都被稱為中介軟體,它們在程式碼中以鏈式結構串聯,以此來處理每個請求。

var seneca = require('seneca')();
seneca.add('role:api, cmd:bazinga', function(args, done) {
	done(null, {bar:"Bazinga!"});
});
seneca.act('role:web', {use:{
	prefix: '/my-api',
	pin: {role:'api', cmd:'*'},
	map: {
		bazinga: {GET: true}
	}
}});
var express = require('express');
var app = express();
app.use( seneca.export('web') );
app.listen(3000);
    資料儲存:Seneca具有資料抽象層,允許我們使用通用的方式操作應用的資料。預設載入in-memory儲存外掛。

    PM2

2.3 PM2---Node.js的任務執行器

    PM2是一款可以為伺服器例項帶來負載均衡功能的生產級別的程序管理器,通過PM2可以自由伸縮Node.js應用。此外,它能確保程序持續執行,解決Node.js單執行緒模型帶來的副作用:一個沒有被捕獲的異常通過殺死執行緒,進而殺死整個應用。
    單執行緒應用及異常:單執行緒模式意味著,如果丟擲的異常沒有被處理的話,應用程式將會掛掉。     這個問題可以通過使用promise庫(例如bluebird)解決;通過promise方式,應用不僅可以處理成功的返回,還能夠處理異常,因此它可以防止異常“冒泡”導致應用崩潰。     然而,還是存在一些在我們控制範圍之外的情況,稱之為不可恢復的錯誤。一旦出現,最終將導致你的應用程式崩潰。在Java中不是大問題,但Node.js中卻是一個大問題。但是,通過任務執行器,例如forever來解決這個問題。     forever與PM2都是任務執行器,當應用意外退出時,它們可以重啟應用,從而能保證其正常執行。     相當有用的工具包nodemon:當它探測到監控的檔案發生變化時,它將過載應用。     PM2---業界標準的任務執行器     PM2比forever更勝一籌。可以管理應用的整個生命週期,並且實現沒有停機時間,也具備負載均衡的功能。 hello.js
var http = require('http');
var server = http.createServer(function(request, response) {
	console.log('called');
	response.writeHead(200, {"Content-Type": "text/plain"});
	response.end("Hello World\n");
});
server.listen(8000);
console.log("Server running at http://127.0.0.1:8000/");
   $ pm2 start hello.js
   $ pm2 show 0   #得到id為0的應用的相關資訊    $ pm2 monit     #監控    $ pm2 logs       #檢視輸出日誌    只需要很少的命令,就能夠覆蓋90%的監控需求    $ pm2 reload all    #輕易地無縫重啟應用    $ pm2 stop all    $ pm2 delete all    $ pm2 start hello.js -i 3    PM2將啟動一個控制程序和指定個數的工作程序。因此,單執行緒模型的Node.js也能享受到多核CPU帶來的效能提升。    $ pm2 scale hello 2    # 工作程序有3個減少為2個    我們能夠毫不費力地配置應用,以做好生產準備。