服务降级是在高请求的情况下,对某些接口的请求非常频繁,而对某些接口几乎没有请求,这时就可以主动的停止那些请求比较低的接口,把服务器资源给请求较高的接口,当再请求那些被停止的接口时,只需给出友好的提示即可,这就是 服务降级。
服务熔断
服务熔断机制是对应服务雪崩的一种微服务链路保护机制。
在链路请求中,如果某个微服务节点不可用或者响应时间太长,可以熔断该节点的微服务调用,快速的返回错误的响应信息,当恢复正常后可正常调用。
服务熔断是在服务端对某个请求设置备选方案,当这个请求超时或异常,就会启用备选方案,属于被动式触发
服务熔断是在 服务端 做的;服务降级是在 消费端 做的
服务熔断的触发条件是客户端的请求已经到达了provider服务,但provider服务端由于某种原因触发了熔断机制,执行备选服务,返回给客户端一个结果,所以说熔断机制是在服务端触发的。但服务降级是服务端已经完全关闭服务,不可能再执行任何操作,由于客户端根本找不到服务端提供的服务,自己给自己生成的一套备选返回方案,所以是在客户端本身触发的。
@RestController
public class CircleBreakerController {
public static final String SERVICE_URL = "http://nacos-payment-provider";
@Resource
private RestTemplate restTemplate;
@RequestMapping("/consumer/fallback/{id}")
// @SentinelResource(value = "fallback")//没有配置
// @SentinelResource(value = "fallback",fallback = "handlerFallback")//fallback只负责异常处理
@SentinelResource(value = "fallback",blockHandler = "blockHandler",fallback = "handlerFallback") //blockHandler只负责sentinel控制台配置违规
public CommonResult fallback(@PathVariable Long id)
{
CommonResult result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/"+id, CommonResult.class,id);
if (id == 4) {
throw new IllegalArgumentException ("IllegalArgumentException,非法参数异常....");
}else if (result.getData() == null) {
throw new NullPointerException ("NullPointerException,该ID没有对应记录,空指针异常");
}
return result;
}
public CommonResult handlerFallback(@PathVariable Long id,Throwable e) {
Payment payment = new Payment(id,"null");
return new CommonResult<>(444,"兜底异常handlerFallback,exception内容 "+e.getMessage(),payment);
}
public CommonResult blockHandler(@PathVariable Long id, BlockException blockException) {
Payment payment = new Payment(id,"null");
return new CommonResult<>(445,"blockHandler-sentinel限流,无此流水: blockException "+blockException.getMessage(),payment);
}
}
以尚硅谷sentinel教学案例为例解释,fallback对应着服务降级,blockhandler对应着服务熔断。
那上面说的客户端、服务端怎么对应在一个类上面了?当请求来到这个order时,他是服务端,可能触发blockhandler;
比如hystrix熔断条件:
FAILURE:执行失败,抛出异常。
TIMEOUT:执行超时。
SHORT_CIRCUITED:断路器打开。
THREAD_POOL_REJECTED:线程池拒绝。
SEMAPHORE_REJECTED:信号量拒绝。
而order向payment系统发起调用时,他又是客户端,客户端自己抛出异常,这时候用fallback处理,这里并不能完全对应上面服务端关闭某个服务,但是都是客户端为了不直接抛异常而所提供的降级服务。
前面服务降级是调用resttemplate,而利用openfeign可以直接调用service,其为我们封装好了。
service接口
package com.atguigu.springcloud.alibaba.service;
import com.atguigu.springcloud.entities.CommonResult;
import com.atguigu.springcloud.entities.Payment;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(value = "nacos-payment-provider",fallback = PaymentFallbackService.class)
public interface PaymentService {
@GetMapping(value = "/paymentSQL/{id}")
public CommonResult paymentSQL(@PathVariable("id") Long id);
}
降级服务类
package com.atguigu.springcloud.alibaba.service;
import com.atguigu.springcloud.entities.CommonResult;
import com.atguigu.springcloud.entities.Payment;
import org.springframework.stereotype.Component;
@Component
public class PaymentFallbackService implements PaymentService{
@Override
public CommonResult paymentSQL(Long id) {
return new CommonResult<>(444,"服务降级返回",new Payment(id,"errorSerial"));
}
}
controller对应方法
@Resource
private PaymentService paymentService;
// openfeign
@GetMapping(value = "/consumer/paymentSQL/{id}")
public CommonResult paymentSQL(@PathVariable("id") Long id) {
return paymentService.paymentSQL(id);
}
主启动类
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class OrderNacosMain84 {
public static void main(String[] args) {
SpringApplication.run(OrderNacosMain84.class,args);
}
}
yml
feign:
sentinel:
enabled: true # 激活Sentinel对Feign的支持