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
相关产品推荐
相关产品推荐

