在 NestJS 项目中,我在创建多个微服务时面临重复依赖解析的挑战。初始化多个微服务的标准方法似乎是重新实例化每个微服务的依赖关系。我怎样才能摆脱它?
当然,我可以使用
amqplib
或类似的东西,但是 @MessagePattern({cmd:"something"})
和其他原生 NestJS 代码将无法工作。
如果您想从
ConfigModule
参数获取一些配置以实例化微服务,也会出现同样的问题。因为要解决 ConfigModule
的依赖关系,您需要先创建应用程序实例,然后再创建微服务实例。
async function bootstrap() {
const appContext = await NestFactory.createApplicationContext(AppModule);
// OR: const appContext = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule);
const configService = appContext.get(ConfigService);
const microserviceOptions: MicroserviceOptions = {
transport: Transport.RMQ,
options: {
urls: [configService.get<string>(ConfigPropertyNames.RABBITMQ_URI)],
queue: QueueNames.AUTH_SERVICE_RPC,
queueOptions: {
durable: false
},
},
}
const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, microserviceOptions);
await app.listen();
Logger.log(
`🚀 Application is running`
);
}
[Nest] 23400 - 14.03.2024, 10:51:58 LOG [NestFactory] Starting Nest application...
[Nest] 23400 - 14.03.2024, 10:51:58 LOG [InstanceLoader] AppModule dependencies initialized +13ms
[Nest] 23400 - 14.03.2024, 10:51:58 LOG [InstanceLoader] CustomConfigModule dependencies initialized +1ms
[Nest] 23400 - 14.03.2024, 10:51:58 LOG [InstanceLoader] MongooseModule dependencies initialized +0ms
[Nest] 23400 - 14.03.2024, 10:51:58 LOG [InstanceLoader] ConfigHostModule dependencies initialized +0ms
[Nest] 23400 - 14.03.2024, 10:51:58 LOG [InstanceLoader] ConfigModule dependencies initialized +1ms
[Nest] 23400 - 14.03.2024, 10:51:58 LOG [InstanceLoader] LoggerModule dependencies initialized +69ms
[Nest] 23400 - 14.03.2024, 10:51:59 LOG [InstanceLoader] MongooseCoreModule dependencies initialized +349ms
[Nest] 23400 - 14.03.2024, 10:51:59 LOG [InstanceLoader] MongooseModule dependencies initialized +6ms
[Nest] 23400 - 14.03.2024, 10:51:59 LOG [InstanceLoader] MongoDBModule dependencies initialized +1ms
2024-03-14 10:51:59 INFO : User service is being initialized
[Nest] 23400 - 14.03.2024, 10:51:59 LOG [InstanceLoader] AuthModule dependencies initialized +2ms
[Nest] 23400 - 14.03.2024, 10:51:59 LOG [NestFactory] Starting Nest application... +2ms
[Nest] 23400 - 14.03.2024, 10:51:59 LOG [InstanceLoader] AppModule dependencies initialized +3ms
[Nest] 23400 - 14.03.2024, 10:51:59 LOG [InstanceLoader] CustomConfigModule dependencies initialized +0ms
[Nest] 23400 - 14.03.2024, 10:51:59 LOG [InstanceLoader] MongooseModule dependencies initialized +1ms
[Nest] 23400 - 14.03.2024, 10:51:59 LOG [InstanceLoader] ConfigHostModule dependencies initialized +0ms
[Nest] 23400 - 14.03.2024, 10:51:59 LOG [InstanceLoader] ConfigModule dependencies initialized +0ms
[Nest] 23400 - 14.03.2024, 10:51:59 LOG [InstanceLoader] LoggerModule dependencies initialized +3ms
[Nest] 23400 - 14.03.2024, 10:51:59 LOG [InstanceLoader] MongooseCoreModule dependencies initialized +303ms
[Nest] 23400 - 14.03.2024, 10:51:59 LOG [InstanceLoader] MongooseModule dependencies initialized +1ms
[Nest] 23400 - 14.03.2024, 10:51:59 LOG [InstanceLoader] MongoDBModule dependencies initialized +0ms
2024-03-14 10:51:59 INFO : User service is being initialized
[Nest] 23400 - 14.03.2024, 10:51:59 LOG [InstanceLoader] AuthModule dependencies initialized +1ms
[Nest] 23400 - 14.03.2024, 10:51:59 LOG [NestMicroservice] Nest microservice successfully started +357ms
[Nest] 23400 - 14.03.2024, 10:51:59 LOG 🚀 Application is running
我认为您可以利用 NestJS 的 混合应用程序支持。
你的代码将变成:
const app = await NestFactory.create(AppModule);
const configService = appContext.get(ConfigService);
const microserviceOptions: MicroserviceOptions = {
transport: Transport.RMQ,
options: {
urls: [configService.get<string>(ConfigPropertyNames.RABBITMQ_URI)],
queue: QueueNames.AUTH_SERVICE_RPC,
queueOptions: {
durable: false
},
},
inheritAppConfig: true // Note this extra config
}
const microservice = app.connectMicroservice<MicroserviceOptions>(microserviceOptions);
await app.startAllMicroservices();
await app.listen(3000);
另外,最近NestJS引入了条件模块注册。您可以创建一个
MicroserviceModule
,将所有感兴趣的模块移到其中,然后基于 ConfigService
变量(例如 isMicroservice
)注册它。您可以为两个应用程序使用两个不同的环境文件,但这可能很棘手。
@Module({
imports: [ConfigModule.forRoot(), ConditionalModule.registerWhen(MicroserviceModule, 'USE_MICROSERVICE')],
})
export class AppModule {}
最后,最简单的方法是创建一个“虚拟”
AppModule
,仅将 ConfigService
作为导入,从中创建 app
,然后使用真实的 microservice
创建
AppModule
@Module({
imports: [ConfigModule.forRoot(),
})
export class AppConfigModule {}
@Module({
...yourAppModuleConfig
})
export class AppModule {}
async function bootstrap() {
const appContext = await NestFactory.createApplicationContext(AppConfigModule);
// OR: const appContext = await NestFactory.createMicroservice<MicroserviceOptions>(AppConfigModule);
const configService = appContext.get(ConfigService);
const microserviceOptions: MicroserviceOptions = {
transport: Transport.RMQ,
options: {
urls: [configService.get<string>(ConfigPropertyNames.RABBITMQ_URI)],
queue: QueueNames.AUTH_SERVICE_RPC,
queueOptions: {
durable: false
},
},
}
const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, microserviceOptions);
await app.listen();
Logger.log(
`🚀 Application is running`
);
}