Мой класс контроллера:
Код: Выделить всё
@RestController
@RequestMapping("v1/profileinfo")
public class WebController {
public static final Logger LOG = LoggerFactory.getLogger(WebController.class);
@Autowired
private CircuitBreakerRegistry circuitBreakerRegistry;
@Autowired
private AppConstants appConstants;
@Autowired
private ProfileService profileService;
@GetMapping("/{profId}")
public ResponseEntity
getProfileInfo(@PathVariable("profId") Long profId){
ProfielInfo resp = null;
resp = profileService.getProfileInfo(profId);
return new ResponseEntity(resp, HttpStatus.OK);
}
@PutMapping("circuitbreaker/{state}")
public String setCircuitBreaker(@PathVariable("state") String state) {
if(state.toUpperCase().equals(appConstants.CB_CLOSED)) {
circuitBreakerRegistry.circuitBreaker("benefitService").transitionToClosedState();
}
if(state.toUpperCase().equals(appConstants.CB_OPEN)) {
circuitBreakerRegistry.circuitBreaker("benefitService").transitionToForcedOpenState();
}
return state;
}
}
Код: Выделить всё
....
import java.util.concurrent.TimeoutException;
import java.util.function.Supplier;
import io.github.resilience4j.circuitbreaker.CallNotPermittedException;
import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
import io.github.resilience4j.decorators.Decorators;
@Service
public class ProfileService {
public static final Logger LOG = LoggerFactory.getLogger(ProfileService.class);
@Autowired
private CircuitBreakerConfig circuitBreakerConfig; //ADDED
@Autowired
private CircuitBreakerRegistry circuitBreakerRegistry; //ADDED
@Autowired
private UserInfoService userInfoService;
@Autowired
private BenefitService benefitService;
public ProfielInfo getProfileInfo(Long profId) throws TimeoutException {
CircuitBreaker circuitBreaker = circuitBreakerRegistry
.circuitBreaker("benefitService");
ProfielInfo profileInfo = null;
profileInfo = new ProfielInfo();
UserInfo userInfo = null;
userInfo = userInfoService.getUserInfo(profId);
Benefit benefit = null;
Supplier supplier = () -> benefitService.getBenefitInfo(profId);
LOG.info("||||Calling benefitService...");
benefit = Decorators.ofSupplier(supplier)
.withCircuitBreaker(circuitBreaker) //---> Why it's not Working here ??
.withFallback(e -> buildFallbackBenefitInfo(profId))
.get();
profileInfo.setUserInfo(userInfo);
profileInfo.setBenefit(benefit);
LOG.info("---End of the ProfileService.getProfileInfo()---");
return profileInfo;
}
public Benefit buildFallbackBenefitInfo(Long memId) {
Benefit benefit = null;
benefit = new Benefit();
benefit.setBenefitId("00000");
benefit.setMemeberId("00000");
return benefit;
}
}
Код: Выделить всё
@Service
public class BenefitService {
@Autowired
private CircuitBreakerRegistry circuitBreakerRegistry;
@Autowired
private WebClient benefitApiClient;
public Benefit getBenefitInfo(long profId) {
CircuitBreaker circuitBreaker = circuitBreakerRegistry
.circuitBreaker("benefitService");
return benefitApiClient.get()
.uri("/" + profId)
.retrieve()
.bodyToMono(Benefit.class)
.timeout(Duration.ofSeconds(3))
.transformDeferred(CircuitBreakerOperator.of(circuitBreaker)) // works here
.block();
}
}
Код: Выделить всё
@Configuration
public class CircuitBreakerConfigs {
@Value("${circuitbreaker.failureRateThreshold}")
private int failureRateThreshold;
@Value("${circuitbreaker.slowCallRateThreshold}")
private int slowCallRateThreshold;
@Value("${circuitbreaker.waitDurationInOpenState}")
private int waitDurationInOpenState;
@Value("${circuitbreaker.slowCallDurationThreshold}")
private int slowCallDurationThreshold;
@Value("${circuitbreaker.permittedNumberOfCallsInHalfOpenState}")
private int permittedNumHalfOpenState;
@Value("${circuitbreaker.minimumNumberOfCalls}")
private int minimumNumberOfCalls;
@Value("${circuitbreaker.slidingWindowSize}")
private int slidingWindowSize;
@Bean
public CircuitBreakerConfig circuitBreakerConfig() {
return CircuitBreakerConfig.custom()
.failureRateThreshold(failureRateThreshold)
.slowCallRateThreshold(slowCallRateThreshold)
.waitDurationInOpenState(Duration.ofSeconds(waitDurationInOpenState))
.slowCallDurationThreshold(Duration.ofSeconds(slowCallDurationThreshold))
.permittedNumberOfCallsInHalfOpenState(permittedNumHalfOpenState)
.minimumNumberOfCalls(minimumNumberOfCalls)
.slidingWindowType(SlidingWindowType.COUNT_BASED)
.slidingWindowSize(slidingWindowSize)
.enableAutomaticTransitionFromOpenToHalfOpen()
.recordExceptions(IOException.class, TimeoutException.class)
.build();
}
@Bean
public CircuitBreakerRegistry circuitBreakerRegistry() {
return CircuitBreakerRegistry.of(circuitBreakerConfig());
}
}
Код: Выделить всё
server:
port: 9099
management:
endpoints:
web:
exposure:
include: "*"
resilience4j.circuitbreaker:
configs:
default:
registerHealthIndicator: true
circuitbreaker:
failureRateThreshold: 50
slowCallRateThreshold: 50
waitDurationInOpenState: 60
slowCallDurationThreshold: 60
minimumNumberOfCalls: 1
permittedNumberOfCallsInHalfOpenState: 3
slidingWindowSize: 5
Код: Выделить всё
plugins {
id 'org.springframework.boot' version '2.7.3'
id 'io.spring.dependency-management' version '1.0.13.RELEASE'
id 'java'
}
group = 'com.demo.ref'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-webflux'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.projectreactor:reactor-test'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-aop', version: '2.7.2'
implementation group: 'io.github.resilience4j', name: 'resilience4j-spring-boot2', version: '1.5.0'
implementation group: 'io.github.resilience4j', name: 'resilience4j-reactor', version: '1.5.0'
implementation group: 'io.github.resilience4j', name: 'resilience4j-all', version: '1.5.0'
implementation group: 'io.micrometer', name: 'micrometer-registry-prometheus', version: '1.9.3'
}
tasks.named('test') {
useJUnitPlatform()
}
Подробнее здесь: https://stackoverflow.com/questions/734 ... decorators