一个用于构建微服务的框架,它使用完备的模式匹配接口来连接各个服务,从代码中将数据传输抽象出来,使得编写具有高可扩展性的软件变得x相当容易。
核心功能
实例
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});
});
var respond = function(err,result){
if(err) {
console.error(err);
}else{
console.log(result);
}
};
seneca.act({role:'math',cmd:'sum',left:1,right:2},respond);
seneca.act({role:'math',cmd:'product',left:3,right:4},respond);
控制反转
可以把seneca.add看作生产者,seneca.act看着消费者
模式匹配
var seneca = require('seneca')();
var age = require('../js/mod');
seneca.add({cmd:'age'},function(msg,respond){
var birthdate = new Date(msg.birthdate);
var a = age.getAge(birthdate);
respond(null,{age:a});
});
seneca.act({cmd:'age',birthdate:'2000-10-10'},function(err,res){
if(err){
console.error(err);
}
console.log(res);
});
服务发布
module.exports = function math(options) {
this.add('role:urp,cmd:grade', function sum(msg, respond){
var res = {
bh:msg.bh,
courseId:123,
grade:99
};
console.log(res);
respond(null,res );
});
this.wrap('role:urp', function (msg, respond) {
this.prior(msg, respond)
});
};
require('seneca')()
.use('urp')
.listen(7002,'127.0.0.1');
PM2是一款可以为服务器实例带来负载均衡功能的生产级别的进程管理器,通过PM2可以自由伸缩Node.jsy应用。此外,它还能确保进程持续进行,解决Node.js单线程模型带来的副作用:一个没有被捕获的异常通过杀死线程,进而杀死整个应用。
其实PM2就是一个任务执行器,当应用出现异常意外退出时,可以重启来确保能正常运行,与之类似的还有forever。
主要特性
主要命令
stu.js
module.exports = function math(options) {
this.add('role:stu,cmd:skipClassList', function sum(msg, respond) {
var bh = msg.bh;
respond(null,
[{"bh":bh,"courseId":"123","time":1451577600000},
{"bh":bh,"courseId":"123","time":1454342400000},
{"bh":bh,"courseId":"123","time":1456934400000},
{"bh":bh,"courseId":"123","time":1459699200000},
{"bh":bh,"courseId":"123","time":1462377600000}]);
});
this.add('role:stu,cmd:stuInfo', function sum(msg, respond) {
var bh = msg.bh;
var res = {
"bh":bh,
"name":"小明",
"sex":"男",
"age":"24"
}
console.log(res);
respond(null, res);
});
this.wrap('role:stu', function (msg, respond) {
this.prior(msg, respond)
})
};
stu-server.js
require('seneca')()
.use('stu')
.listen(7001,'127.0.0.1');
urp.js
module.exports = function math(options) {
this.add('role:urp,cmd:grade', function sum(msg, respond){
var res = {
bh:msg.bh,
courseId:123,
grade:99
};
console.log(res);
respond(null,res );
});
this.wrap('role:urp', function (msg, respond) {
this.prior(msg, respond)
});
};
urp-server.js
require('seneca')()
.use('urp')
.listen(7002,'127.0.0.1');
api.js
var senceaStu = require('seneca')().client({
host : "127.0.0.1",
port : 7001
});
var senceaUrp = require('seneca')().client({
host : "127.0.0.1",
port : 7002
});
module.exports = function api(options) {
this.add('role:api,path:stu', function (msg, respond) {
var operation = msg.args.params.operation;
var param = msg;
param.cmd = operation;
//console.log(param)
senceaStu.act('role:stu', param, respond)
});
this.add('role:api,path:urp', function (msg, respond) {
//var operation = msg.args.params.operation;
var operation = msg.args.params.operation;
var param = msg;
param.cmd = operation;
//console.log(param)
senceaUrp.act('role:urp', param, respond)
});
this.add('init:api', function (msg, respond) {
this.act('role:web',{routes:{
prefix: '/api',
pin: 'role:api,path:*',
map: {
stu: { GET:true, suffix:'/{operation}' },
urp: { GET:true, suffix:'/{operation}' }
}
}}, respond)
})
}
index.js
const Hapi = require('hapi');
const Seneca = require('seneca');
const SenecaWeb = require('seneca-web');
const config = {
adapter: require('seneca-web-adapter-hapi'),
context: (() => {
const server = new Hapi.Server();
server.connection({
port: 8888
});
server.route({
path: '/routes',
method: 'get',
handler: (request, reply) => {
const routes = server.table()[0].table.map(route => {
return {
path: route.path,
method: route.method.toUpperCase(),
description: route.settings.description,
tags: route.settings.tags,
vhost: route.settings.vhost,
cors: route.settings.cors,
jsonp: route.settings.jsonp,
}
})
reply(routes)
}
});
return server;
})()
};
const seneca = Seneca()
.use(SenecaWeb, config)
//.use('stu')
.use('api')
//.client({type: 'tcp', pin: 'role:math'})
.ready(() => {
const server = seneca.export('web/context')();
server.start(() => {
server.log('server started on: ' + server.info.uri);
});
});