java.net.UnknownHostException:在 Spring Boot 和 Cloud 中进行 4 次查询后无法解析“库存服务”

问题描述 投票:0回答:4

我正在使用 Spring Boot v2.7.0 和 Spring Cloud 堆栈来执行服务间通信。我看到了一些解决方案,例如:https://github.com/spring-cloud/spring-cloud-gateway/issues/2091,但它们都不适合我。

我在这里更新了代码:https://github.com/javaHelper/Spring-Boot-Microservices-sai-youtube/tree/main/3.Using-service-discovery

错误:

2022-06-10 09:31:26.600 ERROR 9506 --- [nio-8090-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.reactive.function.client.WebClientRequestException: Failed to resolve 'inventory-service' after 4 queries ; nested exception is java.net.UnknownHostException: Failed to resolve 'inventory-service' after 4 queries ] with root cause

java.net.UnknownHostException: Failed to resolve 'inventory-service' after 4 queries 
    at io.netty.resolver.dns.DnsResolveContext.finishResolve(DnsResolveContext.java:1047) ~[netty-resolver-dns-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.resolver.dns.DnsResolveContext.tryToFinishResolve(DnsResolveContext.java:1000) ~[netty-resolver-dns-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.resolver.dns.DnsResolveContext.query(DnsResolveContext.java:418) ~[netty-resolver-dns-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.resolver.dns.DnsResolveContext.onResponse(DnsResolveContext.java:629) ~[netty-resolver-dns-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.resolver.dns.DnsResolveContext.access$400(DnsResolveContext.java:66) ~[netty-resolver-dns-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.resolver.dns.DnsResolveContext$2.operationComplete(DnsResolveContext.java:462) ~[netty-resolver-dns-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:578) ~[netty-common-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.util.concurrent.DefaultPromise.notifyListeners0(DefaultPromise.java:571) ~[netty-common-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:550) ~[netty-common-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:491) ~[netty-common-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:616) ~[netty-common-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.util.concurrent.DefaultPromise.setSuccess0(DefaultPromise.java:605) ~[netty-common-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:104) ~[netty-common-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.resolver.dns.DnsQueryContext.trySuccess(DnsQueryContext.java:216) ~[netty-resolver-dns-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.resolver.dns.DnsQueryContext.finish(DnsQueryContext.java:208) ~[netty-resolver-dns-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.resolver.dns.DnsNameResolver$DnsResponseHandler.channelRead(DnsNameResolver.java:1314) ~[netty-resolver-dns-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103) ~[netty-codec-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[netty-transport-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[netty-transport-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.channel.nio.AbstractNioMessageChannel$NioMessageUnsafe.read(AbstractNioMessageChannel.java:97) ~[netty-transport-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:722) ~[netty-transport-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:658) ~[netty-transport-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:584) ~[netty-transport-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:496) ~[netty-transport-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:995) ~[netty-common-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.77.Final.jar:4.1.77.Final]
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.77.Final.jar:4.1.77.Final]
    at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]

订单服务调用库存服务

订单服务

应用程序.属性

spring.application.name=order-service


#MySQL DB
spring.datasource.url=jdbc:mysql://localhost:3306/order-service
spring.datasource.username=root
spring.datasource.password=Password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect

spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.sql.init.mode=always
spring.jpa.properties.hibernate.format_sql=true

server.port=8090

#Eureka
eureka.instance.prefer-ip-address=true
eureka.instance.hostname=localhost
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/

eureka.client.register-with-eureka=true
eureka.client.fetch-registry=true
spring.cloud.discovery.enabled=true

调用逻辑

private static final String INVENTORY_SERVICE_URI = "http://inventory-service/api/inventory";
public void placeOrder(OrderRequest orderRequest) {
        log.info("OrderService | placeOrder method called ");
        List<OrderLineItems> orderLineItems = orderRequest.getOrderLineItemsDtoList()
                .stream()
                .map(this::mapToDto)
                .collect(Collectors.toList());

        Order order = new Order();
        order.setOrderNumber(UUID.randomUUID().toString());
        order.setOrderLineItemsList(orderLineItems);


        List<String> skuCodes = order.getOrderLineItemsList()
                .stream()
                .map(orderLineItem -> orderLineItem.getSkuCode())
                .collect(Collectors.toList());

        // Call Inventory Service, and place order if product is in stock
        boolean allProductsInStock = webClient.get()
                .uri(INVENTORY_SERVICE_URI, uriBuilder -> uriBuilder.queryParam("skuCode", skuCodes).build())
                .retrieve()
                .bodyToMono(InventoryResponse[].class)
                .map(e -> Arrays.stream(e))
                .block()
                .allMatch(InventoryResponse::isInStock);

        if(allProductsInStock){
            orderRepository.save(order);
        } else {
            throw new IllegalArgumentException("Product is not in the stock, please try again later");
        }

    }

库存服务

应用程序.属性

spring.application.name=inventory-service

#MySQL DB
spring.datasource.url=jdbc:mysql://localhost:3306/inventory-service
spring.datasource.username=root
spring.datasource.password=Password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect

spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.sql.init.mode=always
spring.jpa.properties.hibernate.format_sql=true

server.port=0


#Eureka
eureka.instance.prefer-ip-address=true
eureka.instance.hostname=localhost
eureka.instance.instance-id=${spring.application.name}:${random.int}
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/

eureka.client.register-with-eureka=true
eureka.client.fetch-registry=true
spring.cloud.discovery.enabled=true

根据@Chetan建议的解决方案 - 如果我有多个库存服务实例,那么只有这个逻辑有效,它不适用于单个实例

java spring-boot microservices spring-cloud
4个回答
12
投票

要将

WebClient
与 Discovery 一起使用,请在配置中声明以下 bean。

    @Bean
    @LoadBalanced
    public WebClient.Builder loadBalancedWebClientBuilder() {
     return WebClient.builder();
    }

在调用其他服务的类中自动装配它,

    @Autowired
    private WebClient.Builder webClientBuilder;

并且,不要使用

webClient.get()
,而是使用
webClientBuilder.build().get()


0
投票

出于某种原因,我通过准确输入服务 url 默认区域来使其工作,如下所示:

eureka.client.service-url.defaultZone=http://localhost:8761/eureka/


0
投票

我遇到了同样的问题,现在已经解决了问题,我不在乎使用什么注册表以及是否使用网关服务。 例如: 发现:纳科斯 webflux:spring-boot-starter-webflux:5.3.25 春季启动:2.7.11 JDK:开放19 当我使用 WebClient 发出远程请求时 [在此输入图像描述][1] 我收到这个错误: [在此输入图像描述][2] 所以真正的问题是为什么无法通过服务器名称找到远程服务器。 客户端无法通过nacos实例信息进行负载均衡 所以我添加了一个新的依赖项

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-loadbalancer</artifactId>
  <version>3.1.6</version>
</dependency>

它将发挥作用。 [1]:https://i.stack.imgur.com/AEpf9.png [2]:https://i.stack.imgur.com/fxjXY.png


0
投票

在所有服务(Eureka 客户端)的 application.properties 文件中添加了以下行,包括发现服务(eureka 服务器)。

eureka.instance.prefer-ip-address=true

现在可以运行邮递员的请求并通过检查库存服务将订单值保存在数据库中

© www.soinside.com 2019 - 2024. All rights reserved.