Sentinel的业务需要

背景分析

在一些节日中,例如京东、淘宝、拼多多、格物等平台参与商品秒杀、抢购以及一些优惠活动,也会在节假日使用车票等等都会引起服务器流量的暴涨,导致网页无法显示,app反应慢,甚至引起整个网站的崩溃。

当业务的负载过重时,为了保证各种业务安全运营,就需要限流、熔断、降级等措施来保护的系统,需要控制流量适用,需要sentinel技术

sentinel概述

sentinel(分布式系统的流量方卫兵)是阿里开源的一套用于服务容错的综合性解决方案。随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统自适应保护等多个维度来帮助您保障微服务的稳定性。

#启动sentinel

一、下载jar包

https://github.com/alibaba/Sentinel/releases

二、在cmd中运行代码

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

三、访问sentinel,通过浏览器进行访问 

http://localhost:8180

 sentinel使用

一、添加依赖

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

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

二、配置application.yml文件,添加sentinel配置

spring:
  cloud:
    sentinel:
      transport:
         port: 8099 #跟sentinel控制台交流的端口,随意指定一个未使用的端口即可
         dashboard: localhost:8180 # 指定sentinel控制台地址。

三、访问路径以及运行结果

 sentinel限流策略

 阈值类型分析

  • QPS(Queries Per Second):当调用相关url对应的资源时,QPS达到单机阈值时,就会限流。

  • 线程数:当调用相关url对应的资源时,线程数达到单机阈值时,就会限流。

 

 QPS:  每秒请求次数  

单机阈值:允许每秒请求的次数

注:下图处理过的数据

 二、关联限流

当关联的资源达到阈值,就限流自己 (操作:连续输出doRestEcho2,快速点击doRestEcho1,就会造成现在的状况)

简述:当关联资源doRestEcho2的访问量过大时,doRestEcho1就被限流了

 

 三、链路限流

链路模式只记录指定链路入口的流量。也就是当多个服务对指定资源调用时,假如流量超出了指定阈值,则进行限流。被调用的方法用@SentinelResource进行注解,然后分别用不同业务方法对此业务进行调用,假如A业务设置了链路模式的限流,在B业务中是不受影响的。例如现在设计一个业务对象,代码如下(为了简单,可以直接写在启动类内部):
 

@Service
public class ConsumerService {
    /**@SentinelResource
     * */
    @SentinelResource
    public String doGetResource() {
        return "Get resource";
    }
}

接下来我们在/consumer/doRestEcho1对应的方法中对ConsumerService中的doGetResource方法进行调用(应用consumerService对象之前,要先在doRestEcho01方法所在的类中进行consumerService值的注入)。例如:

 //http://ip:port/consumer/doRestEcho1
        @GetMapping("/consumer/doRestEcho1")
        public String doRestEcho1() {
            consumerService.doGetResource();
            System.out.println("==doRestEcho1()==");
            //调用服务提供方API(http://ip:port/path)
            //1.定义要调用的API
            String url =
                    "http://localhost:8081/provider/echo/" + appName;
            //2.谁去访问这个API? restTemplate;
            return restTemplate
                    .getForObject(url,
                            String.class);
        }

说明,流控模式为链路模式时,假如是sentinel 1.7.2以后版本,Sentinel Web过滤器默认会聚合所有URL的入口为sentinel_spring_web_context,因此单独对指定链路限流会不生效,需要在application.yml添加如下语句来关闭URL PATH聚合,例如:

sentine降级策略

一、慢调用比例

 慢调用指耗时大于阈值RT(Response Time)的请求称为慢调用,阈值RT由用户设置。

 慢调用逻辑中的状态分析如下:

熔断(OPEN):请求数大于最小请求数并且慢调用的比率大于比例阈值则发生熔断,熔断时长为用户自定义设置。
探测(HALFOPEN):当熔断过了定义的熔断时长,状态由熔断(OPEN)变为探测(HALFOPEN)。
关闭(CLOSED):如果接下来的一个请求小于最大RT,说明慢调用已经恢复,结束熔断,状态由探测(HALF_OPEN)变更为关闭(CLOSED),如果接下来的一个请求大于最大RT,说明慢调用未恢复,继续熔断,熔断时长保持一致
注意:Sentinel默认统计的RT上限是4900ms,超出此阈值的都会算作4900ms,若需要变更此上限可以通过启动配置项-Dcsp.sentinel.statistic.max.rt=xxx来配置

代码:

//AtomicLong 类支持线程安全的自增自减操作
        private AtomicLong along = new AtomicLong(1);
       @GetMapping("/consumer/doRestAlong")
       public  String doRestAlong() throws InterruptedException {
           //获取自增对象的值,然后再加1
           long num = along.getAndIncrement();
           //模拟50%的慢调用比例
           if (num%2 ==0) {
               Thread.sleep(200);
           }
           String url="http://localhost:8081/provider/echo/"+appName;
           //远程过程调用-RPC
           return restTemplate.getForObject(url,String.class);//String.class调用服务响应数据类型
       }


熔断策略为慢调用比例,表示链路请求数超过3时,假如平均响应时间假如超过200毫秒的有50%,则对请求进行熔断,熔断时长为10秒钟,10秒以后恢复正常。

 

二、异常比例

系统提供了默认的异常处理机制,假如默认处理机制不满足我们需求,我们可以自己进行定义。定义方式上可以直接或间接实现BlockExceptionHandler接口,并将对象交给spring管理。

 

@Component
public class ServiceBlockExceptionHandler implements BlockExceptionHandler {
    /**
     * 一旦服务被限流或者降级了,sentinel系统的提供拦截器会
     * 调用此方法对异常
     */
    @Override
    public void handle(HttpServletRequest httpServletRequest,
                       HttpServletResponse httpServletResponse,
                       BlockException e) throws Exception {
        //设置响应数据的编码
//      httpServletResponse.setCharacterEncoding("UTF-8");
        //告诉客户端要响应的数据类型以及客户端以什么编码呈现数据
//      httpServletResponse.setContentType("text/html;charset=utf8");
        httpServletResponse.setContentType("application/json;charset=utf-8");
        PrintWriter out = httpServletResponse.getWriter();
        Map<String,Object> map = new HashMap<>();
        map.put("status", 429);
        if (e instanceof DegradeException) {//降级、熔断
//            out.println("服务暂时不可用");
            map.put("Message", "服务不可用");
        } else {
//            out.println("<h2>访问太频繁,稍等片刻</h2>");
            map.put("message", "访问太频繁");
        }
        //将map对象转换为json格式字符串
        String jsonStr = new ObjectMapper().writeValueAsString(map);
        out.println(jsonStr);
        out.flush();
    }
}

原理:

在这里插入图片描述

 异常比例中的状态分析如下:

熔断(OPEN):当请求数大于最小请求并且异常比例大于设置的阈值时触发熔断,熔断时长由用户设置。
探测(HALFOPEN):当超过熔断时长时,由熔断(OPEN)转为探测(HALFOPEN)
关闭(CLOSED):如果接下来的一个请求未发生错误,说明应用恢复,结束熔断,状态由探测(HALF_OPEN)变更为关闭(CLOSED)。如果接下来的一个请求继续发生错误,说明应用未恢复,继续熔断,熔断时长保持一致。
 

三、异常数量

当资源近1分钟的异常数目超过阈值(异常数)之后会进行服务降级。注意,由于统计时间窗口是分钟级别的,若熔断时长小于60s,则结束熔断状态后仍可能再次进入熔断状态。其属性说明如下:

 sentinel热点策略

热点参数限流会统计传入参数中的热点数据,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。其中,Sentinel会利用 LRU 策略统计最近最常访问的热点参数,结合令牌桶算法来进行参数级别的流控。

 //http://ip:port/consumer/doFindById?id=10
        @GetMapping("/consumer/findById")
        @SentinelResource("res")
        public String doFindById(@RequestParam("id") Integer id){
            return "resource id is "+id;
        }

在这里插入图片描述

在这里插入图片描述

热点规则的限流模式只有QPS模式(这才叫热点)。参数索引为@SentinelResource注解的方法参数下标,0代表第一个参数,1代表第二个参数。单机阈值以及统计窗口时长表示在此窗口时间超过阈值就限流。

系统所报的异常:

com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException: 2

 sentinel特定参数策略

在这里插入图片描述

 这里表示参数值为5时阈值为100,其它参数值阈值为1,例如当我们访问http://ip:port/consumer/doRestEcho1?id=5时的限流阈值为100。

sentinel系统保护规则

Sentinel的系统保护规则是从应用级别的入口流量进行控制,从单台机器的总体 Load、RT、入口 QPS 、线程数和CPU使用率五个维度监控应用数据,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。如图所示:

 在这里插入图片描述

 Load(仅对 Linux/Unix-like 机器生效):当系统 load1 超过阈值,且系统当前的并发线程数超过系统容量时才会触发系统保护。系统容量由系统的 maxQps * minRt 计算得出。设定参考值一般是 CPU cores * 2.5。
CPU使用率:当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0)。
RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。
系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量生效。入口流量指的是进入应用的流量(EntryType.IN),比如 Web 服务。

sentinel授权规则

在业务需要时限制资源是否通过,这时候可以使用 Sentinel 的黑白名单控制的功能。黑白名单根据资源的请求来源(origin)限制资源是否通过,若配置白名单则只有请求来源位于白名单内时才可通过;若配置黑名单则请求来源位于黑名单时不通过,其余的请求通过。例如微信中的黑名单。
在这里插入图片描述

资源名:即限流规则的作用对象

流控应用:对应的黑名单/白名单中设置的规则值,多个值用逗号隔开.

授权类型:白名单,黑名单(不允许访问)

案例实现:

定义请求解析器,用于对请求进行解析,并返回解析结果,sentinel底层 在拦截到用户请求以后,会对请求数据基于此对象进行解析,判定是否符合黑白名单规则

可以通过参数名、请求ip、请求头来授权黑白名单

@Component
public class DefaultRequestOriginParser implements RequestOriginParser {
    @Override
    public String parseOrigin(HttpServletRequest httpServletRequest) {
        //获取请求参数数据,参数名可以自己写 例如origin,然后基于参数值做黑白名单
        //http://ip:port/path?origin=app
//        String origin = httpServletRequest.getParameter("origin");
//        return origin;
       //获取访问请求中的ip地址,基于ip地址进行黑白名单设计
//        String ip = httpServletRequest.getRemoteAddr();
//        System.out.println("ip"+ip);
//        return ip;
        //获取请求头中的数据,基于请求头中token值进行限流统计
        String token = httpServletRequest.getHeader("token");
        return token;
    }//授权规则中的黑白名单的值,来自此方法的返回值
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值