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设计原则:模块化归结于以下设计原则,单一职责原则、开放封闭原则、
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的任务执行器
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的应用的相关信息
更多推荐
所有评论(0)