SpringCloud系列笔记总目录:Spring Cloud 学习笔记
一句话:服务熔断是应对系统服务雪崩
的一种保险措施,给出的一种特殊降级措施(服务熔断是服务降级的一种特殊情况
)。而服务降级则是更加宽泛的概念,主要是对系统整体资源的合理分配以应对压力。
默认熔断机制
:当对某个服务的调用在一定的窗口期
内(默认 10s),有超过一定次数(默认 20 次)并且失败率
超过一定值(默认 50%),该服务的断路器会打开。返回一个由开发者设定的 fallback。当一个窗口期过去的时候,断路器将变成半开(HALF-OPEN)
状态,如果这时候发生的请求正常,则关闭,否则又打开Sentinel
比Hystrix更好用,所以实际开发中一般不再使用Hystrix,但二者的基本思想大同小异<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-hystrixartifactId>
dependency>
@EnableHystrix
//此注解包含了@EnableCircuitBreaker
@HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties = {
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="5000")
})//表示执行时间超过5s则会降级,执行paymentInfo_TimeOutHandler方法
public String paymentInfo_TimeOut(Integer id) {
//int age = 10/0;//异常和超时都会造成降级
try { TimeUnit.MILLISECONDS.sleep(1500); } catch (InterruptedException e) { e.printStackTrace(); }
return "线程池: "+Thread.currentThread().getName()+" id: "+id+"\t"+"O(∩_∩)O哈哈~"+" 耗时(秒): ";
}
@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod")
,其中payment_Global_FallbackMethod就是通用的降级策略,同时在需要降级的方法上加@HystrixCommand
@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT" , fallback = PaymentFallbackService.class)//注意这里要配置降级策略所在的类
public interface PaymentHystrixService
{
@GetMapping("/payment/hystrix/ok/{id}")
public String paymentInfo_OK(@PathVariable("id") Integer id);
@GetMapping("/payment/hystrix/timeout/{id}")
public String paymentInfo_TimeOut(@PathVariable("id") Integer id);
}
@Component
public class PaymentFallbackService implements PaymentHystrixService
{
@Override
public String paymentInfo_OK(Integer id) {
return "-----PaymentFallbackService fall back-paymentInfo_OK ,o(╥﹏╥)o";
}
@Override
public String paymentInfo_TimeOut(Integer id) {
return "-----PaymentFallbackService fall back-paymentInfo_TimeOut ,o(╥﹏╥)o";
}
}
#ribbon:
# #指的是建立连接后从服务器读取到可用资源所用的时间
# ReadTimeout: 5000
# #指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
# ConnectTimeout: 5000
hystrix:
command:
default:
execution:
timeout:
enabled: true
isolation:
thread:
timeoutInMilliseconds: 5000
feign:
client:
config:
default:
connectTimeout: 5000 # 由于ribbon配置无效,改用feign的配置
readTimeout: 5000
hystrix:
enabled: true # 开启feign对hystrix的支持
@HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback",commandProperties = {
@HystrixProperty(name = "circuitBreaker.enabled",value = "true"),// 是否开启断路器
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),// 请求次数
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"), // 时间窗口期
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60"),// 失败率达到多少后跳闸
})
public String paymentCircuitBreaker(@PathVariable("id") Integer id) {
if(id < 0) {
throw new RuntimeException("******id 不能负数");
}
String serialNumber = IdUtil.simpleUUID();
return Thread.currentThread().getName()+"\t"+"调用成功,流水号: " + serialNumber;
}
public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id) {
return "id 不能负数,请稍后再试,/(ㄒoㄒ)/~~ id: " +id;
}
以下三个重要的指标参数(是写在 @HystrixProperty
中,实际项目中也可全局配置
在 yml 或 properties 中)
窗口期
。可以理解为一个触发断路器的周期时间值,默认为 10 秒(10000)。请求阈值
,默认为 20。换句话说,假如某个窗口期内的请求总数都不到该配置值,那么断路器连发生的资格都没有
。断路器在该窗口期内将不会被打开。错误百分比阈值
,默认为 50(也就是说默认容忍 50% 的错误率)。打个比方,假如一个窗口期内,发生了 100 次服务请求,其中 50 次出现了错误。在这样的情况下,断路器将会被打开。在该窗口期结束之前,即使第 51 次请求没有发生异常,也将被执行 fallback 逻辑。<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboardartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
@SpringBootApplication
@EnableHystrixDashboard//服务启动后访问http://localhost:9001/hystrix
public class HystrixDashboardMain9001
{
public static void main(String[] args) {
SpringApplication.run(HystrixDashboardMain9001.class, args);
}
}
被监控的服务
启动类要配置一个servlet:@SpringBootApplication
@EnableEurekaClient
@EnableHystrix//此注解包含了@EnableCircuitBreaker
public class PaymentHystrixMain8001
{
public static void main(String[] args) {
SpringApplication.run(PaymentHystrixMain8001.class, args);
}
/**
*此配置是为了服务监控而配置,与服务容错本身无关,springcloud升级后的坑
*ServletRegistrationBean因为springboot的默认路径不是"/hystrix.stream",
*只要在自己的项目里配置上下面的servlet就可以了
*/
@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;
}
}