【问题标题】:Docker-RabbitMQ-NestJS microservices error 406 PRECONDITION_FAILEDDocker-RabbitMQ-NestJS 微服务错误 406 PRECONDITION_FAILED
【发布时间】:2021-10-26 20:49:38
【问题描述】:

我是 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"

ma​​in.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 {}

功能很简单 - 当 localhost:3000 (api_client) 上的 GET 被调用时,它会调用(在控制器中)
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。

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

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

【问题讨论】:

    标签: docker rabbitmq microservices nestjs


    【解决方案1】:

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

    【讨论】:

    • 感谢您的回答。我已经使用附加的“网络”键(rabbitmq_nestjs:驱动程序:桥接)编辑了 docker compose 文件以连接所有三个服务,但错误仍然存​​在。但是我发现默认情况下所有服务都应该在同一个网络中。我尝试过的另一件事是添加一个新用户“admin”,因为默认用户“guest”仅对 localhost 具有权限,但仍然对错误没有任何影响。
    【解决方案2】:

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

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

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

    【讨论】:

    • 感谢您的建议,此解决方案对我有用!但是,我需要我的微服务通过请求-响应(消息)模式而不是事件模式进行通信。我试图弄清楚为什么 EventPattern 有效而 MessagePattern 无效但没有成功:-(
    【解决方案3】:

    所以在找出导致错误的原因 5 天后,我发现问题出在 Nest 本身。该错误已记录在here。我已经删除了与@nestjs/microservices 相关的所有代码,并尝试仅使用amqlib 使用this approach,请求/响应功能终于可以工作了。

    【讨论】:

      猜你喜欢
      • 2021-01-12
      • 1970-01-01
      • 2021-06-05
      • 2019-05-28
      • 2022-06-15
      • 2020-03-03
      • 1970-01-01
      • 2022-01-22
      • 2017-05-08
      相关资源
      最近更新 更多