案例回放
- 用户登录全部流量接入极验校验后,导致请求到第三方极验公司那边个别请求很慢
- 与第三方公司定位后,还是存在问题(有所好转,但不明显)
- 考虑到不能完全依靠第三方处理,可以通过Dubbo线程池处理
- 个别服务慢,导致占用线程池瞬间上升,其他服务调用也越来越慢,影响整体可用性
增加线程池大小,设置为可伸缩线程池
- 线程模型参考官网介绍
- 配置示例如下
- dubbo默认将所有消息都派发到线程池,并且是固定200个线程
- 考虑到当前应用流量大 这里配置500,并且是可伸缩的
# 这里可以用配置name 是为了后续配置多个线程池组使用的
<dubbo:protocol id="dubbo" name="dubbo" port="21888" threadpool="limited" threads="500" queues="0"/>
- 上线后,还是存在问题,只是出现问题的时间离应用部署时间更久一点而已
- 接下来尝试配置多个线程池处理
配置多个Dubbo线程池
- 配置多个线程池(dubbo-common.xml)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<dubbo:protocol id="dubbo" name="dubbo" port="21888" threadpool="limited" threads="500" queues="0"/>
<!-- http调用极验服务存在超时情况 则将请求延迟服务单独出来 单独配置线程池规则 -->
<dubbo:protocol id="captcha" name="dubbo" port="21889" dispatcher="message" threadpool="fixed"
threads="${captcha.threads:100}"/>
</beans>
- 考虑到线上可能存在线程不够用,此处设置为配动态配置的(但是需要重启应用才能生效)
- 在启动类中引入dubbo-comm.xml即可
@SpringBootApplication
@ImportResource(locations = {"classpath:/dubbo-common.xml"})
public class UserApplication {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(UserApplication.class);
springApplication.run(args);
}
}
@com.alibaba.dubbo.config.annotation.Service(protocol = {"captcha"}, timeout = 2000)
public class CaptchaServiceImple {}
- 上线后问题还是存在,只是没这么频繁
- 之前看SpringCloud书籍,看可以通过Hystrix解决
- 然后网上一搜,阿里也出了一个,而且控制的更细
- Hystrix与Sentinel区别
使用Sentinel
@Configuration
public class SentinelConfig {
@Autowired
private AutoLimitService autoLimitService;
@Bean
public SentinelResourceAspect sentinelResourceAspect() {
return new SentinelResourceAspect();
}
@PostConstruct
public void initDegradeRule() {
List<DegradeRule> rules = Lists.newArrayList();
List<String> resList = Lists.newArrayList("captcha");
DegradeRule rule;
for (String resource : resList) {
rule = new DegradeRule();
rule.setResource(resource);
rule.setGrade(RuleConstant.DEGRADE_GRADE_RT);
rule.setCount(autoLimitService.getSentinelServiceInvokeTimeoutCaptcha());
rule.setTimeWindow(autoLimitService.getSentinelTimeWindowCaptcha());
rules.add(rule);
}
DegradeRuleManager.loadRules(rules);
}
}
@SentinelResource(value = "captcha", fallback = "needCaptchaFallback")
@Override
public Result<***Out> needCaptcha(Request<***In> request) {
}
- 并且同时定义一个方法(方法名为上面fallback定义名称,入参和出参相同,是不是和Hystrix很像呀)
public Result<***Out> needCaptchaFallback(Request<***In> request) {
return ResultUtils.commonServiceTimeOut("captcha needCaptchaFallback", request);
}
- 这样就完全满足我们的需求了。各个业务都调用正常,个别服务调用调用超时也不影响其他服务调用
参考文章