标题:事件(Events)
中介(Broker)内置事件总线,支持事件驱动架构(Event-driven architecture),可将事件发送到本地和远程服务。
需要注意的是,这些内建事件是即发即弃(发送出去就没了)的,假设给一个离线的服务发送事件,这个事件发送出去就会丢失。 关于持久化,想要实现耐用且可靠(不会丢失)的事件可以查看moleculer-channels。
均衡事件(Balanced events)
事件监听器被分成了逻辑组(Groups)。 这意味着在每个组中只触发一个监听器。
示例: 假设你拥有两个主要服务。
用户
(users)&支付
(payments)。 两个服务都订阅(subscribe)了user.created
事件。 你启动了3个用户
服务的实例和2个支付
服务的实例。 当你发送一个user.created
事件给这两个服务时,不论是用户
服务还是支付
服务,都只会有一个实例会接收到这个事件。
组名默认是服务名,但是你可以在服务中的事件定义里覆盖它。
示例
module.exports = { |
发送均衡事件
你可以使用broker.emit
方法发送均衡事件。 第一个参数是事件名,第二个参数是要发送的数据。 如果要发送多个数据,可以把它们放进一个Object
(对象)里。
// `user` 会被序列化成字符串后再传过去。 |
指定接收事件的组或服务:
// 只有`mail` 和 `payments` 服务能接收这个事件。 |
广播事件(Broadcast event)
与均衡事件不同的是,广播事件会发送到所有可以用的本地或者远程服务。 这些服务的每个实例都会接收到这个广播事件。
你可以使用broker.broadcast
方法去发送一个广播事件。
broker.broadcast("config.changed", config); |
指定接收事件的组或服务:
// 发送给 "mail" 服务的所有实例。 |
本地广播事件
你可以使用broker.broadcastLocal
方法将广播事件只发送给本地的所有服务。
broker.broadcastLocal("config.changed", config); |
订阅事件
v0.14
版本支持基于上下文(Context)的事件处理器(Event handlers)。 如果你想在使用事件驱动架构的时候追踪你的事件,事件上下文会非常有用。 你要是熟悉行为上下文(Action Context)你会觉得很容易上手。 事件上下文和行为上下文非常相似,除了一些只有事件具有的相关属性(Properties)。 查看事件属性的完整列表
Legacy event handlers你没必要去重写所有已有的事件处理器,因为Moleculer仍然支持过时的事件处理写法
"user.created"(payload) { ... }
. Moleculer 能够识别事件处理器不同的写法:
- 如果它发现是
"user.created"(ctx) { ... }
这样的写法, 它将会使用事件上下文调用它。- 相反,如果是
"user.created"(payload, sender, eventName, ctx) {...}
这样的写法,它会使用旧的参数形式调用它,旧的参数里第4个参数会变成事件上下文。- 你也可以在事件声明的地方,通过设置
context: true
强制使用新的写法。
基于上下文的事件处理器& 发送一个嵌套事件
module.exports = { |
在服务的’events’属性里订阅事件。 事件名可以使用通配符(?
, *
, **
)。
module.exports = { |
事件参数验证(Event parameter validation)
与操作参数验证相似,事件也支持参数验证。 如同行为定义一样,你应该在事件定义中定义params
,并且通过内置的Validator
在事件中验证参数。
// mailer.service.js |
验证错误不会发送给调用者,它们会被写进日志,或者你也可以通过全局错误处理器(global error handler)捕获这些错误。
内置事件(Internal events)
中介可以广播一些内置事件。 这些内置事件都以$
前缀开头。
$services.changed
中介会在本地或远程节点销毁和加载服务的时候发送这个事件。
参数
Name | Type | 说明 |
---|---|---|
localService |
Boolean |
当本地服务改变的时候为True。 |
$circuit-breaker.opened
中介会在熔断器(Circuit Breaker)模块状态变成open
的时候发送这个事件。
参数
名称 | 类型 | 说明 |
---|---|---|
nodeID |
String |
Node ID |
action |
String |
Action 名称 |
failures |
Number |
失败次数 |
$circuit-breaker.half-opened
中介会在熔断器(Circuit Breaker)模块状态变成half-open
的时候发送这个事件。
参数
名称 | 类型 | 描述 |
---|---|---|
nodeID |
String |
Node ID |
action |
String |
Action 名称 |
$circuit-breaker.closed
中介会在熔断器(Circuit Breaker)模块状态变成closed
的时候发送这个事件。
参数
Name | Type | Description |
---|---|---|
nodeID |
String |
Node ID |
action |
String |
Action 名称 |
$node.connected
中介会在节点连接成功和重连成功的时候发送这个事件。
参数
Name | Type | 描述 |
---|---|---|
node |
节点 |
节点信息的Object |
reconnected |
Boolean |
是不是重连? |
$node.updated
当经纪收到来自节点的 INFO 消息时(即服务已加载或销毁),它会发送此事件。
参数
名字 | Type | 描述 |
---|---|---|
node |
节点 |
节点信息的Object |
$node.disconnected
中介会在节点断开连接时(不论正常或者异常)发送这个事件。
参数
名字 | Type | 描述 |
---|---|---|
node |
节点 |
节点信息的Object |
unexpected |
Boolean |
true - 没有接收到心跳(Heartbeat), false - 接收到从节点发出的DISCONNECT 消息。 |
$broker.started
中介会在所有本地服务启动(started)并且调用broker.start()
时,只发送一次这个事件。
$broker.stopped
中介会在所有本地服务停止(stopped)并且调用broker.stop()
时,只发送一次这个事件。
$transporter.connected
推送系统(Transporter)连接成功时会发送一次这个事件。
$transporter.disconnected
推送系统(Transporter)断开连接后时会发送一次这个事件。
$broker.error
当broker发生错误时中介会发送这个事件。 事件参数(Event payload)
{ |
$transit.error
当传输模块(Transit Module)发生错误时,中介会发送这个事件。 事件参数(Event payload)
{ |
$transporter.error
当推送系统(Transporter)模块发生错误时中介会发送这个事件。 事件参数(Event payload)
{ |
$cacher.error
当缓存器(Cacher)模块发生错误时中介会发送这个事件。 事件参数(Event payload)
{ |
$discoverer.error
当服务发现(Discoverer)模块发生错误时中介会发送这个事件。 事件参数(Event payload)
{ |