微服务入门之Nodejs-Seneca

项目上可能会用到微服务,因此以Seneca构建微服务为例,记录一下自己的一些理解。主要内容以get-started为基础。

Seneca is a microservices toolkit for Node.js

what is Senaca

业务逻辑之外的一切都可以用微服务包装。通过解耦来让业务系统可以很容易的创建和改变。

Senaca有以下几个属性:

1. 模式匹配。
2. 隐藏服务间通信细节。
3. 组件化。通过插件组合成为微服务。

问题:多种通信协议的支持是怎么做的,或者是怎么配置的?Seneca内置有http,tcp等,消息队列等应该需要加新的微服务。搜索了一下,npm有seneca-queue。

在一个进程内

通过seneca.add()增加模式,以及对应的处理函数。通过seneca.act()来触发该模式,以供add中添加的处理函数在逻辑之后调用act的回掉函数。

问题:如果是远程调用,回调函数会被传递过去吗?
答:不会,把模式msg发过去,远程的微服务将处理的结果传递回来,再供回调函数处理。可以看出,一个模式,加一个
处理逻辑就是一个服务,区别只是这个服务的位置。远端需要类似rpc。

模式匹配

在seneca中,“The more specific pattern always wins. In other words, the pattern with the highest number of matching attributes has precedence”。“If the patterns have the same number of properties, they are matched in alphabetical order.”

举例说明:需要匹配的pattern信息是'a:1, b:2':
如果微服务提供 'a:1','a:1, b:2',这两个同时满足,则匹配more specific,即第二个。
字母顺序没太懂。感觉是在说精确匹配,不知道为什么要专门提这个。

因此,新的更具体的服务,只需要更加具体的模式,就可以在不影响原有功能的情况下扩展。

模式匹配的一些小tips

代码复用,新的模式可以直接通过this.act()来使用之前的其他服务。

如果需要在原有服务的基础上,加强新功能,可以选择overwrite,在原来add的基础上,继续add,在新的处理函数中,可以通过this.prior调用previous action definition。这样,可以在调用前功能之前改变输入,又可以在调用前功能之后改变输出。相当于给原有的服务包装了一层。

插件化

Seneca的插件是一个拥有单个参数的函数,通过use来引用,和express相似。

函数名就是插件名,插件内通过this.add()添加新的模式,this指代的就是调用use的Seneca实例(instance)。

调用this.add(‘init:插件名’, func(msg, respond){ })可以初始化插件。respond不用自己定义,出错了调用就行。

如果想要将单独的服务放在单独的文件中,必须是Node.js的modules了。module.exports = function name(options) {},调用时use中使用require或者直接用name都可以。

还有一个this.wrap函数,就类似自动overwrite所有满足条件的pattern。在测试中,通过express,再远程调用服务,我这边看到的结果是wrap影响了pattern,具体的需要再研究。

把微服务摘出来

之前的讨论都是在同一个进程中,现在要开始加上通信。

Server的一方listen({'type':"tcp", pin:'role:math'})
Client的一方client({'type':"tcp", pin:'role:math'})。

这样,Client端只管act,满足pin的pattern就会自动调client。

问题:seneca发送的包和接收的包是什么样的。

根据不同的协议走不同格式的数据。http没必要,太重,tcp可以直接传递流。udp也不错。

集成web框架

seneca不是一个web框架。它可以处理http请求,但是它不是一个web框架。这块倒没有什么新的点,主要就是将api向pattern的转换,以及参数的一些设置。注意配置。

数据存储

seneca-entity提供了一个数据抽象层.基于以下几个操作:

load:加载entity, role:entity,cmd:load,name:<entity-name> 
save:创建或者更新entity, role:entity,cmd:save,name:<entity-name>
list:列举entity.role:entity,cmd:list,name:<entity-name>
remove:删除entity.role:entity,cmd:remove,name:<entity-name>

总结

seneca本身也只是提供了一个管理微服务的框架,服务本身+index:即pattern+通信机制。微服务是一个解耦的产物,有点类似于unix哲学,一个物体实现一个功能。相对于之前一个程序的所有功能统一管理,微服务以通信为代价,换取了扩展,部署等等好处。在云上应该很方便。