我正在尝试使用 spring 注释@CircuitBreaker 来实现 resilience4j。我有 2 个微服务:订单服务和库存服务。订单服务在控制器中有一个 post 方法,它使用服务来调用库存。一切正常,直到我添加@CircuitBreaker 注释。当我添加它时,我在服务上得到一个 nullPointerException。
这是例外:
订单控制器:
@RestController
@RequestMapping("/api/order")
@RequiredArgsConstructor
public class OrderController {
private final OrderService orderService;
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
@CircuitBreaker(name = "inventory", fallbackMethod = "fallbackMethod")
private String placeOrder(@RequestBody OrderRequest orderRequest) {
orderService.placeOrder(orderRequest);
return "Order placed successfully!";
}
public String fallbackMethod(OrderRequest orderRequest, RuntimeException runtimeException) {
return "Oops! Something went wrong, please order after some time!";
}
}
<br/>
订单服务:
@Service
@RequiredArgsConstructor
@Transactional
public class OrderService {
private final OrderRepository orderRepository;
private final WebClient.Builder webClientBuilder;
public void placeOrder(OrderRequest orderRequest) {
Order order = new Order();
order.setOrderNumber(UUID.randomUUID().toString());
List<OrderLineItems> orderLineItems = orderRequest.getOrderLineItemsDtoList()
.stream()
.map(this::mapToDto)
.toList();
order.setOrderLineItemsList(orderLineItems);
List<String> skuCodes = order.getOrderLineItemsList().stream().map(OrderLineItems::getSkuCode).toList();
//Call inventory service and place order if product is in stock
InventoryResponse[] inventoryResponseArray = webClientBuilder.build().get()
.uri("http://inventory-service/api/inventory",
uriBuilder -> uriBuilder.queryParam("skuCode", skuCodes).build())
.retrieve()
.bodyToMono(InventoryResponse[].class)
.block();
boolean allProductsInStock = Arrays.stream(inventoryResponseArray).allMatch(InventoryResponse::isInStock);
if(allProductsInStock) {
orderRepository.save(order);
} else {
throw new IllegalArgumentException("Product is not in stock!");
}
}
private OrderLineItems mapToDto(OrderLineItemsDto orderLineItemsDto) {
OrderLineItems orderLineItems = new OrderLineItems();
orderLineItems.setPrice(orderLineItemsDto.getPrice());
orderLineItems.setQuantity(orderLineItemsDto.getQuantity());
orderLineItems.setSkuCode(orderLineItemsDto.getSkuCode());
return orderLineItems;
}
}
spring.datasource.url=jdbc:postgresql://localhost:5432/order-service
spring.datasource.username=postgres
spring.datasource.password=admin
spring.jpa.hibernate.ddl-auto=create
server.port=8081
eureka.client.serviceUrl.defaultZone=http://eureka:password@localhost:8761/eureka
spring.application.name=order-service
management.health.circuitbreakers.enabled=true
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always
#Resilience4j Properties
resilience4j.circuitbreaker.instances.inventory.registerHealthIndicator=true
resilience4j.circuitbreaker.instances.inventory.event-consumer-buffer-size=10
resilience4j.circuitbreaker.instances.inventory.slidingWindowType=COUNT_BASED
resilience4j.circuitbreaker.instances.inventory.slidingWindowSize=5
resilience4j.circuitbreaker.instances.inventory.failureRateThreshold=50
resilience4j.circuitbreaker.instances.inventory.waitDurationInOpenState=5s
resilience4j.circuitbreaker.instances.inventory.permittedNumberOfCallsInHalfOpenState=3
resilience4j.circuitbreaker.instances.inventory.automaticTransitionFromOpenToHalfOpenEnabled=true
我尝试将 resilience4j 与 spring 注释 @CircuitBreaker 一起使用,但它没有正常工作,而是使我的 spring 上下文不加载我的服务 bean。