springCloud Alibaba实战四之Sentinel(控制台及限流)

Spring Cloud Alibaba Sentinel
上一篇博客我已经用到SentinelOpenFeign结合完成服务降级功能, 只是单纯的使用了他的降级供能,并没有介绍Sentinel详细内容,到底还有什么其他功能, 接下来正式介绍Sentinel:
sentinel官方文档
Sentinel 介绍
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。 Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

Sentinel 具有以下特征:

  • 丰富的应用场景: Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、实时熔断下游不可用应用等。

  • 完备的实时监控: Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。

  • 广泛的开源生态: Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。

  • 完善的 SPI 扩展点: Sentinel 提供简单易用、完善的 SPI 扩展点。您可以通过实现扩展点,快速的定制逻辑。例如定制规则管理、适配数据源等。

sentinel适配的主流框架:
在这里插入图片描述
具体如何适配,请查看sentinel适配的主流框架文档
其他具体介绍请查看sentinel官方文档
接下来我们实现Sentinel 控制台
Sentinel 控制台文档
Sentinel 控制台提供一个轻量级的控制台,它提供机器发现、单机资源实时监控、集群资源汇总,以及规则管理的功能。您只需要对应用进行简单的配置,就可以使用这些功能。

注意: 集群资源汇总仅支持 500 台以下的应用集群,有大概 1 - 2 秒的延时。
获取控制台工程
可以从 release 页面 下载最新版本的控制台 jar 包。
也可以从最新版本的源码自行构建 Sentinel 控制台:
下载 控制台 工程
使用以下命令将代码打包成一个 fat jar: mvn clean package

启动控制台
Sentinel 控制台是一个标准的 Spring Boot 应用,以 Spring Boot 的方式运行 jar 包即可。

java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar

如若8080端口冲突,可使用 -Dserver.port=新端口 进行设置。
启动后会进行登录用户名和密码都是sentinel,启动后界面如下:
在这里插入图片描述
在控制台中接入我们的应用

上一篇博客就sentinel如何使用进行了基本代码实现,接着上一篇博客的demo实现限流功能, 及控制台动态配置流控规则
demo中我们已经引入sentinel依赖

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

在Sentinel 控制台的文档中要求客户端需要引入 Transport 模块来与 Sentinel 控制台进行通信。可以通过 pom.xml 引入 JAR 包, 但是上面的jar包中已经包含了下面这个jar包,

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-transport-simple-http</artifactId>
    <version>x.y.z</version>
</dependency>

所以我们就不用单独引入这个jar包了

这里我们修改payment-service这个模块
修改application.yml

spring:
  profiles:
    active: dev
  cloud:
    nacos:    #nacos地址
      discovery:
        server-addr: 127.0.0.1:8848
    sentinel:      #sentinel地址
      transport:
        dashboard: localhost:8080
        port: 8720 #这里的 spring.cloud.sentinel.transport.port 端口配置会在应用对应的机器上启动一个 Http Server,该 Server 会与 Sentinel 控制台做交互。比如 Sentinel 控制台添加了1个限流规则,会把规则数据 push 给这个 Http Server 接收,Http Server 再将规则注册到 Sentinel 中。
server:
  port: 8082

# 自定义配置
sleep: 0

添加sentinel限流处理类

package com.hc.paymentservice.exception;

import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.hc.scacommon.pojo.Balance;

public class SentinelExceptionHandler {

    public static Balance blockExceptionHandle(Integer id, BlockException exception) {
        exception.printStackTrace();
        return new Balance(0, 0, 0, "sentinel限流处理");
    }
}

修改controller,在接口方法上添加@SentinelResource这个注解

package com.hc.paymentservice.controller;

import com.alibaba.csp.sentinel.EntryType;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.hc.paymentservice.exception.SentinelExceptionHandler;
import com.hc.scacommon.pojo.Balance;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
@RefreshScope
public class PaymentController {
    @Value("${sleep:0}")
    private int sleep;

    @Value("${server.port:0}")
    private int port;

    final static Map<Integer, Balance> balanceMap = new HashMap() {{
        put(1, new Balance(1, 10, 1000));
        put(2, new Balance(2, 0, 10000));
        put(3, new Balance(3, 100, 0));
    }
    };

    /**
     *
     * @param id
     * @return
     */
    @SentinelResource(value = "getBalance", entryType = EntryType.OUT, blockHandlerClass = SentinelExceptionHandler.class, blockHandler = "blockExceptionHandle")
    @RequestMapping("/pay/balance")
    public Balance getBalance(Integer id) {
        System.out.println("request: " + port + ", /pay/balance?id=" + id + ", sleep: " + sleep);
        if(sleep > 0) {
            try {
                Thread.sleep(sleep);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        if(id != null && balanceMap.containsKey(id)) {
            return balanceMap.get(id);
        }
        return new Balance(0, 0, 0);
    }
}

注解介绍
在具体配置之前介绍一下一个非常重要的注解:@SentinelResource

@SentinelResource 用于定义资源,并提供可选的异常处理和 fallback 配置项。 @SentinelResource 注解包含以下属性:

  • value: 资源名称,必需项(不能为空)
  • entryType: 入口类型,可选项: EntryType.IN和EntryType.OUT(默认为 EntryType.OUT)
  • blockHandler / blockHandlerClass: blockHandler 对应处理 BlockException 的函数名称,可选项。若未配置,则将 BlockException 直接抛出。blockHandler 函数访问范围需要是 public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException。blockHandler 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
  • fallback: fallback 函数名称,可选项,仅针对降级功能生效(DegradeException)。fallback 函数的访问范围需要是 public,参数类型和返回类型都需要与原方法相匹配,并且需要和原方法在同一个类中。业务异常不会进入 fallback 逻辑。

说明:

  • value:定义资源名,该名称将会显示在控制台中,并且在定义流控以及熔断降级规则时,指定资源名在这里插入图片描述
  • blockHandler是异常处理的方法,默认需要与原方法在同一个类中,如果需要在另外的类中定义,则需要设置blockHandlerClass,并且噶异常处理的方法应为静态方法。

启动payment-service
这个时候刷新控制台,可能不会出现payment-service这个应用
我们多访问几次http://localhost:8082/pay/balance?id=1 , 再刷新控制台
在这里插入图片描述
查看链路如上图

选择链路添加流控规则, 这里我们再代码中已经再资源中指定了getBalance这个资源的限流名称, 刚好value对应得是getBalance,所有我们可以直接再这里点击getBalance这个链路的**+流控**来添加规则
也可以点击左边的菜单 流控规则 添加
在这里插入图片描述
这里我配置的是getBalance这个资源一秒中只能通过一次
我们快速刷新几次http://localhost:8082/pay/balance?id=1
看看结果
在这里插入图片描述
快速请求一秒钟请求多次
在这里插入图片描述
查看控制台
在这里插入图片描述
下一篇将实现sentinel熔断处理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值