You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot微服务调用报错:WebClientRequestException连接被拒绝

订单服务调用库存服务时连接被拒绝问题排查

我基于Spring Boot构建微服务,需实现订单服务与库存服务的通信。但使用WebClient的GET方法从订单服务调用库存服务时,始终返回以下错误:

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.web.reactive.function.client.WebClientRequestException: Connection refused: no further information: localhost/192.168.1.1:8080] with root cause

已尝试关闭防火墙、配置防火墙允许TCP响应数据等操作,问题仍未解决。相关代码如下:

订单服务核心代码

OrderManager.java

@Service
@AllArgsConstructor
@Transactional
public class OrderManager implements OrderService {
    private OrderRepository orderRepository;
    private ModelMapperService modelMapperService;
    private WebClient webClient;
    
    @Override
    public void placeOrder(OrderRequest orderRequest) {
      Order order = new Order();
      order.setOrderNumber(UUID.randomUUID().toString());
      List<OrderLineItems> orderLineItemsList= orderRequest.getOrderLineItemsResponseList().stream()
                .map(orders -> this.modelMapperService.forResponse().map(orders, OrderLineItems.class)).collect(Collectors.toList());
      order.setOrderLineItemsList(orderLineItemsList);

      List<String> skuCodes =  order.getOrderLineItemsList().stream()
             .map(OrderLineItems::getSkuCode)
                .toList();

        InventoryResponse[] inventoryResponsesArray =  this.webClient.get()
        .uri("http://localhost:8080/api/v1/inventory", uriBuilder -> uriBuilder.queryParam("skuCode",skuCodes).build())
                .retrieve()
                .bodyToMono(InventoryResponse[].class)
                .block();

        boolean allProductIsInStock = Arrays.stream(inventoryResponsesArray)
                .allMatch(InventoryResponse::isInStock);
      if ( allProductIsInStock){
          this.orderRepository.save(order);
      }
      else {
          throw new IllegalArgumentException("Product is not in stock");
      }
    }
}

OrderController.java

@RestController
@RequestMapping("/api/v1/order")
@AllArgsConstructor
public class OrderController {
    private OrderService orderService;

    @PostMapping()
    @ResponseStatus(HttpStatus.CREATED)
    public String placeOrder(@RequestBody OrderRequest orderRequest){
       this.orderService.placeOrder(orderRequest);
        return "Order Placed Successfully";
    }
}

库存服务核心代码

InventoryManager.java

@Service
@AllArgsConstructor
public class InventoryManager implements InventoryService {

    private final InventoryRepository inventoryRepository;
    
    @Override
    @Transactional(readOnly = true)
    public List<InventoryResponse> isInStock(List<String> skuCode) {
      return  inventoryRepository.findBySkuCodeIn(skuCode).stream()
              .map(inventory ->
                      InventoryResponse.builder()
                      .skuCode(inventory.getSkuCode())
                      .isInStock(inventory.getQuantity()> 0)
                      .build()
              ).toList();
    }
}

InventoryController.java

@RestController
@RequestMapping("/api/v1/inventory")
@AllArgsConstructor
public class InventoryController {

    private final InventoryService inventoryService;
    
    @GetMapping()
    @ResponseStatus(HttpStatus.OK)
    public List<InventoryResponse> isInStock(@RequestParam() List<String> skuCode){
        return this.inventoryService.isInStock(skuCode);
    }
    
    @GetMapping("/gets")
    public List<Inventory> gets(){
        return this.inventoryService.find();
    }
}

问题排查与解决方案

1. 库存服务状态与端口校验

  • 确认库存服务是否正常启动,且监听端口为8080。若库存服务使用其他端口(如8081),需同步修改WebClient请求URI中的端口号。
  • 手动访问http://localhost:8080/api/v1/inventory/gets,验证库存服务是否能正常响应请求。

2. WebClient配置优化

  • 检查WebClient Bean是否正确配置,建议手动指定基础URL避免拼接错误:
    @Bean
    public WebClient webClient() {
        return WebClient.builder()
                .baseUrl("http://localhost:8080") // 与库存服务端口保持一致
                .build();
    }
    
  • 简化URI构建逻辑,减少拼接错误:
    InventoryResponse[] inventoryResponsesArray = this.webClient.get()
            .uri(uriBuilder -> uriBuilder.path("/api/v1/inventory")
                    .queryParam("skuCode", skuCodes)
                    .build())
            .retrieve()
            .bodyToMono(InventoryResponse[].class)
            .block();
    

3. 网络绑定配置调整

  • 错误信息显示绑定地址为localhost/192.168.1.1:8080,需确保库存服务监听所有网络接口。修改库存服务的application.properties:
    server.address=0.0.0.0
    server.port=8080
    

4. 请求参数与日志校验

  • 在库存服务的isInStock方法中添加日志,打印接收到的skuCode参数,确认参数是否正确传递。
  • 检查订单服务中skuCodes列表是否为空,避免空参数导致的异常。

5. 非阻塞调用改造(可选)

  • 目前使用block()会阻塞线程,不符合Reactive编程规范,建议改为非阻塞实现:
    @Override
    public Mono<Void> placeOrder(OrderRequest orderRequest) {
        // 订单对象构建逻辑不变
        List<String> skuCodes = order.getOrderLineItemsList().stream()
                .map(OrderLineItems::getSkuCode)
                .toList();
    
        return webClient.get()
                .uri(uriBuilder -> uriBuilder.path("/api/v1/inventory")
                        .queryParam("skuCode", skuCodes)
                        .build())
                .retrieve()
                .bodyToFlux(InventoryResponse.class)
                .allMatch(InventoryResponse::isInStock)
                .flatMap(allInStock -> {
                    if (allInStock) {
                        return orderRepository.save(order).then();
                    } else {
                        return Mono.error(new IllegalArgumentException("Product is not in stock"));
                    }
                });
    }
    
  • 同步修改Controller返回类型为Mono<String>:
    @PostMapping()
    @ResponseStatus(HttpStatus.CREATED)
    public Mono<String> placeOrder(@RequestBody OrderRequest orderRequest){
       return orderService.placeOrder(orderRequest)
               .thenReturn("Order Placed Successfully");
    }
    

内容的提问来源于stack exchange,提问作者Hakan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 00:11:09