所谓混合应用(Hybrid application),是指能够同时处理来自多个不同传输层协议请求的 Nest 应用。常见的场景包括同时监听 HTTP 请求和微服务消息,或同时运行多个类型的微服务监听器(如 TCP、Redis、MQTT 等)。
由于 createMicroservice() 方法无法一次性创建多个微服务实例,因此需要分别为每个微服务独立创建并启动。实现这一需求的推荐方式是:通过 connectMicroservice() 方法将一个主应用实例(INestApplication)与一个或多个微服务实例(INestMicroservice)连接起来。
const app = await NestFactory.create(AppModule)
const microservice = app.connectMicroservice<MicroserviceOptions>({
transport: Transport.TCP,
})
await app.startAllMicroservices()
await app.listen(3001)如果你的应用不需要处理 HTTP 请求,可以用 app.init() 来替代
app.listen(port),只初始化框架而不绑定端口。
若应用需要同时连接多个微服务,只需为每个微服务单独调用一次 connectMicroservice() 即可。例如,以下代码展示了同时启动一个 TCP 微服务和一个 Redis 微服务的方式:
const app = await NestFactory.create(AppModule)
// 微服务实例 #1 - TCP
const microserviceTcp = app.connectMicroservice<MicroserviceOptions>({
transport: Transport.TCP,
options: {
port: 3001,
},
})
// 微服务实例 #2 - Redis
const microserviceRedis = app.connectMicroservice<MicroserviceOptions>({
transport: Transport.REDIS,
options: {
host: 'localhost',
port: 6379,
},
})
await app.startAllMicroservices()
await app.listen(3001)在混合应用中,如果希望 @MessagePattern() 装饰器仅处理来自特定传输层(例如仅处理 NATS 消息),可以通过第二个参数显式指定传输类型。Transport 是一个枚举,包含了所有内置传输协议选项。
@MessagePattern('time.us.*', Transport.NATS)
getDate(@Payload() data: number[], @Ctx() context: NatsContext) {
console.log(`Subject: ${context.getSubject()}`) // 例如 "time.us.east"
return new Date().toLocaleTimeString(...)
}
@MessagePattern({ cmd: 'time.us' }, Transport.TCP)
getTCPDate(@Payload() data: number[]) {
return new Date().toLocaleTimeString(...)
}@Payload()、@Ctx()、Transport 和 NatsContext 均来自
@nestjs/microservices 包。
默认情况下,混合应用中的微服务实例不会自动继承主应用(即基于 HTTP 的 INestApplication 实例)所注册的全局配置,例如全局管道、拦截器、守卫和异常过滤器。
如果你希望这些全局配置同样应用于微服务,可以在调用 connectMicroservice() 时,通过其第二个参数启用继承机制。只需将 inheritAppConfig 选项设置为 true 即可:
const microservice = app.connectMicroservice<MicroserviceOptions>(
{
transport: Transport.TCP,
},
{
inheritAppConfig: true,
}
)