Election
如果需要在后端启动一个独立服务,在 VonaJS 中该如何实现呢?
由于 VonaJS 是分布式架构,后端可以启动多个 Workers。那么,应该在哪个 Worker 中启动独立服务呢?
VonaJS 针对此场景提供了Election,工作原理如下:
- 所有 Workers 都会参与竞争,获取所有权
- 可以指定同时获取所有权的 Workers 数量
- 取得所有权的 Workers 可以启动服务
- 如果某个拥有所有权的 Worker 正常退出或者异常终止,那么其他 Workers 就会继续参与竞争
创建meta.election
比如,在模块 demo-student 中创建meta.election。在选中的 Worker 中启动一个定时器,每隔 2 秒输出Hello World
1. Cli命令
bash
$ vona :create:bean meta election --module=demo-student2. 菜单命令
TIP
右键菜单 - [模块路径]: Vona Meta/Election
meta.election定义
typescript
export type TypeElectionObtainResource = 'echo';
@Meta()
export class MetaElection extends BeanElectionBase<TypeElectionObtainResource> {}TypeElectionObtainResource: 定义 Election 资源的类型
创建 Module Monkey
接下来创建Module Monkey,响应appStarted和appClose钩子
- 参见: 应用启动自定义
typescript
export class Monkey extends BeanSimple implements IMonkeyAppStarted, IMonkeyAppClose {
private _fnRelease: FunctionAsync<void> | undefined;
async appStarted() {
const scope = this.app.scope(__ThisModule__);
scope.election.obtain('echo', fnRelease => {
this._fnRelease = fnRelease;
this._doCustomLogic();
});
}
async appClose() {
this._fnRelease?.();
}
private _doCustomLogic() {
setInterval(() => {
console.log('Hello World, pid: ', process.pid);
}, 2000);
}
}_fnRelease: 此变量是一个函数,用于释放所有权appStarted: 调用election.obtain获取指定资源的所有权。当取得所有权就会调用回调函数。该回调函数提供一个fnRelease参数,用于后续释放所有权appClose: 释放所有权,以便其他 Workers 参与后续的竞争_doCustomLogic: 实现自定义的逻辑或者服务
Tickets
在调用election.obtain时,可以指定允许多个 Workers 取得所有权:
diff
async appStarted() {
const scope = this.app.scope(__ThisModule__);
scope.election.obtain(
'echo',
fnRelease => {
this._fnRelease = fnRelease;
this._doCustomLogic();
},
+ { tickets: 2 },
);
}| 名称 | 说明 |
|---|---|
| tickets | 允许指定数量的Workers取得所有权,默认为1 |