多框架研发
所谓的多框架启动,指的是多个能提供服务的上层框架,在一个进程中同时提供服务。
这里的多个上层框架,指的是 midway 提供的 @midwayjs/web , @midwayjs/koa , @midwayjs/express , @midwayjs/socektio , @midwayjs/grpc , @midwayjs/rabbitmq 等。
这些框架都能独立对外提供服务,暴露某个协议。比如 @midwayjs/web (包装 Egg.js ,提供 HTTP 服务),@midwayjs/grpc(包装 grpc.js,提供 gRPC 服务)。
框架(Framework)概念
Midway 现有的框架(Framework)每个是独立的,每一个框架都可以单独在进程中运行,理论上来说,每个框架都是一个独立的依赖注入容器,加上特定框架包含的三方库的组合。
这些独立的框架,都遵循 IMidwayFramewok 的接口定义,由 @midwayjs/bootstrap 库加载起来。
所以在提供的单进程部署方案中,我们可以通过一个 bootstrap.js 入口来启动应用。
// bootstrap.js
const WebFramework = require('@midwayjs/koa').Framework;
const web = new WebFramework().configure({
port: 7001,
});
const { Bootstrap } = require('@midwayjs/bootstrap');
Bootstrap.load(web).run();
多个框架启动文件(主副框架)
如果我们需要启动多个上层框架,可以利用 load 方法加载多次 。
// bootstrap.js
const WebFramework = require('@midwayjs/koa').Framework;
const GRPCFramework = require('@midwayjs/grpc').Framework;
const { Bootstrap } = require('@midwayjs/bootstrap');
const web = new WebFramework().configure({
port: 7001,
});
const grpcService = new GRPCFramemwork().configure({
services: [
{
protoPath: join(__dirname, 'proto/helloworld.proto'),
package: 'helloworld',
},
],
});
Bootstrap.load(web).load(grpcService).run();
注意,所有的上层框架都会遵循规范,导出一个 Framework 属性。
这里有一个主、副框架的概念。
第一个被 load 的框架为主框架,后面被 load 的都为副框架。
比如,上面示例的 @midwayjs/koa 为主框架, @midwayjs/grpc 为副框架。
主框架只能一个,而副框架可以有多个。
主框架在使用时略微有一些优势。
启动多框架
多框架启动需要依赖启动文件。
在本地开发时,我们之前使用 midway-bin dev --ts 命令,需要增加一个 entryFile 的入口参数。
$ cross-env NODE_ENV=local midway-bin dev --ts --entryFile=bootstrap.js
bootstrap.js 会自动判断 ts 环境,在本地开发时会加载 src 下的 ts 文件。
在服务器部署时,由于脚手架自带了 bootstrap.js 文件,直接修改即可,启动文件依旧为 start 命令(注意,启动前需要执行 npm run build 先将 ts 构建为 js)。
$ cross-env NODE_ENV=production node bootstrap.js
多框架场景不支持使用 egg-scripts 部署。
多框架生命周期
业务代码中生命周期的 onReady 方法在一个进程只执行一次。
在 egg 场景下,只会在 worker 进程生效。
import { Configuration } from '@midwayjs/decorator';
import { Application } from '@midwayjs/koa';
import { Application as GRPCApplication } from '@midwayjs/grpc';
@Configuration()
export class AutoConfiguration {
async onReady() {
// 这个 onReady 方法只会执行一次
}
}
全局的依赖注入容器
所有的框架将共享同一个依赖注入容器。
如下图,启动器(@midwayjs/bootstrap)模块将提前初始化一个依赖注入容器 A,在后续所有的框架中,都将复用这个依赖注入容器 A。
这意味这,在任意框架注入到容器中的单例,在其他框架也可以取到。