使用AWS Copilot部署NestJS微服务至ECS时的TCP连接问题
问题描述
本地运行正常的NestJS微服务栈(API Gateway + restaurant微服务),通过AWS Copilot部署到同一应用后,API Gateway无法连接restaurant服务,报错Error: connect ECONNREFUSED 0.0.0.0:8001。
环境与配置
服务类型
- API Gateway:Load Balanced Web Service
- restaurant服务:Backend Service
- 已在两者manifest中启用
network.connect=true(Service Connect)
核心代码
Gateway/src/main.ts
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule); await app.listen(8000); } bootstrap();
Restaurant/src/main.ts
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { Transport, TcpOptions } from '@nestjs/microservices'; async function bootstrap() { const app = await NestFactory.createMicroservice(AppModule, { transport: Transport.TCP, options: { host: '0.0.0.0', port: 8001, }, } as TcpOptions); await app.listen(); } bootstrap();
Gateway/src/app.module.ts
@Module({ imports: [ ConfigModule.forRoot({ envFilePath: [`.env.stage.${process.env.STAGE}`], }), ], controllers: [RestaurantController, AppController], providers: [ ConfigService, { provide: 'RESTAURANT_SERVICE', useFactory: (configService: ConfigService) => { return ClientProxyFactory.create({ options: { host: '0.0.0.0', port: 8001, }, }); }, inject: [ConfigService], }, ], }) export class AppModule {}
Manifest配置
api-gw manifest
name: api-gw type: Load Balanced Web Service http: path: '/' image: build: Dockerfile port: 8000 cpu: 256 # Number of CPU units for the task. memory: 512 # Amount of memory in MiB used by the task. platform: linux/x86_64 count: 1 # Number of tasks that should be running in your service. exec: true # Enable running commands in your container. network: connect: true # Enable Service Connect for intra-environment traffic between services.
restaurant service manifest
name: restaurant type: Backend Service image: build: Dockerfile port: 8001 cpu: 256 # Number of CPU units for the task. memory: 512 # Amount of memory in MiB used by the task. platform: linux/x86_64 count: 1 # Number of tasks that should be running in your service. exec: true # Enable running commands in your container. network: connect: true # Enable Service Connect for intra-environment traffic between services.
解决方案
核心问题
API Gateway中配置的restaurant服务地址0.0.0.0:8001是本地回环地址,在AWS Copilot的Service Connect网络环境中无法正确指向restaurant服务实例。
修复步骤
修改API Gateway的服务连接配置
在Gateway的app.module.ts中,将ClientProxy的host改为Copilot自动注入的服务DNS名称,同时补全传输类型配置:{ provide: 'RESTAURANT_SERVICE', useFactory: (configService: ConfigService) => { return ClientProxyFactory.create({ transport: Transport.TCP, options: { host: 'restaurant', // 使用manifest中定义的服务名称作为域名 port: 8001, }, }); }, inject: [ConfigService], },注:Copilot启用Service Connect后,同一应用内的服务可直接通过服务名称(manifest的
name字段)作为域名访问,无需手动指定IP。验证端口一致性
确保restaurant服务代码监听的端口(8001)与manifest中image.port配置完全一致,Copilot会自动通过Service Connect暴露该端口给同应用内的其他服务。重新部署服务
执行部署命令使配置生效:copilot deploy --name api-gw copilot deploy --name restaurant
额外优化建议
通过环境变量管理服务地址,避免硬编码:
- 在Gateway的
.env.stage.<环境名>文件中添加:RESTAURANT_SERVICE_HOST=restaurant RESTAURANT_SERVICE_PORT=8001 - 在
app.module.ts中读取环境变量:options: { host: configService.get('RESTAURANT_SERVICE_HOST'), port: configService.get('RESTAURANT_SERVICE_PORT'), },
内容的提问来源于stack exchange,提问作者Mickael Zana
相关产品推荐
相关产品推荐

