JAVA和Nginx 教程大全

网站首页 > 精选教程 正文

服务兜底方案之:服务降级和熔断实现

wys521 2024-11-17 16:59:14 精选教程 19 ℃ 0 评论
原创不易,请多多支持!对Java技术感兴趣的童鞋请关注我,后续技术分享更精彩。

背景

电商应用中的核心服务,如加购物车,订单支付等,直接关系公司收入来源。这些服务的稳定可靠,持续可用是系统建设的重中之重。如何减小核心流程服务出问题的概率?甚至当出现故障时,自动由兜底方案接管,最大限度的降低公司成本损失。解决这类问题,服务的降级/熔断就再适合不过了。

概念

当一个服务的使用范围和频度被无限放大时,不出问题的概率几乎为0。所以,在系统服务层面,我们都可以认为它是不可靠的。服务本身不可靠,业务上却要求它稳定可靠,这本身就存在矛盾。世界不存在完美的事物,理论上要做到这个完美虽无法实现,但我们可以通过A/B方案服务实现,降低这个概率。当A方案出故障时,B方案自动接管。A和B方案同时出现问题的概率相对较小,从而变相的减少损失。

服务降级:当服务A出现故障时,服务自动降级为服务B处理。服务B作为服务A出问题时的兜底方案。如短信服务,系统A方案使用电信的短信服务。当A方案的短信服务有问题时(网络不稳定、被临时工不小心挖断线路),服务自动尝试B方案的联通服务来收发短信。通过两套方案的综合使用来保证服务的稳定,持续可用。

服务熔断:服务熔断决定了服务的降级处理行为。一般来说,服务的A/B方案,A方案为主要方案、优选方案,B方案为次要方案、兜底方案。A方案故障有可能是临时的,问题出现后迅速就恢复了。比如网络抖动,几秒后网络就好了。这种情况下,我们希望更好的A方案仍能对外提供服务。所以,这里的服务熔断,就决定了当前的A方案是临时故障,还是非临时故障。若为非临时故障,服务短期内不能恢复,即触发了服务熔断操作,备选方案B开始接管服务。服务熔断期间,方案B升级为主要服务,直到服务A恢复后,方案B再调整为次要服务。

服务降级和服务熔断的区别,在于服务熔断触发前后,A/B方案的服务提供行为。服务降级始终是先尝试A服务,A不可用,再使用B兜底。服务熔断后,系统很明确知道A方案不可用,短期不能迅速恢复,这时B服务接管,接管后的请求都是B直接提供服务。

设计

使用hystrix服务熔断降级开源方案实现。

核心服务均需采用A/B(主备)两套方案,防止某套服务故障导致整体服务不可用。如上图,当Service B出故障时,通过Fallback兜底服务自动接管,统一对外提供服务。对调用端而言完全透明,就好像完全未发生故障一样。

集成

添加依赖

<dependency>
 <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

添加注解熔断开关

@EnableCircuitBreaker // 打开熔断开关
@EnableScheduling
@SpringBootApplication
@Slf4j
@RestController
public class Application implements ApplicationContextAware{
 // business logic code...
}

添加熔断配置

springboot 配置yml添加以下配置

# 熔断/降级配置 https://github.com/Netflix/Hystrix/wiki/Configuration
hystrix:
 command:
 default: #全局配置
 circuitBreaker: # 默认熔断器设置
 requestVolumeThreshold: 10 #至少有10个请求,熔断器才进行错误率的计算
 sleepWindowInMilliseconds: 10000 # 熔断器中断请求10秒后会进入半打开状态,放部分流量过去重试
 errorThresholdPercentage: 10 #错误率达到10%开启熔断保护
 execution:
 isolation:
 strategy: SEMAPHORE # 程序执行隔离策略 - 信号量。 可选值:THREAD, SEMAPHORE
 semaphore:
 maxConcurrentRequests: 20 # 最大并发访问数 默认10
 thread:
 timeoutInMilliseconds: 60000 # 默认1000 谨慎设置该值. execution.timeout.enabled=true时才生效
 timeout:
 enabled: false # 程序是否开启超时机制
 default: #全局配置
 circuitBreaker: # 默认熔断器设置
 requestVolumeThreshold: 10 #至少有10个请求,熔断器才进行错误率的计算
 sleepWindowInMilliseconds: 10000 # 熔断器中断请求10秒后会进入半打开状态,放部分流量过去重试
 errorThresholdPercentage: 10 #错误率达到10%开启熔断保护

添加熔断代码注解

@RestController
@Slf4j
public class SmsResource{
// 添加服务降级注解配置。 配置降级分组groupKey,降级commandKey,降级方法fallbackMethod注解设置。
// 短信发送A方案
@HystrixCommand(fallbackMethod = "sendSmsFailback",groupKey = "SmsResource",commandKey = "sendSms")
@Override
public ResponseResult sendSms(@RequestBody RequestParam requestParam) {
 //todo: 短信发送业务逻辑
}
 
//降级方法逻辑实现: 短信发送B方案
public ResponseResult sendSmsFailback(@RequestBody RequestParam requestParam){
 //todo: 短信发送业务逻辑
}
 }

hystrix属性配置动态监控

添加依赖

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

添加bean配置

@Bean
public ServletRegistrationBean getServlet() {
 HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
 ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
 registrationBean.setLoadOnStartup(1);
 registrationBean.addUrlMappings("/hystrix.stream");
 registrationBean.setName("HystrixMetricsStreamServlet");
 return registrationBean;
}

配置监控


启动服务后,浏览器访问请求地址。http://{域名}/hystrix.stream

注意:hystrix command属性设置是懒加载模式。必须至少访问一次配置熔断/降级接口后才有监控数据。

总结

本文介绍了核心服务的稳定可靠实现方案,服务的降级/熔断开源hystrix实现。即通过A/B两套方案的冗余实现,减少故障发生的概率,以达到服务长期可用,降低成本损失的目的。

hystrix天生与springboot项目融合,简单通过springboot yml文件即可实现服务监控配置。在服务业务中通过注解标记,便能很快实现A/B服务方案的整合。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表