Dubbo使用Sentinel来对服务进行降级与限流 (3)

在这里插入图片描述
Sentinel 是什么

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。

Sentinel 的历史

2012 年,Sentinel 诞生,主要功能为入口流量控制。
2013-2017 年,Sentinel 在阿里巴巴集团内部迅速发展,成为基础技术模块,覆盖了所有的核心场景。Sentinel 也因此积累了大量的流量归整场景以及生产实践。
2018 年,Sentinel 开源,并持续演进。
2019 年,Sentinel 朝着多语言扩展的方向不断探索,推出 C++ 原生版本,同时针对 Service Mesh 场景也推出了 Envoy 集群流量控制支持,以解决 Service Mesh 架构下多语言限流的问题。
2020 年,推出 Sentinel Go 版本,继续朝着云原生方向演进。

Sentinel 怎么用

Sentinel分为两个部分:客户端以及控制台。
控制台用于管理限流,熔断规则的发布与监控。
客户端则用于接收规则,并执行相关规则。

Docker安装Sentinel

拉取镜像: docker pull bladex/sentinel-dashboard

[root@localhost opt]# docker pull bladex/sentinel-dashboard
Using default tag: latest
latest: Pulling from bladex/sentinel-dashboard
169185f82c45: Pull complete 
4346af5b5a4f: Pull complete 
28ac9c6decc7: Pull complete 
4ca458a82bd5: Pull complete 
Digest: sha256:c596d19cd68b6f140a2230f5f7f16a4203fd3241d3f507e5513de5d28c897b8a
Status: Downloaded newer image for bladex/sentinel-dashboard:latest
docker.io/bladex/sentinel-dashboard:latest
[root@localhost opt]# 

创建、运行、映射:docker run --name sentinel -d -p 8858:8858 -d bladex/sentinel-dashboard

[root@localhost opt]# docker run --name sentinel -d -p 8858:8858 -d bladex/sentinel-dashboard
278ee8b04569983d27c474c99410256e49499fe03e23e91b1147536582b58836
[root@localhost opt]# 

查看运行的容器 :docker ps

[root@localhost opt]# docker ps
CONTAINER ID   IMAGE                       COMMAND                  CREATED          STATUS          PORTS                                                  NAMES
278ee8b04569   bladex/sentinel-dashboard   "java -Djava.securit…"   31 seconds ago   Up 29 seconds   8719/tcp, 0.0.0.0:8858->8858/tcp                       sentinel
[root@localhost opt]# 

访问dashboard 地址:192.168.230.136:8858
账号密码都为:sentinel
在这里插入图片描述
在这里插入图片描述
整合项目

创建一个SpringBoot项目 sentinel

引入子相关依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.jq</groupId>
        <artifactId>test</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <groupId>com.jq</groupId>
    <artifactId>sentinel</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sentinel</name>
    <description>Demo project for Spring Boot</description>

    <dependencies>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>

        <!-- cloud-dubbo依赖 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-dubbo</artifactId>
            <version>2.1.1.RELEASE</version>
        </dependency>


        <!-- 引入provider-api -->
        <dependency>
            <groupId>com.jq</groupId>
            <artifactId>server-dubbo-provider-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

    </dependencies>

</project>

application.yml配置

server:
  port: 10005

spring:
  application:
    name: sentinel
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.230.137:8848
    #连接sentinel 
    sentinel:
      transport:
        port: 10005
        dashboard: http://192.168.230.137:8858

dubbo:
  scan:
    base-packages: com.jq.service
  protocol:
    name: dubbo
    port: 19005
  registry:
    address: spring-cloud:// 192.168.230.137:8848

启动类:加@EnableDiscoveryClient

package com.jq;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient  
public class SentinelApplication {

    public static void main(String[] args) {
        SpringApplication.run(SentinelApplication.class, args);
    }

}

创建控制层测试 限流

package com.jq.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.jq.config.MyBlockHandlerClass;
import com.jq.service.IDubboProviderService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

@RequestMapping("Sentine")
@RestController
public class SentineController {

    // 限流
    @SentinelResource(value = "test", blockHandler = "degradeException")
    @GetMapping("/test")
    public String server() {
        return "正常访问";
    }

    // 自定义异常必须与原方法返回值及参数完全一致
    public String degradeException(
            BlockException e) {
        return "限流了!";
    }
}


浏览器访问测试:http://localhost:10005/Sentine/test

在这里插入图片描述
设置限流数:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
设置后,在1秒内 请求 > = 2 次 时触发
在这里插入图片描述
创建控制层测试 降级

1.熔断数 降级测试

异常数( DEGRADF_GRADE_EXCEPTION_cOuNT ):当资源近1分钟的异常数目超过阈值之后会进行熔断。注意由于统计时间窗口是分钟级别的,若 timewindow小于60s,则结束熔断状态后仍可能再进入熔断状态。时间窗口一定要大于60s

在这里插入图片描述

package com.jq.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.jq.config.MyBlockHandlerClass;
import com.jq.service.IDubboProviderService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

@RequestMapping("Sentine")
@RestController
public class SentineController {
	//降级测试1
    @GetMapping("/test")
    public String test()
    {
        int age = 10/0;
        return "------test测试异常数";
    }

}


设置降级规则:

在这里插入图片描述
浏览器http://localhost:10005/Sentine/test
http://localhost:10005/Sentine/test,第一次访问绝对报错,因为除数不能为零,
我们看到error窗口,但是达到5次报错后,进入熔断后降级。
在这里插入图片描述
2.异常比例 降级测试

异常比例( DEGRADE_GRADE_EXCEPTION_RATIO ):当资源的每秒请求量>=5,并且每秒异常总数占通过量的比值超过阈值( DegradeRule中的count )之后,资源进入降级状态,即在接下的时间窗口( DegradeRule中的timewindow,以s为单位)之内,对这个方法的调用都会自动地返回。异常比率的阈值范围是[0.0,1.0],代表0%- 100%。
在这里插入图片描述
控制层代码

package com.jq.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.jq.config.MyBlockHandlerClass;
import com.jq.service.IDubboProviderService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

@RequestMapping("Sentine")
@RestController
public class SentineController {

    @GetMapping("/test1")
    public String testD()
    {
        int age = 10/0;
        return "------test1";
    }
}


设置降级规则
在这里插入图片描述
当资源的每秒请求量>=5 时 触发
在这里插入图片描述

3.慢调用比例 RT 降级测试

RT是什么

平均响应时间( DEGRADE_GRADE_RT ):当1s内持续进入5个请求,对应时刻的平均响应时间(秒级)均超过阈值( count ,以ms为单位),那么在接下的时间窗口( DegradeRule中的
timewindow,以s为单位)之内,对这个方法的调用都会自动地熔断(抛出
DegradeException )。注意Sentinel默认统计的RT上限是4900 ms,超出此阈值的都会算作4900 ms,若需要变更此上限可以通过启动配置项-Dcsp.sentine1.statistic.max. rt=xxx来配置。

在这里插入图片描述
控制层代码:

package com.jq.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.jq.config.MyBlockHandlerClass;
import com.jq.service.IDubboProviderService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

@RequestMapping("Sentine")
@RestController
public class SentineController {


    @GetMapping("/test2")
    public String test2() {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "----test2";
    }


}


一秒钟打进来10个线程(大于5个了)调用test2,我们希望200毫秒处理完本次任务,
如果超过200毫秒还没处理完,在未来1秒钟的时间窗口内,断路器打开(保险丝跳闸)微服务不可用,保险丝跳闸断电了
在这里插入图片描述

4.使用@SentinelResource 降级测试

	@GetMapping("/byResource")
    @SentinelResource(value = "byResource", blockHandler = "handleException")
    public String byResource() {
        return  "按照资源名称限流测试";
    }
    
 	@GetMapping("/byResource/exection")
    @SentinelResource(value = "byResourceForExection", blockHandler = "handleException")
    public String byResourceForExection() {
        int i = 10 / 0;
        return "按照异常数做降级";
    }


    public String handleException(BlockException exception) {
        return "服务不可用";
    }


	
    @GetMapping("/rateLimit/byUrl")
    @SentinelResource(value = "byUrl")
    //注意如果使用url进行限流降级那么SentinelResource配置的blockHandler将无效
    public String byUrl() {
        return "按照byUrl限流测试";
    }

    @GetMapping("/rateLimit/customerBlockHandler")
    @SentinelResource(value = "customerBlockHandler",
            blockHandlerClass = CustomerBlockHandler.class, blockHandler = "handlerException2")
    public String customerBlockHandler() {
        return "按照客户自定义限流测试";
    }


 

自定义处理类

package com.jq.config;

import com.alibaba.csp.sentinel.slots.block.BlockException;

public class CustomerBlockHandler   {


    public static String handlerException(BlockException exception) {
        return "按照客户自定义的Glogal 全局异常处理 ---- 1";
    }

    public static String handlerException2(BlockException exception) {
        return "按照客户自定义的Glogal 全局异常处理 ---2";
    }

}

注:每次第一次访问后都需要设置规则
注意资源名称要和@SentinelResource()的value属性相同才会限流

在这里插入图片描述

1.按照资源名称限流测试第一次
在这里插入图片描述
再次访问按照资源名称限流测试

在这里插入图片描述
2.按照异常数做降级
@GetMapping("/byResource/exection") 第一次显示报错 因为除数不能为零
在这里插入图片描述
再请求时
在这里插入图片描述
3.按照byUrl限流测试
@GetMapping("/rateLimit/byUrl") 第一次访问
在这里插入图片描述
再访问此次时
在这里插入图片描述
在这里插入图片描述
4.按照客户自定义限流测试第一次访问
在这里插入图片描述
再次按照客户自定义限流测试
在这里插入图片描述
原文地址 https://www.cnblogs.com/idcode/p/14551366.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Spring Cloud Alibaba是一个基于Spring Cloud的开源框架,提供了丰富的微服务开发工具包,包括服务注册与发现、配置管理、消息总线、负载均衡、熔断降级、分布式事务、流量控制、安全控制、分布式追踪等功能。 Spring Cloud Alibaba与Nacos、DubboSentinel等组件协同工作,Nacos作为注册中心和配置中心,Dubbo作为RPC框架,Sentinel作为流量控制和熔断降级组件,共同构建起完整的微服务生态体系。 使用Spring Cloud Alibaba进行服务注册和发现,可以通过注解@EnableDiscoveryClient开启服务注册与发现功能,并通过@FeignClient或@LoadBalanced注解实现服务调用和负载均衡。 使用Spring Cloud Alibaba进行服务治理,可以通过注解@EnableCircuitBreaker开启熔断降级功能,并通过@SentinelResource注解配置熔断降级规则。 使用Spring Cloud Alibaba进行熔断降级,可以通过Sentinel Dashboard进行实时监控和管理,同时通过注解@SentinelRestTemplate实现对RestTemplate的熔断降级使用Spring Cloud Alibaba进行服务配置管理,可以通过注解@EnableConfigNacosConfig和@Value注解实现动态配置管理。 使用Spring Cloud Alibaba进行分布式事务管理,可以通过注解@EnableDistributedTransaction开启分布式事务管理功能,并通过@GlobalTransactional注解实现分布式事务的统一管理和控制。 使用Spring Cloud Alibaba进行链路追踪,可以通过注解@EnableZipkinServer和@EnableZipkinClient开启链路追踪功能,并通过Sleuth和Zipkin实现对微服务调用链的追踪和分析。 使用Spring Cloud Alibaba进行服务限流,可以通过Sentinel进行实时流控和熔断降级,同时通过注解@SentinelResource实现对服务限流控制。 Spring Cloud Alibaba支持微服务服务网关管理,可以通过注解@EnableZuulProxy或@EnableGateway开启服务网关功能,并通过Zuul或Gateway实现微服务的API网关管理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jq1223

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值