Docker-RabbitMQ-NestJS微服务错误406PRECONDITION_FAILED

Docker-RabbitMQ-NestJS microservices error 406 PRECONDITION_FAILED

我是 Docker 和 RabbitMQ 的新手,我已经尝试了 2 天来解决我的 docker 容器中的错误,其中包含:api_client, api_consumer, RabbitMQ。 我做了一项研究,并尝试阅读尽可能多的有这个问题的线程,但不幸的是没有任何帮助。

所以这是我的代码: compose.yml

  services:
    api_client:
     build:
      context: ""
      dockerfile: apps/api_client/Dockerfile
     env_file:
      - ./config/.env.local
     restart: always
     ports:
       - "3000:3000"
     depends_on:
       - rabbitmq

    api_consumer:
     build:
      context: ""
      dockerfile: apps/api_consumer/Dockerfile
    env_file:
      - ./config/.env.local
    restart: always
    depends_on:
      - rabbitmq

  rabbitmq:
    image: rabbitmq:3.9.2-management
    container_name: rabbitmq
    hostname: rabbitmq
    volumes:
      - /var/lib/rabbitmq
      - ./rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf
    ports:
      - "5672:5672"
      - "15672:15672"

main.ts(在api_consumer)

async function bootstrap() {
    const app = await NestFactory.createMicroservice<MicroserviceOptions>(
        ApiConsumerModule,
        {
            transport: Transport.RMQ,
            options: {
                queue: 'test_queue',
                urls: ['amqp://guest:guest@rabbitmq:5672'],
                queueOptions: {
                    durable: true
                }
            }
        },
    );
    const AWSAppConfig = app.get(AwsAppconfigLoaderService);
    const Log = new Logger(ApiClientService.name);

    await AWSAppConfig.loadAWSAppConfig()
        .then((_) => {
            Log.log(AWSAppConfig.getAppName());
        })
        .catch((err) => {
            Log.error(
                `Error occured while downloading AWS Config: ${JSON.stringify(
                    err,
                )}`,
            );
        });

    await app.listen();
}
bootstrap();

api-client.module.ts(在api_client)

@Module({
    imports: [
        ConfigModule.forRoot({
            isGlobal: true,
            load: [AppConfig],
        }),
        ClientsModule.register([{
            name: GET_MATCHED_DEVICES,
            transport: Transport.RMQ,
            options: {
                queue: 'test_queue',
                urls: ['amqp://guest:guest@rabbitmq:5672'],
                queueOptions: {
                    durable: true
                }
            }
        },
        ]),
        AwsAppconfigLoaderModule,
    ],
    controllers: [ApiClientController],
    providers: [ApiClientService],
})
export class ApiClientModule {}

功能很简单——当 GET on localhost:3000 (api_client) 被调用时,它会调用(在控制器中)
return this.client.send('getSample', "hello")

然后在 api_consumer 它应该调用(在控制器中)

@MessagePattern('getSample')
    getSample(data): string {
        Logger.debug(data)
        return "It works!";
    }

当所有 docker 服务启动时出现第一个错误:

Disconnected from RMQ. Trying to reconnect.
{
 "err": {
  "code": 406,
  "classId": 60,
  "methodId": 40
 }
}

然后当我尝试访问 localhost:3000 时,总是出现此错误:

Error: Channel closed by server: 406 (PRECONDITION-FAILED) with message "PRECONDITION_FAILED - fast reply consumer does not exist"

两个错误都来自 api_client。

我尝试过但没有帮助的内容:
-将耐用更改为 false 或完全删除耐用选项
- 添加 noAck
- 在 localhost:15672 上删除管理员中的队列(工作正常)
-从两个微服务中的 urls 中删除端口
- 如您所见,两个微服务中的队列选项相同

现在最荒谬的是这段代码 确实工作得很好 直到我开始处理第二个撰写文件(和 docker 文件)以进行本地(更快)的卷开发。然后突然间这些错误开始出现,即使 我撤消了所有代码更改,错误仍然存​​在。因此,我已经擦除我所有的卷(使用 docker system prune -a --volumes)很多次,但仍然没有。我的 OS 是 Ubuntu 20.04
我完全没有想法所以我把它写在这里希望能得到一些帮助。

失败是因为应用无法连接到rabbitmq,问题出在你的docker compose。确保服务在 docker 中使用相同的网络并且能够通信。

我知道这听起来很奇怪,但我昨天遇到了同样的问题,同样使用了 docker-compose 文件,但没有对其或 rabbitmq 逻辑进行任何更改,它就坏了。我尝试了很多东西,当我改变时

  • return this.client.send('getSample', "hello")@MessagePattern
  • return this.client.emit('getSample', "hello")@EventPattern

认为它解决问题没有意义,但实际上确实如此。
我建议您尝试一下,如果它有效,请告诉我,如果我不能为您提供更多帮助,请见谅。

所以在找出导致错误的原因 5 天后,我发现问题出在 Nest 本身。该错误已记录 here. I've deleted all the code associated with @nestjs/microservices and tried to use this approach 仅使用 amqlib,并且 request/response 功能终于起作用了。