SpringBoot(十五)springboot集成Sentinel

52 阅读3分钟

目前负责的业务一直有一个小问题没有太好的解决办法,这个小问题是什么呢?传说中的学生选课。

 

这玩意跟商城的秒杀还不一样,商城的秒杀是萝卜多,坑少,最后不一定能秒杀的到。学生选课是一个萝卜一个坑,最后你一定能选上课。这么相对来说,商城秒杀要比学生选课的难度要高一个等级。

 

话也说回来了,能玩得了秒杀活动的商城,大概率也都是分布式部署,有单独的一个秒杀系统,配置了多个秒杀服务器。但是本公司就没有那么有实力了,就一台服务器。还得让前端在大数据量请求并发的时候可以正常访问。

 

这个事儿哈,我想过使用ip进行限制,但是有一个小问题,同一个学校的学生的ip都一样。

 

那怎么搞呢?

 

后来我想到了使用RabbitMQ,但是现阶段是有问题的,只有一台服务器,不符合在生产环境中部署的要求。一旦要是崩了,没有备份,造成数据丢失就很麻烦。而且RabbitMQ会增加整个系统的复杂度。不利于后期维护。

 

后来发现了好东西:Sentinel,这个好这个,官网:sentinelguard.io/zh-cn/index…

 

下面我们在Springboot中集成Sentinel

 

一:Sentinel依赖

        <!-- Sentinel 对 Spring Cloud Alibaba 的适配 -->
         <dependency>
             <groupId>com.alibaba.csp</groupId>
             <artifactId>sentinel-core</artifactId>
             <version>1.8.6</version>
         </dependency>
         <!-- SpringBoot 使用 @SentinelResource(value = "AddUser", blockHandler = "exceptionHandler") 需要的依赖 -->
 <!--        <dependency>-->
 <!--            <groupId>com.alibaba.csp</groupId>-->
 <!--            <artifactId>sentinel-annotation-aspectj</artifactId>-->
 <!--            <version>1.8.6</version>-->
 <!--        </dependency>-->
         <!-- sentinel客户端与dashboard通信依赖 版本与控制台保持一致即可 -->
         <dependency>
             <groupId>com.alibaba.csp</groupId>
             <artifactId>sentinel-transport-simple-http</artifactId>
             <version>1.8.6</version>
         </dependency>

 

 

二:引入控制台

Sentinel 提供一个轻量级的控制台, 它提供机器发现、单机资源实时监控以及规则管理等功能。

下载jar包,解压到文件夹

github.com/alibaba/Sen…

直接下载jar包就可以了(我下载的1.8.7版本)

运行命令:

java -Dserver.port=8089 -jar sentinel-dashboard-1.8.7.jar

 

访问 Sentinel 控制台:http://127.0.0.1:8089/

默认账号密码:sentinel/ sentinel

 

但是怎么配置控制台和Springboot集成,这事儿我没搞明白。哪位同学搞明白了可以大概跟我说下,谢谢。

 

三:yml配置

spring:
   application:
     name: msb-sentinel
   # Sentinel 参数配置
   cloud:
     sentinel:
       nacos:
         discovery:
           server-addr: localhost:8848
           service: msb-sentinel
       transport:
         dashboard: 127.0.0.1:8088 # Sentinel 控制台地址
         port: 8719 # 默认端口,不需要可以不配置
       # 配置规则
       #rules:
       #  - resource: my-api
       #    limitApp: default
       #    grade: 1
       #    count: 5
       #    strategy: 0
       #    controlBehavior: 0

 

四:Springboot集成Sentinel

实现说明一下,@SentinelResource注解我也没整明白。哪位同学搞明白了可以大概跟我说下,谢谢。

 

下边是我使用的方法。

 

1 :定义一个设置Sentinel规则的公共方法

public class Function
 {
     /**
      * 设置Sentinel规则
      * 使用代码编写流控规则,项目中不推荐使用,这是硬编码方式 官方推荐使用控制台页面进行设置
      * @param resource
      * @param number
      */
     public static void setSentinelRule(String resource,Integer number)
     {
         /* 1.创建存放限流规则的集合 */
         List<FlowRule> rules = new ArrayList<>();
         /* 2.创建限流规则 */
         FlowRule rule = new FlowRule();
         /* 定义资源,表示 Sentinel 会对哪个资源生效 "AddUser" */
         rule.setResource(resource);
         /* 定义限流的类型(此处使用 QPS 作为限流类型) */
         rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
         /* 定义 QPS 每秒通过的请求数 1 */
         rule.setCount(number);
         /* 3.将限流规则存放到集合中 */
         rules.add(rule);
         /* 4.加载限流规则 */
         FlowRuleManager.loadRules(rules);
     }
 }

 

2 :在controller类中设置规则

这一步不是必须得,看你需求

/**
  * 注解 @PostConstruct 的含义是:本类构造方法执行结束后执行
  */
 @PostConstruct
 public void initFlowRule()
 {
     // 设置Sentinel规则
     Function.setSentinelRule("AddUser"1);
 }

 

3 :在方法中使用Sentinel

/**
  * 获取博客首页数据
  * @return
  */
 @GetMapping("index/test")
 public Map<StringObjecttest()
 {
     try
     {
         // 设置一个资源名称为 Hello
         Entry ignored = SphU.entry("AddUser");
         Map<StringObject> result = new HashMap<>();
         result.put("code"1);
         result.put("msg""通过!");
         return result;
     }
     catch (BlockException ex)
     {
         Map<StringObject> result = new HashMap<>();
         result.put("code", -1);
         result.put("msg""别急,等一会在请求!");
         return result;
     }
 }

 我设置的参数是一秒只允许访问一次,因此每秒访问第二次的时候就会输出:

{"msg":"别急,等一会在请求!","code":-1}

具体参数设置还需要根据你自己的需求来设置。

 

以上大概就是Springboot集成Sentinel的基本实现。

 

有好的建议,请在下方输入你的评论。