服务熔断和服务降级 以尚硅谷sentinel为例

服务降级

服务降级是在高请求的情况下,对某些接口的请求非常频繁,而对某些接口几乎没有请求,这时就可以主动的停止那些请求比较低的接口,把服务器资源给请求较高的接口,当再请求那些被停止的接口时,只需给出友好的提示即可,这就是 服务降级。

服务熔断

服务熔断
服务熔断机制是对应服务雪崩的一种微服务链路保护机制。
在链路请求中,如果某个微服务节点不可用或者响应时间太长,可以熔断该节点的微服务调用,快速的返回错误的响应信息,当恢复正常后可正常调用。
服务熔断是在服务端对某个请求设置备选方案,当这个请求超时或异常,就会启用备选方案,属于被动式触发

联系与区别

服务熔断是在 服务端 做的;服务降级是在 消费端 做的
服务熔断的触发条件是客户端的请求已经到达了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处理,这里并不能完全对应上面服务端关闭某个服务,但是都是客户端为了不直接抛异常而所提供的降级服务。

整合openfeign

前面服务降级是调用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的支持

你可能感兴趣的:(分布式,java)