微服务架构-SpringCloudAlibaba-100:sentinel服务保护框架

1 sentinel实现动态服务限流演示

课程内容:

  1. 服务保护、服务限流、服务降级的概念
  2. 服务雪崩效应产生背景及解决方案
  3. sentinel配置及多种使用方式
  4. 实例演示sentinel限流效果

2 服务保护、服务限流、服务降级的概念

服务接口保护有哪些方案?
黑名单和白名单、对IP实现限流/熔断机制、服务降级、服务隔离机制。

服务限流:目的是为了保护服务。在高并发的情况下,如果客户端请求服务器端达到一定的极限,请求的数量超出了设置的阈值,开启自我保护机制。直接执行服务降级的方法,不会执行业务逻辑,走本地fallback方法。

服务降级:在高并发的情况下,为了防止用户一直等待,采用限流或者熔断机制保护服务,不会执行业务逻辑,走本地fallback方法,返回一个友好的提示给客户端。
比如:返回提示“当前排队人数过多,请稍后重试”。

3 服务雪崩效应产生的背景与解决方案

服务雪崩效应:默认的情况下,tomcat/jetty服务器只会有一个线程池处理所有接口的请求。这样的话在高并发的情况下,如果客户端所有的请求都堆积到同一个接口上,那么会出现该服务器所有的线程都在处理该接口,可能会导致其他的接口无法访问,短暂没有线程处理。
在这里插入图片描述
jmeter模拟雪崩效应场景
订单服务

@RestController
@Slf4j
public class OrderService {

    @RequestMapping("/orderToMember")
    public String orderToMember() {
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("orderToMember >>>" + Thread.currentThread().getName() + ">>>");
        return "this is order";
    }

    @RequestMapping("/smsOrder")
    public String smsOrder() {
        log.info("smsOrder >>>" + Thread.currentThread().getName() + ">>>");
        return "订单发送短信消息";
    }
}

在这里插入图片描述
如何去证明tomcat服务器只有一个线程池处理所有接口的请求?
打印线程名称。线程名称组合:线程池名称+线程id名称。

服务雪崩解决方案
服务隔离机制:线程池隔离或者信号量隔离机制。

线程池隔离:每个接口都有自己独立的线程池去维护请求,每个线程池互不影响。
缺点:占用服务器内存非常大。
信号量隔离:设置最多允许某个接口有一阈值的线程数量处理接口,如果超出该线程数量,则拒绝访问。

4 sentinel中文基本的介绍

Sentinel: 分布式系统的流量防卫兵
Sentinel是什么?
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

Sentinel具有以下特征:

  1. 丰富的应用场景:Sentinel承接了阿里巴巴近10年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
  2. 完备的实时监控:Sentinel同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至500台以下规模的集群的汇总运行情况。
  3. 广泛的开源生态:Sentinel提供开箱即用的与其它开源框架/库的整合模块,例如与Spring Cloud、Dubbo、gRPC的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入Sentinel。
  4. 完善的SPI扩展点:Sentinel提供简单易用、完善的SPI扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

Sentinel中文文档介绍:
https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D

sentinel与hystrix的区别
在这里插入图片描述

5 sentinel手动实现限流规则

限流配置有两种方案:
1 手动使用代码配置 纯代码/注解的形式
2 Sentinel 控制台形式配置
默认情况下Sentinel不对数据持久化,需要自己独立持久化。

实现的步骤:
创建流控规则(限流规则),然后再被映射地址去引用。
maven依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-alibaba-sentinel</artifactId>
        <version>0.2.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
</dependencies>

手动配置管理Api限流接口

@RestController
@Slf4j
public class OrderService {

    /**
     * 限流规则名称
     */
    private static final String GETORDER_KEY = "orderToMember";

    /**
     * 限流规则
     * @return
     */
    @RequestMapping("/initFlowQpsRule")
    public String initFlowQpsRule() {
        List<FlowRule> rules = new ArrayList<FlowRule>();
        FlowRule rule1 = new FlowRule();
        rule1.setResource(GETORDER_KEY);
        // QPS控制在1,每秒钟运行1个请求
        rule1.setCount(1);
        // QPS限流
        rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule1.setLimitApp("default");
        rules.add(rule1);
        FlowRuleManager.loadRules(rules);
        return "....限流配置初始化成功..";
    }

    @RequestMapping("/orderToMember")
    public String orderToMember() {
        Entry entry = null;
        try {
            entry = SphU.entry(GETORDER_KEY);
            return "orderToMember接口";
        } catch (Exception e) {
            // 限流的情况就会进入到Exception
            return "当前访问人数过多,请稍后重试!";
        } finally {
            // SphU.entry(xxx) 需要与 entry.exit() 成对出现,否则会导致调用链记录异常
            if (entry != null) {
                entry.exit();
            }
        }
    }
}

测试效果:
在这里插入图片描述
项目启动自动加载
当SpringBoot项目启动成功之后,加载限流规则。

@Slf4j
@Component
public class SentinelApplicationRunner implements ApplicationRunner {
    /**
     * 限流规则名称
     */
    private static final String GETORDER_KEY = "orderToMember";

    @Override
    public void run(ApplicationArguments args) throws Exception {
        List<FlowRule> rules = new ArrayList<FlowRule>();
        FlowRule rule1 = new FlowRule();
        rule1.setResource(GETORDER_KEY);
        // QPS控制在1,每秒钟运行1个请求
        rule1.setCount(1);
        // QPS限流
        rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule1.setLimitApp("default");
        rules.add(rule1);
        FlowRuleManager.loadRules(rules);
        log.info(">>>限流配置加载成功<<<");
    }
}

6 使用注解形式实现对服务接口限流

@SentinelResource参数
Value:流量规则资源名称、
BlockHandler 限流/熔断出现异常执行的方法
Fallback 服务降级执行的方法
服务降级由很多原因造成:限流、熔断、接口超时、接口出现异常等,hystrix没有把异常分开,sentinel把限流/熔断独立出来。

注解形式配置管理Api限流

@RestController
@Slf4j
public class OrderService {

    /**
     * 限流规则名称
     */
    private static final String GETORDER_KEY = "orderToMember";

    /**
     * fallback 服务降级本地方法
     * blockHandler 限流/熔断出现异常执行的方法
     * value 指定资源的名称
     * @return
     */
    @SentinelResource(value = GETORDER_KEY, blockHandler = "getOrderQpsException")
    @RequestMapping("/orderToMemberSentinelResource")
    public String orderToMemberSentinelResource() {
        return "orderToMemberSentinelResource";
    }

    /**
     * 被限流后返回的提示
     * @param e
     * @return
     */
    public String getOrderQpsException(BlockException e) {
        e.printStackTrace();
        return "该接口已经被限流啦!";
    }
}

测试效果:
在这里插入图片描述

7 SpringBoot整合sentinel控制台

Sentinel 环境快速搭建
下载对应Sentinel-Dashboard jar包
下载地址:https://github.com/alibaba/Sentinel/releases/tag/1.7.1
运行执行命令
java -Dserver.port=8718 -Dcsp.sentinel.dashboard.server=localhost:8718 -Dproject.name=sentinel-dashboard -Dcsp.sentinel.api.port=8719 -jar (jar包)
访问:http://127.0.0.1:8718 默认账号密码:sentinel sentinel

SpringBoot整合Sentinel仪表盘 配置

spring:
  application:
    ## 服务名称
    name: mayikt-order
  cloud:
    nacos:
      discovery:
        ## nacos注册地址
        server-addr: 127.0.0.1:8848
    sentinel:
      transport:
        dashboard: 127.0.0.1:8718
      eager: true

运行效果:
在这里插入图片描述

8 sentinel控制台动态实现接口限流

@RestController
@Slf4j
public class OrderService {

    /**
     * 被限流后返回的提示
     * @param e
     * @return
     */
    public String getOrderQpsException(BlockException e) {
        e.printStackTrace();
        return "该接口已经被限流啦!";
    }

    /**
     * 基于控制台创建规则实现限流
     * 注意:如果没有使用@SentinelResource注解的情况下,默认的资源名称为接口路径地址
     * @return
     */
    @RequestMapping("/getOrderConsole")
    public String getOrderConsole(){
        return "getOrderConsole";
    }

    @RequestMapping("/getOrderConsole2")
    @SentinelResource(value = "getOrderConsole2", blockHandler = "getOrderQpsException")
    public String getOrderConsole2(){
        return "getOrderConsole2";
    }
}

测试效果:
在这里插入图片描述

9 sentinel控制台实现信号隔离

@RestController
@Slf4j
public class OrderService {

    /**
     * 被限流后返回的提示
     * @param e
     * @return
     */
    public String getOrderQpsException(BlockException e) {
        e.printStackTrace();
        return "该接口已经被限流啦!";
    }

    @RequestMapping("/getOrderSemaphore")
    @SentinelResource(value = "getOrderSemaphore", blockHandler = "getOrderQpsException")
    public String getOrderSemaphore() {
        try{
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info(">>>" + Thread.currentThread().getName());
        return "getOrderSemaphore";
    }
}

测试效果:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值