【问题标题】:Spring Boot API Gateway Unable to resolve nameSpring Boot API Gateway 无法解析名称
【发布时间】:2021-05-13 23:10:25
【问题描述】:

通过网关调用 Api 会引发 java.net.UnknownHostException,即使我可以使用给定的主机名直接访问应用程序

Spring Boot 版本:2.4.2
Spring-cloud.version:2020.0.1
Java 版本:11

注意:同样适用于 spring boot 2.3.8.RELEASE 和云版本:Hoxton.SR9 与 Java 8

日志:

2021-02-10 14:25:05.398 ERROR 12632 --- [ctor-http-nio-4] a.w.r.e.AbstractErrorWebExceptionHandler : [efcc81fd-3]  500 Server Error for HTTP GET "/sample-order-service/sample-order"

java.net.UnknownHostException: failed to resolve 'MY-COMPUTER-NAME' after 2 queries 
    at io.netty.resolver.dns.DnsResolveContext.finishResolve(DnsResolveContext.java:1013) ~[netty-resolver-dns-4.1.58.Final.jar:4.1.58.Final]
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
    |_ checkpoint ⇢ org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain]
    |_ checkpoint ⇢ HTTP GET "/sample-order-service/sample-order" [ExceptionHandlingWebHandler]
Stack trace:
        at io.netty.resolver.dns.DnsResolveContext.finishResolve(DnsResolveContext.java:1013) ~[netty-resolver-dns-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.resolver.dns.DnsResolveContext.tryToFinishResolve(DnsResolveContext.java:966) ~[netty-resolver-dns-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.resolver.dns.DnsResolveContext.query(DnsResolveContext.java:414) ~[netty-resolver-dns-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.resolver.dns.DnsResolveContext.onResponse(DnsResolveContext.java:625) ~[netty-resolver-dns-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.resolver.dns.DnsResolveContext.access$400(DnsResolveContext.java:63) ~[netty-resolver-dns-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.resolver.dns.DnsResolveContext$2.operationComplete(DnsResolveContext.java:458) ~[netty-resolver-dns-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:578) ~[netty-common-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.util.concurrent.DefaultPromise.notifyListeners0(DefaultPromise.java:571) ~[netty-common-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:550) ~[netty-common-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:491) ~[netty-common-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:616) ~[netty-common-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.util.concurrent.DefaultPromise.setSuccess0(DefaultPromise.java:605) ~[netty-common-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:104) ~[netty-common-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.resolver.dns.DnsQueryContext.trySuccess(DnsQueryContext.java:201) ~[netty-resolver-dns-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.resolver.dns.DnsQueryContext.finish(DnsQueryContext.java:193) ~[netty-resolver-dns-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.resolver.dns.DnsNameResolver$DnsResponseHandler.channelRead(DnsNameResolver.java:1230) ~[netty-resolver-dns-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103) ~[netty-codec-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.channel.nio.AbstractNioMessageChannel$NioMessageUnsafe.read(AbstractNioMessageChannel.java:93) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493) ~[netty-transport-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) ~[netty-common-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.58.Final.jar:4.1.58.Final]
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.58.Final.jar:4.1.58.Final]
        at java.base/java.lang.Thread.run(Thread.java:834) ~[na:an]

【问题讨论】:

  • 您是如何注册客户的?

标签: spring-boot spring-cloud spring-cloud-gateway


【解决方案1】:

在你的属性文件中添加这个属性:

eureka.instance.hostname=localhost

【讨论】:

    【解决方案2】:

    我也遇到了同样的问题,我可以通过更换弹簧的版本来解决它。这是我的 POM。

    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.9.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.demo.microservices</groupId>
    <artifactId>api-gateway</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>api-gateway</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>11</java.version>
        <spring-cloud.version>Hoxton.SR10</spring-cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    

    【讨论】:

      【解决方案3】:

      将此配置添加到您的微服务中

      eureka.instance.hostname=localhost
      

      【讨论】:

      • 它也不适合我。然后我意识到我必须将eureka.instance.hostname=localhost 传播到我想通过 api-gateway 访问的所有微服务。
      • 这解决了我的问题...但你能解释一下原因吗?
      【解决方案4】:

      在 API Gateway 中添加以下属性应该可以解决这个问题。它似乎在 Windows 平台上发现 API 网关不是默认的。

      spring.cloud.discovery.enabled=true

      请参阅下面的链接。 “https://stackoverflow.com/questions/65333590/spring-cloud-api-gateway-routing-not-working

      【讨论】:

      • 这不适用于 Spring Cloud 2020.0.2 + Spring Webflux + Netty。问题仍然存在
      【解决方案5】:

      这困扰了我很多,似乎是 netty 和 spring boot 2.4.x 的问题。

      但我设法通过使用reactor.netty.http.client.HttpClientDefaultAddressResolverGroup.INSTANCE 解析器解决了这个问题。

      因此,当您创建 WebClient bean 时,您可以执行以下操作

          @Bean
          @Primary
          public WebClient webClient() {
              HttpClient httpClient = HttpClient.create().resolver(DefaultAddressResolverGroup.INSTANCE);
              return WebClient.builder()
                      .clientConnector(new ReactorClientHttpConnector(httpClient))
                      .build();
          }
      

      【讨论】:

        【解决方案6】:

        使用可以在您从 api-gateway 调用的所有微服务的 application.properties 文件中使用“eureka.instance.prefer-ip-address=true”。根本原因是您的 api-gateway 正在使用系统的 username 调用微服务,您需要使用系统的 ip 地址调用该微服务。

        【讨论】:

          【解决方案7】:

          我遇到了同样的问题,发现这是因为 Spring 和 spring.cloud 版本。

          我已经改变了我的 pom.xml,如下所示。在父级中,我评论了 2.4.4 并使用了 2.2.6,然后在属性中我将 spring.cloud.version 2020.0.2 替换为 Hoxton.SR3 就是这样,然后它就开始工作了。

          <parent>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-parent</artifactId>
                  <!-- <version>2.4.4</version> -->
                  <version>2.2.6.RELEASE</version>
                  <relativePath/> <!-- lookup parent from repository -->
          </parent>
          
          <properties>
              <java.version>11</java.version>
              <!-- <spring-cloud.version>2020.0.2</spring-cloud.version> -->
              <spring-cloud.version>Hoxton.SR3</spring-cloud.version>
          </properties>
          

          【讨论】:

            【解决方案8】:

            我已经通过另一种方式解决了这个问题。 对于使用 Spring Webflux + Spring Cloud 遇到此问题的用户,请执行以下操作:

            1. 您需要自动接线DiscoveryClient discoveryClient;
            2. 将此方法添加到您的服务层(您使用 WebClient 的地方):
                private String getGatewayBaseUrl(ServiceInstance instance) {
                    return instance.getUri().toString();
                  }
            
            1. 从实例中获取网关的url
                getGatewayBaseUrl(discoveryClient.getInstances("YOUR_GATEWAY_SERVICE_NAME").get(0)
            

            也许这不是解决问题的最佳方法,或者也许不是最正确的方法,但可以工作

            【讨论】:

              猜你喜欢
              • 2021-07-14
              • 2021-03-23
              • 2020-12-11
              • 2018-12-20
              • 2018-02-10
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-12-08
              相关资源
              最近更新 更多