什么是服务降级?
服务降级是指 当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理,或换种简单的方式处理,从而释放服务器资源以保证核心业务正常运作或高效运作。说白了,就是尽可能的把系统资源让给优先级高的服务。
由上图可得,当某一时间内服务A的访问量暴增,而B和C的访问量较少,为了缓解A服务的压力,这时候需要B和C暂时关闭一些服务功能,去承担A的部分服务,从而为A分担压力,叫做服务降级。
服务降级需要考虑的问题
- 那些服务是核心服务,哪些服务是非核心服务
- 那些服务可以支持降级,那些服务不能支持降级,降级策略是什么
- 除服务降级之外是否存在更复杂的业务放通场景,策略是什么?
导入依赖
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.2.9.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.9.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-eureka-client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--这样每次在保存代码的时候都会自动重新加载。-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
案例(基于Feign)
Controller层
@RestController
public class FeignContorllerFall {
@Resource
public FeignBookServiceFall service;
@RequestMapping("/getAllBook")
public JSONObject getAll(){
return service.queryAll();
}
@RequestMapping("/getBookById/{id}")
public Books queryBookById(@PathVariable("id") int id){
Books books = service.queryById(id);
return books;
}
}
service层@FeignClient(服务名,实现降级处理的fallbackFactory)
/**
* 处理服务降级,@FeignClient(服务名,处理降级的服务类)
*/
@FeignClient(name = "SpringCloud-Provider1",fallbackFactory = FeignBookServiceFallFactory.class)
@Component
public interface FeignBookServiceFall {
@RequestMapping("book/queryBookById/{id}")
Books queryById(@PathVariable("id") int id);
@RequestMapping("/book/allBook")
JSONObject queryAll();
}
需要实现FallbackFactory下的方法create返回的是我们进行降级的服务类,在这里处理服务降级后的一些程序
/**
* 处理需要降级的服务 需要实现:FallbackFactory
*/
@Component
public class FeignBookServiceFallFactory implements FallbackFactory {
@Override
public Object create(Throwable throwable) {
return new FeignBookServiceFall() {
@Override
public Books queryById(int id) {
Books books = new Books();
books.setBookName("msg=====>进行了服务降级处理,关闭了此服务");
return books;
}
@Override
public JSONObject queryAll() {
JSONObject jsonObject = new JSONObject();
jsonObject.put("msg==>","进行了服务降级处理,关闭了此服务");
return jsonObject;
}
};
}
}
并在配置中开启服务降级
注意:把服务提供者关了(服务器)之后,再次访问这个接口即可看出这个服务已经进行降级处理
服务熔断和降级的区别
- 服务熔断—>服务端:某个服务超时或异常,引起熔断~,类似于保险丝(自我熔断)
- 服务降级—>客户端:从整体网站请求负载考虑,当某个服务熔断或者关闭之后,服务将不再被调用,此时在客户端,我们可以准备一个 FallBackFactory ,返回一个默认的值(缺省值)。会导致整体的服务下降,但是好歹能用,比直接挂掉强。
- 触发原因不太一样,服务熔断一般是某个服务(下游服务)故障引起,而服务降级一般是从整体负荷考虑;管理目标的层次不太一样,熔断其实是一个框架级的处理,每个微服务都需要(无层级之分),而降级一般需要对业务有层级之分(比如降级一般是从最外围服务开始)
- 实现方式不太一样,服务降级具有代码侵入性(由控制器完成/或自动降级),熔断一般称为自我熔断。