服务降级
是什么?
整体资源快不够了,忍痛将某些服务先关掉,待渡过难关,再开启回来。
如下图,在某一个时间段,访问服务A的请求特别多,而访问服务B和服务C的请求特别少,这时我们可以把服务B和服务C先关闭,等到度过此时间段,在把他们开启回来。
把服务关闭之后,用户如果访问该服务应该怎么办呢?
如果直接把服务关闭不进行任何处理的话,用户访问该服务的时候,就会发生500代码错误。而我们Hystrix的服务降级功能,可以对用户的请求进行一些处理。就是预先写好一个失败回调类,如果访问已经关闭的服务,就会进入该失败回调类,响应给用户一些预先写好的信息,比如 “该服务已关闭” 等。
虽然看起来作用不是很大,但是可以让客户端看到正常的信息,而不是代码500,增加用户的体验。
具体实例
1、在Feign实现负载均衡的 DeptClientService
的基础上,为他写一个失败回调类,命名 DeptClientServiceFallbackFactory
,如下:
2、失败回调类需要继承 FallbackFactory
类,并且重写 create
方法,方法返回值为 DeptClientService
接口 ,方法中返回 DeptClientService
接口的实现,我这里只写了一个函数的返回代码,其他函数也是类似,代码如下:
//失败回调方法
@Component
public class DeptClientServiceFallbackFactory implements FallbackFactory {
@Override
public DeptClientService create(Throwable throwable) {
return new DeptClientService() {
@Override
public Dept queryById(Long id) {
return new Dept()
.setDeptno(id)
.setDname("id=>" + id + "没有对应的信息,客户端提供了降级的信息,这个服务现在以及被关闭")
.setDbSource("没有数据");
}
@Override
public boolean addDept(Dept dept) {
return false;
}
@Override
public List<Dept> queryAllDept() {
return null;
}
};
}
}
3、在 DeptClientService
接口的 @FeignClient
注解中,加一个属性 fallbackFactory
,值为 失败回调方法的名字.class,如下:
@FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT" ,fallbackFactory = DeptClientServiceFallbackFactory.class) //通过服务名获取注册中心的服务
4、在 springcloud-consumer-dept-feign 的配置文件中开启服务降级。
# 开启hystrix服务降级
feign:
hystrix:
enabled: true
5、现在可以开启 springcloud-consumer-dept-feign 、springcloud-eureka-7001、springcloud-provider-dept-8001进行测试。
具体流程
将服务开启,可以正常访问服务的信息;将服务关闭再访问服务的话,会进入失败回调类,返回预先写好的提示信息给用户。此时服务端provider已经down了,但是我们做了服务降级处理,让客户端在服务端不可用时也会获得提示信息而不会挂起耗死服务器。
总结
服务熔断:一般是某个服务故障或者异常引起,类似现实世界中的 “保险丝” , 当某个异常条件被触发,直接熔断整个服务,而不是一直等到此服务超时!
服务降级:所谓降级,一般是从整体负荷考虑,就是当某个服务熔断之后,服务器将不再被调用,此时客户端可以自己准备一个本地的fallback回调,返回一个缺省值。这样做,虽然服务水平下降,但好歹可用,比直接挂掉要强。