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个
   我们能够毫不费力地配置应用,以做好生产准备。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐