弹簧引导弹性4j断路器和回退未执行



我有一个带有Resilience4j实现的简单rest api,但由于某种原因,断路器或回退实现无法工作。我不确定我是否使用了正确的依赖关系。我有一个简单的成员信息api,它使用另一个名为benefitApi的api。我已经实现了福利api调用的断路器和创建超时异常的逻辑。当它运行时,它仍然等待超时,然后抛出TimeOutException。看起来我的断路器没有被执行。这是我的代码:

build.gradle

plugins {
id 'org.springframework.boot' version '2.7.2'
id 'io.spring.dependency-management' version '1.0.12.RELEASE'
id 'java'
}
group = 'com.thomsoncodes'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
mavenCentral()
}
ext {
set('springCloudVersion', "2021.0.3")
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.springframework.cloud:spring-cloud-starter-circuitbreaker-reactor-resilience4j'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.projectreactor:reactor-test'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
tasks.named('test') {
useJUnitPlatform()
}

控制器类

@RestController
public class WebController {
public static final Logger LOG = LoggerFactory.getLogger(WebController.class);
@Autowired
private MemberInfoService memberInfoService;

@GetMapping("member/{memId}")
public ResponseEntity<MemberInfo> memberInfo(@PathVariable("memId") String memId) throws TimeoutException { 
LOG.info("---Beginning of the WebController.methodmemberInfo()---");
MemberInfo resp = null;
resp = memberInfoService.getMemberInfo(memId);

LOG.info("---End of the WebController.methodmemberInfo()---");
return new ResponseEntity<MemberInfo>(resp, (HttpStatus.OK));
}
}

MemberInfoService.java

@Service
public class MemberInfoService {
public static final Logger LOG = LoggerFactory.getLogger(MemberInfoService.class);

@Autowired
private UserInfoService userInfoService;

@Autowired
private BenefitService benefitService;
public MemberInfo getMemberInfo(String memId) throws TimeoutException {
LOG.info("---End of the WebController.MemberInfoService()---");

MemberInfo memberInfo = null;
memberInfo = userInfoService.getUserInfo(memId);
Benefit benefit = null;
benefit = benefitService.getBenefitInfo(memId);
memberInfo.setBenefit(benefit);

LOG.info("---End of the WebController.MemberInfoService()---");
return memberInfo;
}
}

BenefitService.java

@Service
public class BenefitService {
public static final Logger LOG = LoggerFactory.getLogger(BenefitService.class);
@Autowired
private WebClient benefitApiClient;

@CircuitBreaker(name = "benefitService", fallbackMethod = "buildFallbackBenefitInfo")
@RateLimiter(name = "benefitService", fallbackMethod = "buildFallbackBenefitInfo")
@Retry(name = "retryBenefitService", fallbackMethod = "buildFallbackBenefitInfo")
public Benefit getBenefitInfo(String memId) throws TimeoutException {
LOG.info("---Beginning of the BenefitService.getBenefitInfo()---");
randomlyRunLong();
return benefitApiClient.get()
.uri("/member/benefit/" + memId)
.retrieve()
.bodyToMono(Benefit.class)
.block();
}

public Benefit buildFallbackBenefitInfo(String memId, Throwable t) throws TimeoutException {
Benefit benefit = null;
benefit = new Benefit();
benefit.setBenefitId("00000");
benefit.setMemeberId("00000");

return benefit;
}


private void randomlyRunLong() throws TimeoutException{
Random rand = new Random();
int randomNum = rand.nextInt((3 - 1) + 1) + 1;
if (randomNum==3) sleep();
}
private void sleep() throws TimeoutException{
try {
System.out.println("Sleep");
Thread.sleep(5000);
throw new java.util.concurrent.TimeoutException();
} catch (InterruptedException e) {
LOG.error(e.getMessage());
}
}       
}

application.yml

server:
port: 9095
management.endpoints.enabled-by-default: false
management.endpoint.health:
enabled: true
show-details: always

resilience4j.circuitbreaker:
instances:
benefitService:
registerHealthIndicator: true
ringBufferSizeInClosedState: 5
ringBufferSizeInHalfOpenState: 3
waitDurationInOpenState: 10s
failureRateThreshold: 50
recordExceptions:
- org.springframework.web.client.HttpServerErrorException
- java.io.IOException
- java.util.concurrent.TimeoutException
- org.springframework.web.client.ResourceAccessException
resilience4j.ratelimiter:
instances:
benefitService:
limitForPeriod: 5
limitRefreshPeriod: 5000
timeoutDuration: 1000ms
resilience4j.retry:
instances:
retryBenefitService:
maxRetryAttempts: 5
waitDuration: 10000
retry-exceptions:
- java.util.concurrent.TimeoutException
resilience4j.bulkhead:
instances:
bulkheadBenefitService:
maxWaitDuration: 2ms
maxConcurrentCalls: 20

resilience4j.thread-pool-bulkhead:
instances:
bulkheadBenefitService:
maxThreadPoolSize: 1
coreThreadPoolSize: 1
queueCapacity: 1

我不知道我在这里做错了什么。如果能提供帮助,我们将不胜感激。提前感谢

默认的Resilience4j方面顺序是

Retry( CircuitBreaker( RateLimiter( TimeLimiter( Bulkhead( function)))))

您的RateLimit有一个回退,因此它从不抛出异常,因此CircuitBreaker从不看到失败的调用。仅对将执行的最后一个方面指定回退。

相关内容

  • 没有找到相关文章

最新更新