通过 docker 访问的 Swagger UI 不起作用

Swagger UI accessed through docker does not work

我有两个微服务(交易和支付)将通过 ApiGateway 访问,每个微服务都在一个 docker 容器中。此外,我已经实现了自己的 SwaggerResourcesProvider,以便从一个点访问两个 Swagger:ApiGateway Swagger,正如您在这个问题中看到的:Single Swagger

为了在每个微服务中启用CORS,所有微服务(包括ApiGateway)都有以下代码:

@Bean
public CorsFilter corsFilter() {
    final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("*");
    config.addAllowedHeader("*");
    config.addAllowedMethod("*");
    source.registerCorsConfiguration("/**", config);
    return new CorsFilter(source);
}

如果我使用 IDE 执行每个微服务,我可以毫无问题地从 ApiGateway 访问微服务的 Swagger,如您所见(ApiGateway 在 8070 端口上执行):

但是,当我使用 docker-compose 执行它们时,我尝试通过 ApiGateway(将内部端口映射到 8070)访问任何微服务的 Swagger,我收到以下错误:

奇怪的是,如果我使用 bash 进入 ApiGateway docker,然后执行 curl transactionservice/api/v2/api-docs 然后我我正在接收相应的 json,因此 ApiGateway 的 docker 正在访问其余 docker 的 Swagger,但它无法从我的网络浏览器访问。

问题:为什么Swagger在使用docker执行时无法访问其他Swagger?

终于找到问题所在:在使用docker-compose执行时,每个微服务都使用服务名与其他微服务通信,而docker-compose能够将其翻译成相应的IP(这就是为什么在第二张图片中,交易 link 显示 http://transactionservice/...,因为在 docker- compose.yml 我正在使用 URL 作为资源 URL)。

因此,当我在 ApiGateway 中访问 swagger 时,它 returns 将 URL 作为资源。但是,html 是在我的机器中执行的,而不是在 docker 中执行的,所以当它尝试访问 http://transactionservice/api/v2/api-docs 时,我的机器确实对交易服务一无所知。

解决方案是在 ApiGateway 中使用重定向,使用此配置:

  zuul.routes.transaction.path: /transaction/**
  zuul.routes.transaction.url: http://transactionservice/api/transaction
  zuul.routes.transaction-swagger.path: /swagger/transaction/**
  zuul.routes.transaction-swagger.url: http://transactionservice/api
  zuul.routes.payment.path: /payment/**
  zuul.routes.payment.url: http://paymentservice/api/payment
  zuul.routes.payment-swagger.path: /swagger/payment/**
  zuul.routes.payment-swagger.url: http://paymentservice/api

  swagger.resources[0].name: transactions
  swagger.resources[0].url: /swagger/transaction/v2/api-docs
  swagger.resources[0].version: 2.0
  swagger.resources[1].name: payments
  swagger.resources[1].url: /swagger/payment/v2/api-docs
  swagger.resources[1].version: 2.0

这样一来,所有请求都使用 ApiGateway 执行,即使是 swagger 请求也是如此。