案例回放
- 用戶登錄全部流量接入極驗校驗後,導致請求到第三方極驗公司那邊個別請求很慢
- 與第三方公司定位後,還是存在問題(有所好轉,但不明顯)
- 考慮到不能完全依靠第三方處理,可以通過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);
}
- 這樣就完全滿足我們的需求了。各個業務都調用正常,個別服務調用調用超時也不影響其他服務調用
參考文章