文章目录
一、服务熔断功能
1. Ribbon系列
参考代码:码云 注意提交记录
1.1 整体流程
1.2 配置
- 启动nacos和sentinel
 - 服务提供者cloudalibaba-provider-payment9003/9004 配置和正常的服务提供者一样
 - 测试所用的controller
 
@RestController
public class PaymentController
{
   
    @Value("${server.port}")
    private String serverPort;
    public static HashMap<Long, Payment> hashMap = new HashMap<>();
    static{
   
        hashMap.put(1L,new Payment(1L,"28a8c1e3bc2742d8848569891fb42181"));
        hashMap.put(2L,new Payment(2L,"bba8c1e3bc2742d8848569891ac32182"));
        hashMap.put(3L,new Payment(3L,"6ua8c1e3bc2742d8848569891xt92183"));
    }
    @GetMapping(value = "/paymentSQL/{id}")
    public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id){
   
        Payment payment = hashMap.get(id);
        CommonResult<Payment> result = new CommonResult(200,"from mysql,serverPort: "+serverPort,payment);
        return result;
    }
}
  - 消费端 cloudalibaba-consumer-nacos-order84
主要配置 
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
  server:
  port: 84
spring:
  application:
    name: nacos-order-consumer
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    sentinel:
      transport:
        dashboard: localhost:8080
        port: 8719
service-url:
  nacos-user-service: http://nacos-payment-provider
  - 消费端的controller
 
@RestController
@Slf4j
public class CircleBreakerController {
   
    public static final String SERVICE_URL = "http://nacos-payment-provider";
    @Resource
    private RestTemplate restTemplate;
    //======= OpenFeign
    @Resource
    private PaymentServiceFeign paymentServiceFeign;
    @RequestMapping("/consumer/fallback/{id}")
// @SentinelResource(value = "fallback") //没有任何配置
// @SentinelResource(value = "fallback",fallback ="handlerFallback") //fallback只负责业务异常
    @SentinelResource(value = "fallback", fallback = "handlerFallback", blockHandler = "blockHandler") //blockHandler只负责Sentinel控制台配置违规
    public CommonResult<Payment> fallback(@PathVariable Long id) {
   
        CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/" + id, CommonResult.class, id);
        if (id == 4) {
   
            throw new IllegalArgumentException("IllegalArgument ,非法参数异常...");
        } 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 e) {
   
        Payment payment = new Payment(id, "null");
        return new CommonResult(444, "blockHandler-sentinel 限流,BlockException: " + e.getMessage(), payment);
    }
}
  - 消费端的RestTemplate(远程调用)配置负载均衡
 
@Configuration
public class ApplicationContextConfig {
   
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate() {
   
        return new RestTemplate();
    }
}
  1.3 测试
1.3.1没有任何配置
http://localhost:84/consumer/fallback/4
前提没有限流和降级处理 出现异常直接返回Errorpage
1.3.2只配置fallback
处理业务中的异常
    @RequestMapping("/consumer/fallback/{id}")
    @SentinelResource(value = "fallback",fallback ="handlerFallback")  //fallback只负责业务异常
    public CommonResult<Payment> fallback(@PathVariable Long id) {
   
        CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/" + id, CommonResult.class, id);
        if (id == 4) {
   
            throw new IllegalArgumentException("IllegalArgument ,非法参数异常...");
        } else if (result.getData() == null) {
   
            throw new NullPointerException("NullPointerException,该ID没有对应记录,空指针异常");
        }
	}
	 public CommonResult handlerFallback(@PathVariable Long id, Throwable e) {
   
        Payment payment = new Payment(id, "null");
        return new CommonResult(444, "异常handlerFallback,exception内容: " + e.getMessage(), payment);
    }
  访问http://localhost:84/consumer/fallback/4 一定会出现异常
并没有返回异常页面 而是调用handlerFallback方法
SentinelResource的·fallback·:针对于方法级别的处理 <mark>注意</mark>:方法的返回值请求参数对应 并且添加一个异常方法Throwable e
springmvc:全局异常异常处理:针对于异常类型进行处理
配置fallback出现异常走指定的fallback方法 控制台<mark>不会进行打印异常</mark>
1.3.3只配置blockHandler
@RequestMapping("/consumer/fallback/{id}")
    @SentinelResource(value = "fallback", blockHandler = "blockHandler")//blockHandler只负责Sentinel控制台配置违规
    public CommonResult<Payment> fallback(@PathVariable Long id) {
   
        CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/" + id, CommonResult.class, id);
        if (id == 4) {
   
            throw new IllegalArgumentException("IllegalArgument ,非法参数异常...");
        } else if (result.getData() == null) {
   
            throw new NullPointerException("NullPointerException,该ID没有对应记录,空指针异常");
        }
        return result;
    }
    public CommonResult blockHandler(@PathVariable Long id, BlockException e) {
   
    	Payment payment = new Payment(id, "null");
    	return new CommonResult(444, "blockHandler-sentinel 限流,BlockException: " + e.getMessage(), payment);
    }
  访问localhost:84/consumer/fallback/4 一定会抛出异常
第一次访问 
第二次 访问 和第一次一样
第三次访问
已经进行熔断了
1.3.4 fallback和blockHandler都配置
前两次使用fallback
两次异常触发了降级 使用blockHandler方法
1.3.5 结论
fallback:只负责业务异常
blockHandle:只负责Sentinel控制台配置违规 使用该属性只是替换默认的违规提示
参考博文:你知道Sentinel限流、降级的统一处理吗?
2. Feign系列
pom
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
  yml
#对Feign的支持
feign:
  sentinel:
    enabled: true
  //远程调用service
//fallback 熔断调用的类
@FeignClient(value = "nacos-payment-provider",fallback = PaymentFallbackService.class)
public interface PaymentService
{
   
    @GetMapping(value = "/paymentSQL/{id}")
    public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id);
}
 
//熔断实现类
@Component
public class PaymentFallbackService implements PaymentService
{
   
    @Override
    public CommonResult<Payment> paymentSQL(Long id)
    {
   
        return new CommonResult<>(44444,"服务降级返回,---PaymentFallbackService",new Payment(id,"errorSerial"));
    }
}
  二、熔断框架对比
同类组件功能对比
| Sentinel | Hystrix | resilience4j | |
|---|---|---|---|
| 隔离策略 | 信号量隔离(并发控制) | 线程池隔离/信号量隔离 | 信号量隔离 | 
| 熔断降级策略 | 基于慢调用比例、异常比例、异常数 | 基于异常比例 | 基于异常比例、响应时间 | 
| 实时统计实现 | 滑动窗口(LeapArray) | 滑动窗口(基于 RxJava) | Ring Bit Buffer | 
| 动态规则配置 | 支持近十种动态数据源 | 支持多种数据源 | 有限支持 | 
| 扩展性 | 多个扩展点 | 插件的形式 | 接口的形式 | 
| 基于注解的支持 | 支持 | 支持 | 支持 | 
| 单机限流 | 基于 QPS,支持基于调用关系的限流 | 有限的支持 | Rate Limiter | 
| 集群流控 | 支持 | 不支持 | 不支持 | 
| 流量整形 | 支持预热模式与匀速排队控制效果 | 不支持 | 简单的 Rate Limiter 模式 | 
| 系统自适应保护 | 支持 | 不支持 | 不支持 | 
| 热点识别/防护 | 支持 | 不支持 | 不支持 | 
| 多语言支持 | Java/Go/C++ | Java | Java | 
| Service Mesh 支持 | 支持 Envoy/Istio | 不支持 | 不支持 | 
| 控制台 | 提供开箱即用的控制台,可配置规则、实时监控、机器发现等 | 简单的监控查看 | 不提供控制台,可对接其它监控系统 | 
三、持久化
maven配置
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
  yml配置
spring:
  application:
    name: cloudalibaba-sentinal-service
  cloud:
    nacos:
      discovery:
        #Nacos服务注册中心地址
        server-addr: localhost:8848
    sentinel:
      transport:
        #配置Sentin dashboard地址
        dashboard: localhost:8080
        port: 8719 # 默认8719端口,假如被占用了会自动从8719端口+1进行扫描,直到找到未被占用的 端口
      datasource: #持久化配置
        ds1:  
          nacos:
            server-addr: localhost:8848
            dataId: cloudalibaba-sentinel-service
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow
  nacos中
 
[
    {
   
         "resource": "/retaLimit/byUrl",
         "limitApp": "default",
         "grade":   1,
         "count":   1,
         "strategy": 0,
         "controlBehavior": 0,
         "clusterMode": false    
    }
]
  
 启动8401后刷新sentinel发现业务规则有了
 
 
结论:
 会把nacos中配置的同步到sentinel <mark>注意</mark>在sentinel界面中配置的不会添加到nacos中

京公网安备 11010502036488号