Sentinel(第一篇)_Springboot2.x+Sentinel

5 篇文章 0 订阅

前言:

Sentinel干嘛用的,我们先通过几个问题点,再通过这个几个问题点来看Sentinel是干嘛用的。

限流:

限流,字眼上的意思就是限制流量(请求数等),就是打个比方:一桶水最多装50毫升以每秒不超过10毫升,就不会溢出,假设瞬间你的水龙头滴水量超过了10毫升,那桶就会溢出,可能比较慢,但是如果一秒20毫升的水滴入,那很快就溢出了。可能一瞬间,也可能慢慢叠加。

在系统上如果你的系统最大支持1000/qps,那如果一秒只有1000的qps进来,那服务器能稳定运行,如果一秒2000/qps的进来,服务器扛不住,扛不住就挂了,挂了没法提供对外服务导致业务直接熔断。如果算上1个请求的执行时间超过1秒,那可能不达到1000/qps也会扛不住。

限流的意义在于限制
如:服务器只有支撑1000QPS的处理能力,那就每秒放1000个请求,自然保证了服务器的稳定,这就是限流。

熔断降级:

在分布式系统中,如:一个下单接口,它调了一个接口,如时间太长未响应等问题,那肯定会拖垮核心服务,直接把当前这个服务给熔断掉。

由于调用关系的复杂性,如果调用链路中的某个资源不稳定,最终会导致请求发生堆积。Sentinel 熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联错误。当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都自动熔断

附:ratelimter也可以用做限流,可自行研究

简述:

Sentinel主要限流、熔断降级,系统负载保护等多个维度来保障服务之间的稳定性

进入正文,接下来我们就以Springboot+sentinel来做一个限流的demo

一:创建springboot项目

这里只贴相关依赖和截图

1.1:基础代码

pom.xml

<properties>
    <java.version>1.8</java.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <spring-boot.version>2.3.7.RELEASE</spring-boot.version>
    <sentinel.version>1.8.0</sentinel.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>


    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- Sentinel -->
    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-core</artifactId>
        <version>${sentinel.version}</version>
    </dependency>
    <!-- Sentinel注解 -->
    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-annotation-aspectj</artifactId>
        <version>${sentinel.version}</version>
    </dependency>
    <!-- 控制台通信的jar包 客户端 -->
    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-transport-simple-http</artifactId>
        <version>${sentinel.version}</version>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>
    </plugins>
</build>

在这里插入图片描述

1.2: properties

可自行修改成yml格式,我为了偷懒

server.port=8085

# 应用名称
spring.application.name=peng-sentinel
# Sentinel 控制台地址
spring.cloud.sentinel.transport.dashboard=localhost:8080
# 取消Sentinel控制台懒加载
# 默认情况下 Sentinel 会在客户端首次调用的时候进行初始化,开始向控制台发送心跳包
# 配置 sentinel.eager=true 时,取消Sentinel控制台懒加载功能
spring.cloud.sentinel.eager=true
# 如果有多套网络,又无法正确获取本机IP,则需要使用下面的参数设置当前机器可被外部访问的IP地址,供admin控制台使用
# spring.cloud.sentinel.transport.client-ip=

在这里插入图片描述

1.3:Controller

@RestController
@RequestMapping("home")
public class HomeController {
    @Autowired
    private HomeService homeService;

    @RequestMapping("/goHome")
    @ResponseBody
    public String queryHome(@RequestParam("homeName") String homeName) {
        return homeService.queryHomeInfo(homeName);
    }
}

在这里插入图片描述

1.4 service

1.4.1-- 硬编码限流
@Service
public class HomeService {

    /**
     * 订单查询接口, 使用Sentinel注解实现限流
     *
     * @param homeName
     * @return
     */
    @SentinelResource(value = "getHomeInfo", blockHandler = "handleFlowQpsException",
            fallback = "queryHomeInfoFallback")
    public String queryHomeInfo(String homeName) {
        // 模拟接口运行时抛出代码异常
        if ("000".equals(homeName)) {
            throw new RuntimeException();
        }

        System.out.println("获取信息:" + homeName);
        return "return Info :" + homeName;
    }
    /**
     * 订单查询接口抛出限流或降级时的处理逻辑
     *
     * 注意: 方法参数、返回值要与原函数保持一致
     * @return
     */
    public String handleFlowQpsException(String homeName, BlockException e) {
        e.printStackTrace();
        System.out.println("FlowQpsException");
        return "handleFlowQpsException for queryHomeInfo: " + homeName;
    }

    /**
     * 订单查询接口运行时抛出的异常提供fallback处理
     *
     * 注意: 方法参数、返回值要与原函数保持一致
     * @return
     */
    public String queryHomeInfoFallback(String homeName, Throwable e) {
        e.printStackTrace();
        System.out.println("Fallback");
        return "fallback queryHomeInfo: " + homeName;
    }

//    @PostConstruct
//    public void initDegradeRule() {
//        List<DegradeRule> rules = new ArrayList<>();
//        DegradeRule rule = new DegradeRule();
//        rule.setResource("getHomeInfo");
//        // 80s内调用接口出现异常次数超过5的时候, 进行熔断
//        rule.setCount(5);
//        rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);
//        rule.setTimeWindow(80);
//        rules.add(rule);
//        DegradeRuleManager.loadRules(rules);
//    }

    @PostConstruct
    public static void initFlowQpsRule() {
        List<FlowRule> rules = new ArrayList<FlowRule>();
        FlowRule rule1 = new FlowRule();
        rule1.setResource("getHomeInfo");
        // QPS控制在2以内
        rule1.setCount(2);
        // QPS限流
        rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule1.setLimitApp("default");
        rules.add(rule1);
        FlowRuleManager.loadRules(rules);
    }

在这里插入图片描述

1.5:测试

1.5.1 测试硬编码

注意:测试前,先走标题二:引入sentinel服务端

启动项目
浏览器输入如下地址:http://localhost:8085/home/goHome?homeName=123
为了方便,我们引入客户端,我们已经引入了客户端的依赖,
我们还需要在idea插件添加一行命令
-Dproject.name=peng-sentinel -Dcsp.sentinel.dashboard.server=127.0.0.1:8080 -Dcsp.sentinel.api.port=8719

在这里插入图片描述
浏览器:http://localhost:8080/#/login
进入客户端
默认账号密码都是sentinel

注意,各个版本可能不一样
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
接下来我们连续访问
http://localhost:8085/home/goHome?homeName=123
在这里插入图片描述
就可以看到如下的信息
注意:根据官方wiki文档,sentinel控制台的实时监控数据,默认仅存储 5 分钟以内的数据。如需持久化,需要定制实现相关接口。持久化,后文会加入

1.5.2 控制台控制限流等

修改service
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
超过阈值就500拒绝掉了

暂时告一段落了,当然,控制台流控规则、降级规则、热点规则、系统规则等很多使用,可以参考官方文档,看看具体如何使用。

二:引入sentinel服务端

启动控制台
启动方式:

2.1:通过下载jar,命令方式

打开网站https://github.com/alibaba/Sentinel/releases,
然后下载对应版本的dashboard jar包,进入到该jar所在的目录,然后通过java命令运行该jar包
目前最新是1.8.1
一般下载都是第二新的
在这里插入图片描述
在这里插入图片描述
下载完成打开cmd窗口,
如windows系统,打开jar所在目录,在

在这里插入图片描述
然后输入cmd回车,即可cmd打开的窗口就在当前目录

输入如下命令
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject=peng-sentinel -jar sentinel-dashboard-1.8.0.jar

在这里插入图片描述
启动成功

2.2 下载源码进行打包

git clone 整个sentinel源码,进入sentinel-dashboard模块,执行打包命令:mvn clean package,生成一个可执行的 fat jar包,然后启动控制台,输入url:localhost:8080后即可进入主页面。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值