踩坑Resilience4j @Bulkhead

先说问题情况

系统环境

  1. java version: 17
  2. spring boot: 3.x
  3. spring cloud: 4.x

项目配置和代码

项目中使用了Spring Cloud Circuit Breaker

<dependency>
    <groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
</dependency>

在代码里面使用了@Bulkhead避免远程服务出现问题或者性能低下时蔓延到当前服务导致当前服务出现资源耗尽。黑话就是解决爆炸半径问题。

@CircuitBreaker(name = "licenseService", fallbackMethod = "buildFallbackLicenseList")
@Bulkhead(name = "bulkheadLicenseService", fallbackMethod = "buildFallbackLicenseList")
public List<License> getLicensesByOrganization(String organizationId) {
    LOGGER.info("find all licenses belong to {}", organizationId);
    LicenseExample example = new LicenseExample();
    example.createCriteria().andOrganizationIdEqualTo(organizationId);
    return licenseMapper.selectByExample(example);
}

当我们运行调试业务时发现@Bulkhead未生效, 代码也没报错,通过日志信息发现线程依然是tomcat的线程。另外从prometheus 指标也能反映@Bulkhead未生效。
查看文档,我在Bulkhead pattern supporting里面发现需要io.github.resilience4j:resilience4j-bulkhead,查看maven 依赖树确实没有io.github.resilience4j:resilience4j-bulkhead,好吧我把它加到pom.xml

<dependency>
	<groupId>io.github.resilience4j</groupId>
	<artifactId>resilience4j-bulkhead</artifactId>
</dependency>

重新启动项目,测试发现问题依然没变
在这里插入图片描述
经过一番查找发现缺少org.aspectj:aspectjweaver,so在pom.xml中加入

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

why?

debug调试

解决问题后,回过头去分析为什么会应为没有org.aspectj:aspectjweaver@Bulkhead就不生效
io.github.resilience4j.springboot3.bulkhead.autoconfigure.AbstractBulkheadConfigurationOnMissingBean发现了问题

@Bean
@Conditional(value = {AspectJOnClasspathCondition.class})
@ConditionalOnMissingBean
public BulkheadAspect bulkheadAspect(
    BulkheadConfigurationProperties bulkheadConfigurationProperties,
    ThreadPoolBulkheadRegistry threadPoolBulkheadRegistry,
    BulkheadRegistry bulkheadRegistry,
    @Autowired(required = false) List<BulkheadAspectExt> bulkHeadAspectExtList,
    FallbackExecutor fallbackExecutor,
    SpelResolver spelResolver) {
    return bulkheadConfiguration
        .bulkheadAspect(bulkheadConfigurationProperties, threadPoolBulkheadRegistry,
            bulkheadRegistry, bulkHeadAspectExtList, fallbackExecutor, spelResolver);
}

要创建BulkheadAspect 需要经过AspectJOnClasspathCondition条件判断,我们经入AspectJOnClasspathCondition看看是怎么判断的

package io.github.resilience4j.spring6.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class AspectJOnClasspathCondition implements Condition {

    private static final Logger logger = LoggerFactory.getLogger(AspectJOnClasspathCondition.class);
    private static final String CLASS_TO_CHECK = "org.aspectj.lang.ProceedingJoinPoint";

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return AspectUtil.checkClassIfFound(context, CLASS_TO_CHECK, (e) -> logger
            .debug("Aspects are not activated because AspectJ is not on the classpath."));
    }

}

AspectJOnClasspathCondition会检测org.aspectj.lang.ProceedingJoinPoint是否出现在classpath中。
本地调试我们调整日志level就可以看到debug提示

2024-09-30T12:14:04.950+08:00 DEBUG 10525 --- [licensing-service] [           main] i.g.r.s.u.AspectJOnClasspathCondition    : Aspects are not activated because AspectJ is not on the classpath.
2024-09-30T12:14:04.951+08:00 DEBUG 10525 --- [licensing-service] [           main] i.g.r.s.u.AspectJOnClasspathCondition    : Aspects are not activated because AspectJ is not on the classpath.

ok到这里原因就一目了然了。当然文档写的不沟详细也是导致出现这个问题的原因。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值