Service
表示 Moleculer 框架中的微服务。 您可以在服务中定义动作和订阅事件。 要创建服务,您必须定义一个方案。 服务方案类似于 VueJS 的一个组件。
Schema
方案有一些主要部件: name
, version
, settings
, actions
, methods
, events
.
定义有2个动作的简单服务方案
// math.service.js |
基本属性
服务方案中有一些基础属性。
// posts.v1.service.js |
name
是一个必须定义的属性。 当你调用它时,它是动作名称的第一部分。
要禁用服务名称前缀, 请在服务设置中修改
$noServiceNamePrefix: true
。
version
是一个可选的属性。 使用它来运行来自同一服务的多个版本。 它也是动作名称中的前缀。 它可以是 Number
或 String
。
// posts.v2.service.js |
在版本 2
上调用此服务的动作 find
:
broker.call("v2.posts.find"); |
REST call通过API Gateway, 发出请求
GET /v2/posts/find
.
要禁用服务名称前缀, 请在服务设置中修改
$noVersionPrefix: true
。
设置
settings
属性是一个静态存储属性,您可以在那里存储每个设置/选项到您的服务。 您可以通过服务内的 this.settings
操作它。
// mailer.service.js |
settings
也可以在远程节点上获得。 它在发现服务期间转移。
内部设置
核心模块使用了一些内部设置。 这些设置名称具有 $
(dollar sign) 前缀。
Name | Type | Default | 说明 |
---|---|---|---|
$noVersionPrefix |
Boolean |
false |
在动作名称中禁用版本前缀。 |
$noServiceNamePrefix |
Boolean |
false |
在动作名称中禁用名字前缀。 |
$dependencyTimeout |
Number |
0 |
等待此服务的依赖服务超时时间。 |
$shutdownTimeout |
Number |
0 |
超时关闭此等待的活动请求。 |
$secureSettings |
Array |
[] |
安全设置列表。 |
服务安全设置项
为了保护您的令牌 & API 密钥,在服务设置中定义 $secureSettings: []
属性并设置受保护的属性键。 受保护的设置不会被发布到其他节点,它不会出现在服务注册表中。 这些设置仅在服务函数内的 this.settings
下可用。
// mail.service.js |
混入
Mixins 是分配 Moleculer 服务的可重复使用功能的一种灵活的方式。 服务构造器将这些混入功能与当前服务方案合并。 当一个服务使用混入时,mixins 中存在的所有属性都将被“混入”到当前的服务中。
以下示例扩展 moleculer-web
服务
// api.service.js |
上面的示例创建一个 api
服务,继承来自 ApiGwService
的所有属性,但覆盖端口设置并通过新的 myAction
动作扩展。
合并算法
合并算法取决于属性类型。
Property | Algorithm |
---|---|
name , version |
合并 & 覆盖。 |
settings |
在 defaultsDeep 的情况下深度扩展。 |
metadata |
在 defaultsDeep 的情况下深度扩展。 |
actions |
在 defaultsDeep 的情况下深度扩展。 如果您在服务中设置为 fals 您可以禁用混入行为。 |
hooks |
在 defaultsDeep 的情况下深度扩展。 |
methods |
合并 & 覆盖。 |
events |
连接侦听器。 |
created , started , stopped |
连接侦听器。 |
mixins |
合并 & 覆盖。 |
dependencies |
合并 & 覆盖。 |
any custom | 合并 & 覆盖。 |
Merge algorithm examples合并 & 覆盖: 如果 serviceA 有
a: 5
,b: 8
且 serviceB 有c: 10
b: 15
, 混合服务将有a: 5
,b: 15
andc: 10
Concatenate: 如果 serviceA & serviceB 订阅users.created
事件,当users.created
事件发出时,两个事件处理程序都会被调用。
Actions
服务公开的可调用的方法称为活动或动作或行为 (actions, 以后不加区分)。 他们可以使用 broker.call
或 ctx.call
来调用。 该动作可以是 Function
(简写为 handler) 或一个对象具有 handler
属性及更多属性。 该动作应该放置在方案中的 actions
下. 参见 actions documentation.
// math.service.js |
您可以这样调用上述动作
const res = await broker.call("math.add", { a: 5, b: 7 }); |
在动作中,您可以使用 ctx.call
方法在其他服务中调用其他嵌套动作。 它是 broker.call
的一个别名,但它将自己设置为父 context (由于正确的追踪链)。
// posts.service.js |
动作处理器的
this
总是指向 Service 实例。
Events
您可以在 events
中订阅事件。 参见 events documentation.
// report.service.js |
动作处理器的
this
总是指向 Service 实例。
Grouping
服务管理器按群组名称将事件监听器分组。 默认情况下,群组名称是服务名称。 但你可以在事件定义中覆盖它。
// payment.service.js |
Methods
若要在服务中创建私有方法,请将您的函数放在 methods
中。 这些函数是私有的,无法与 broker.call
一起调用。 但你可以在服务中调用它(来自操作处理器、事件处理器和生命周期事件处理器)。
用例
// mailer.service.js |
If you want to wrap a method with a middleware use the following notation:
// posts.service.js |
方法名称不能是
name
,version
,settings
,metadata
,schema
,broker
,actions
,logger
, 因为在方案中这些名字是保留的。
方法中的
this
总是指向 Service 实例。
生命周期事件
有一些生命周期服务事件,将由服务管理器触发。 它们放置服务方案中。
// www.service.js |
依赖关系
如果您的服务依赖于其他服务,请使用方案中的 dependencies
属性。 服务在调用 started
事件之前会等待它的依赖服务处理完毕。
// posts.service.js |
一旦 likes
, v2.auth
, v2.users
, staging.comments
(无论以上服务在本地还是远程节点) 变得可用,服务立即执行 started
处理器。
等待通过 ServiceBroker 提供的服务
可以使用 ServiceBroker
的方法 waitForServices
来等待服务。 所有定义的服务可用 & 启动后, 它返回的 Promise
将被解决。
Parameters
Parameter | Type | Default | Description |
---|---|---|---|
services |
String or Array |
- | 等待服务列表 |
timeout |
Number |
0 |
等待超时。 0 意味着没有超时。 如果超时,引发 MoleculerServerError 。 |
interval |
Number |
1000 |
以毫秒为单位的监视频率 |
示例
broker.waitForServices(["posts", "v2.users"]).then(() => { |
设置超时 & 间隔
broker.waitForServices("accounts", 10 * 1000, 500).then(() => { |
元数据
Service
方案有一个 metadata
属性。 您可以在此存储任何关于服务的元信息。 您可以在服务函数内用 this.metadata
访问它。 Moleculer 核心模块不使用它, 你可以用它存储任何东西。
module.exports = { |
metadata
也可以在远程节点上获得。 它在服务发现期间转移。
ServiceBroker 属性
在服务函数中, this
始终指向服务实例。 它有一些属性 & 方法可以用于您的服务函数。
Name | Type | Description |
---|---|---|
this.name |
String |
Name of service (from schema) |
this.version |
Number or String |
Version of service (from schema) |
this.fullName |
String |
Name of version prefix |
this.settings |
Object |
Settings of service (from schema) |
this.metadata |
Object |
Metadata of service (from schema) |
this.schema |
Object |
Schema definition of service |
this.broker |
ServiceBroker |
Instance of broker |
this.Promise |
Promise |
Class of Promise (Bluebird) |
this.logger |
Logger |
Logger instance |
this.actions |
Object |
Actions of service. Service can call own actions directly |
this.waitForServices |
Function |
Link to broker.waitForServices method |
this.currentContext |
Context |
Get or set the current Context object. |
服务创建
创建和加载服务有几种方式。
broker.createService()
想要用于测试、开发或查看原型,使用 broker.createService
方法加载 & 通过 schema 创建的服务。 这是最简单 & 最快的方法。
broker.createService({ |
从文件载入服务
推荐的方式是将您的服务代码放入一个文件并加载到服务管理器。
math.service.js
// Export the schema of service |
用服务管理器加载它:
// Create broker |
在服务文件中,您也可以创建服务实例。 在这种情况下,您必须导出返回 Service 实例的函数。
const { Service } = require("moleculer"); |
或者创建一个以服务模式返回的函数
// Export a function, the `loadService` will call with the ServiceBroker instance. |
从文件夹加载多个服务
如果您有许多服务(而且您必将会有)我们建议将它们放到 services
文件夹中,使用 broker.loadServices
方法加载它们。
Syntax
broker.loadServices(folder = "./services", fileMask = "**/*.service.js"); |
示例
// Load every *.service.js file from the "./services" folder (including subfolders) |
(推荐) 使用 Moleculer Runner 加载
我们建议使用 Moleculer Runner 启动一个 ServiceBroker 并加载服务。 阅读更多关于 Moleculer Runner 的内容。 这是启动节点最容易的办法。
服务热重载
Moleculer 具有内置的热重载功能。 在开发过程中,它可能非常有用,因为当您修改它时它会重新加载您的服务。 您可以在服务管理器选项或 Moleculer Runner 中启用它。 视频演示它如何工作。
在服务管理器选项中启用
const broker = new ServiceBroker({ |
在 Moleculer Runner 中启用
使用 --hot
或 -H
打开它。
$ moleculer-runner --hot ./services/test.service.js |
热重载功能仅适用于 Moleculer Runner ,或者如果您使用
broker.loadService
或broker.loadServices
加载您的服务。broker.createService
不起作用。
热重载机制监视服务文件及其依赖。 每次检测到文件更改时,热重载机制将跟踪依赖它的服务并重新启动它们。
本地变量
如果您想要在您的服务中使用本地属性/变量,在 created
事件方法中声明它们。
本地变量示例
const http = require("http"); |
Naming restriction注意,你不能使用保留给服务的变量名称,或者与你的方法名冲突! 例如:
this.name
,this.version
,this.settings
,this.schema
…等。
ES6 Classes
如果您喜欢ES6类而不是Moleculer服务模式,您可以在 ES6 类中写入您的服务。 这样做有两种方式。
具有schema解析的原生ES6类
定义 actions
和 events
方法作为类方法并调用 parseServiceSchema
构造函数中包含schema 定义的方法,处理程序指向这些类方法。
const Service = require("moleculer").Service; |
使用装饰器
感谢 @ColonelBundy, 你也可以使用 ES7/TS 装饰符: moleculer-decorators
Need a compiler注意,您必须使用 Typescript 或 Babel 来编译装饰器。
服务示例
const { ServiceBroker } = require('moleculer'); |
内置服务
ServiceBroker
包含一些内部服务来检查节点健康状况或获取一些注册表信息。 您可以通过设置服务管理器选项 internalServices: false
来禁用他们。
节点列表
它列出所有已知节点(包括本地节点)。
broker.call("$node.list").then(res => console.log(res)); |
Parameters
Name | Type | Default | Description |
---|---|---|---|
withServices |
Boolean |
false |
List with services. |
onlyAvailable |
Boolean |
false |
List only available nodes. |
服务列表
它列出所有注册的服务(本地 & 远程)。
broker.call("$node.services").then(res => console.log(res)); |
Parameters
名字 | Type | 默认设置 | 描述 |
---|---|---|---|
onlyLocal |
Boolean |
false |
List only local services. |
skipInternal |
Boolean |
false |
Skip the internal services ($node ). |
withActions |
Boolean |
false |
List with actions. |
onlyAvailable |
Boolean |
false |
List only available services. |
本地动作列表
它列出所有注册的动作(本地 & 远程)。
broker.call("$node.actions").then(res => console.log(res)); |
它有一些您可以在 params
中声明的选项。
Options
名字 | Type | 默认设置 | 描述 |
---|---|---|---|
onlyLocal |
Boolean |
false |
List only local actions. |
skipInternal |
Boolean |
false |
Skip the internal actions ($node ). |
withEndpoints |
Boolean |
false |
List with endpoints (nodes). |
onlyAvailable |
Boolean |
false |
List only available actions. |
本地事件列表
它列出所有事件订阅。
broker.call("$node.events").then(res => console.log(res)); |
它有一些您可以在 params
中声明的选项。
Options
名字 | Type | 默认设置 | 描述 |
---|---|---|---|
onlyLocal |
Boolean |
false |
List only local subscriptions. |
skipInternal |
Boolean |
false |
Skip the internal event subscriptions $ . |
withEndpoints |
Boolean |
false |
List with endpoints (nodes). |
onlyAvailable |
Boolean |
false |
List only available subscriptions. |
性能指标列表
它列出了所有衡量标准。
broker.call("$node.metrics").then(res => console.log(res)); |
它有一些您可以在 params
中声明的选项。
Options
名字 | Type | 默认设置 | 描述 |
---|---|---|---|
types |
String or Array |
null |
Type of metrics to include in response. |
includes |
String or Array |
null |
List of metrics to be included in response. |
excludes |
String or Array |
null |
List of metrics to be excluded from the response. |
获取服务管理器选项
它返回服务管理器选项。
broker.call("$node.options").then(res => console.log(res)); |
节点健康值
它返回本地节点的健康信息(包括 process & OS 信息)。
broker.call("$node.health").then(res => console.log(res)); |
健康信息示例:
{ |
注意,内部服务动作作未被追踪。
扩展
内部服务可以通过自定义功能轻松扩展。 要做到这一点,您必须定义一个 mixin schema internalServices
选项。
// moleculer.config.js |