Sentinel基本使用--基于QPS流量控制(二), 采用Warm Up预热/冷启动方式控制突增流量
Sentinel基本使用--基于QPS流量控制(二), 采用Warm Up预热/冷启动方式控制突增流量
一, Warm Up
Sentinel的Warm Up(RuleConstant.CONTROL_BEHAVIOR_WARM_UP
)方式,即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。warm up冷启动主要用于启动需要额外开销的场景,例如建立数据库连接等。
二, 实例
本文结合sentinel提供的示例, 通过dashboard控制台展示warm up方式启动流量曲线变化,
WarmUpFlowDemo类说明:
1 初始化基于QPS流控规则, 流控效果使用warm up; 阈值 : 1000, 预热时间60s;
- private static void initFlowRule() {
- List<FlowRule> rules = new ArrayList<FlowRule>();
- FlowRule rule1 = new FlowRule();
- rule1.setResource(KEY);
- // 这里设置QPS最大的阈值1000, 尽量设置大一点, 便于在监控台查看流量变化曲线
- rule1.setCount(1000);
- // 基于QPS流控规则
- rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
- // 默认不区分调用来源
- rule1.setLimitApp("default");
- // 流控效果, 采用warm up冷启动方式
- rule1.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_WARM_UP);
- // 在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。
- // warmUpPeriodSec 代表期待系统进入稳定状态的时间(即预热时长)。
- // 这里预热时间为1min, 便于在dashboard控制台实时监控查看QPS的pass和block变化曲线
- rule1.setWarmUpPeriodSec(60); // 默认值为10s
- rules.add(rule1);
- FlowRuleManager.loadRules(rules);
- }
2 启动一个TimerTask线程, 统计每一秒的pass, block, total这三个指标;
- static class TimerTask implements Runnable {
- @Override
- public void run() {
- long start = System.currentTimeMillis();
- System.out.println("begin to statistic!!!");
- long oldTotal = 0;
- long oldPass = 0;
- long oldBlock = 0;
- while (!stop) {
- try {
- TimeUnit.SECONDS.sleep(1);
- } catch (InterruptedException e) {
- }
- long globalTotal = total.get();
- long oneSecondTotal = globalTotal - oldTotal;
- oldTotal = globalTotal;
- long globalPass = pass.get();
- long oneSecondPass = globalPass - oldPass;
- oldPass = globalPass;
- long globalBlock = block.get();
- long oneSecondBlock = globalBlock - oldBlock;
- oldBlock = globalBlock;
- System.out.println("currentTimeMillis:" + TimeUtil.currentTimeMillis() + ", totalSeconds:"
- + TimeUtil.currentTimeMillis() / 1000 + ", currentSecond:"
- + (TimeUtil.currentTimeMillis() / 1000) % 60 + ", total:" + oneSecondTotal
- + ", pass:" + oneSecondPass + ", block:" + oneSecondBlock);
- if (seconds-- <= 0) {
- stop = true;
- }
- }
- long cost = System.currentTimeMillis() - start;
- System.out.println("time cost: " + cost + " ms");
- System.out.println("total:" + total.get() + ", pass:" + pass.get() + ", block:" + block.get());
- System.exit(0);
- }
- }
3 同时启动三个WarmUpTask线程, 设置其休眠时间小于2s, 使系统访问资源处于一个较低的流量 .
①同时启动3个WarmUpTask线程
- for (int i = 0; i < 3; i++) {
- Thread t = new Thread(new WarmUpTask());
- t.setName("sentinel-warmup-task");
- t.start();
- }
②WarmUpTask线程休眠小于2s, 通过控制休眠时间, 达到控制访问资源的流量处于一个较低的水平.
- static class WarmUpTask implements Runnable {
- @Override
- public void run() {
- while (!stop) {
- Entry entry = null;
- try {
- entry = SphU.entry(KEY);
- // token acquired, means pass
- pass.addAndGet(1);
- } catch (BlockException e1) {
- block.incrementAndGet();
- } catch (Exception e2) {
- // biz exception
- } finally {
- total.incrementAndGet();
- if (entry != null) {
- entry.exit();
- }
- }
- Random random2 = new Random();
- try {
- // 随机休眠时间<2s, 通过设置休眠时间, 模拟访问资源的流量大小
- TimeUnit.MILLISECONDS.sleep(random2.nextInt(2000));
- } catch (InterruptedException e) {
- // ignore
- }
- }
- }
- }
4 WarmUpTask线程运行20s后,再同时启动100个线程, 设置其休眠时间小于50ms, 这样就模拟造成了访问资源的流量突增, 一是可以查看后台console观察流量变化数值, 而是查看监控台的实时监控, 能比较直观的看见warm up过程.
①20s后, 再同时启动100个线程
- // 20s开始有突增的流量进来, 访问资源
- Thread.sleep(20000);
②再同时启动100个线程, 模拟突增的流量访问资源
- // 创建一个100线程, 模拟突增的流量访问被保护的资源
- for (int i = 0; i < threadCount; i++) {
- Thread t = new Thread(new RunTask());
- t.setName("sentinel-run-task");
- t.start();
- }
③RunTask线程休眠时间小于50ms, 这样每个线程就能多次的访问资源, 模拟造成资源被突增的流量访问. 这样对资源的访问流量就处于一个较高的水平.
- static class RunTask implements Runnable {
- @Override
- public void run() {
- while (!stop) {
- Entry entry = null;
- try {
- entry = SphU.entry(KEY);
- pass.addAndGet(1);
- } catch (BlockException e1) {
- block.incrementAndGet();
- } catch (Exception e2) {
- // biz exception
- } finally {
- total.incrementAndGet();
- if (entry != null) {
- entry.exit();
- }
- }
- Random random2 = new Random();
- try {
- // 随机休眠时间<50ms, 通过设置休眠时间, 模拟访问资源的流量大小
- TimeUnit.MILLISECONDS.sleep(random2.nextInt(50));
- } catch (InterruptedException e) {
- // ignore
- }
- }
- }
- }
三, 后台console端每秒展示pass, block, total数据.
①从下图可以很明显的看出, 有一个很明显的流量激增, total由原来的几或者几十, 突然增加到了4000左右, 而pass也是陡然的增加到了几百, block也由原来的0变成了3500左右.
②接着往下看, 由于我们设置的阈值为1000, 所以最终的pass值是稳定在1000没有问题; 流控效果采用warm up方式, pass的值不是一下子增加到1000, 而是由300-->400-->500-->600-->700-->800-->900-->1000逐渐增加的.
③最终QPS流量稳定在最大阈值1000, 如下图:
四, dashboard控制台流量曲线展示
① 下图展示的是, 访问资源的流量刚开始处于一个较低的水平, QPS大概只有3左右;
②下图可以明显的看到绿曲线p_qps是一个逐渐上升的过程, 代表着访问资源的流量逐渐变大, 最终稳定在阈值1000QPS.
③下图, 展示的是38分51秒左右, 经过60s的预热, QPS最终达到阈值1000.
完整代码:
- public class WarmUpFlowDemo {
- private static final String KEY = "abc";
- private static AtomicInteger pass = new AtomicInteger();
- private static AtomicInteger block = new AtomicInteger();
- private static AtomicInteger total = new AtomicInteger();
- private static volatile boolean stop = false;
- private static final int threadCount = 100;
- private static int seconds = 60 + 40;
- public static void main(String[] args) throws Exception {
- initFlowRule();
- // trigger Sentinel internal init
- Entry entry = null;
- try {
- entry = SphU.entry(KEY);
- } catch (Exception e) {
- } finally {
- if (entry != null) {
- entry.exit();
- }
- }
- Thread timer = new Thread(new TimerTask());
- timer.setName("sentinel-timer-task");
- timer.start();
- // first make the system run on a very low condition
- // 创建3个线程, 模拟一个系统处于一个低水平流量
- for (int i = 0; i < 3; i++) {
- Thread t = new Thread(new WarmUpTask());
- t.setName("sentinel-warmup-task");
- t.start();
- }
- // 20s开始有突增的流量进来, 访问资源
- Thread.sleep(20000);
- /*
- * Start more thread to simulate more qps. Since we use {@link RuleConstant.CONTROL_BEHAVIOR_WARM_UP} as {@link
- * FlowRule#controlBehavior}, real passed qps will increase to {@link FlowRule#count} in {@link
- * FlowRule#warmUpPeriodSec} seconds.
- */
- // 创建一个100线程, 模拟突增的流量访问被保护的资源
- for (int i = 0; i < threadCount; i++) {
- Thread t = new Thread(new RunTask());
- t.setName("sentinel-run-task");
- t.start();
- }
- }
- private static void initFlowRule() {
- List<FlowRule> rules = new ArrayList<FlowRule>();
- FlowRule rule1 = new FlowRule();
- rule1.setResource(KEY);
- // 设置最大阈值为20
- // rule1.setCount(20);
- // 这里设置QPS最大的阈值1000, 便于查看变化曲线
- rule1.setCount(1000);
- rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
- rule1.setLimitApp("default");
- rule1.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_WARM_UP);
- // 在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。
- // warmUpPeriodSec 代表期待系统进入稳定状态的时间(即预热时长)。
- // 这里预热时间为1min, 便于在dashboard控制台实时监控查看QPS的pass和block变化曲线
- rule1.setWarmUpPeriodSec(60); // 默认值为10s
- rules.add(rule1);
- FlowRuleManager.loadRules(rules);
- }
- static class WarmUpTask implements Runnable {
- @Override
- public void run() {
- while (!stop) {
- Entry entry = null;
- try {
- entry = SphU.entry(KEY);
- // token acquired, means pass
- pass.addAndGet(1);
- } catch (BlockException e1) {
- block.incrementAndGet();
- } catch (Exception e2) {
- // biz exception
- } finally {
- total.incrementAndGet();
- if (entry != null) {
- entry.exit();
- }
- }
- Random random2 = new Random();
- try {
- // 随机休眠时间<2s, 通过设置休眠时间, 模拟访问资源的流量大小
- TimeUnit.MILLISECONDS.sleep(random2.nextInt(2000));
- } catch (InterruptedException e) {
- // ignore
- }
- }
- }
- }
- static class RunTask implements Runnable {
- @Override
- public void run() {
- while (!stop) {
- Entry entry = null;
- try {
- entry = SphU.entry(KEY);
- pass.addAndGet(1);
- } catch (BlockException e1) {
- block.incrementAndGet();
- } catch (Exception e2) {
- // biz exception
- } finally {
- total.incrementAndGet();
- if (entry != null) {
- entry.exit();
- }
- }
- Random random2 = new Random();
- try {
- // 随机休眠时间<50ms, 通过设置休眠时间, 模拟访问资源的流量大小
- TimeUnit.MILLISECONDS.sleep(random2.nextInt(50));
- } catch (InterruptedException e) {
- // ignore
- }
- }
- }
- }
- static class TimerTask implements Runnable {
- @Override
- public void run() {
- long start = System.currentTimeMillis();
- System.out.println("begin to statistic!!!");
- long oldTotal = 0;
- long oldPass = 0;
- long oldBlock = 0;
- while (!stop) {
- try {
- TimeUnit.SECONDS.sleep(1);
- } catch (InterruptedException e) {
- }
- long globalTotal = total.get();
- long oneSecondTotal = globalTotal - oldTotal;
- oldTotal = globalTotal;
- long globalPass = pass.get();
- long oneSecondPass = globalPass - oldPass;
- oldPass = globalPass;
- long globalBlock = block.get();
- long oneSecondBlock = globalBlock - oldBlock;
- oldBlock = globalBlock;
- System.out.println("currentTimeMillis:" + TimeUtil.currentTimeMillis() + ", totalSeconds:"
- + TimeUtil.currentTimeMillis() / 1000 + ", currentSecond:"
- + (TimeUtil.currentTimeMillis() / 1000) % 60 + ", total:" + oneSecondTotal
- + ", pass:" + oneSecondPass + ", block:" + oneSecondBlock);
- if (seconds-- <= 0) {
- stop = true;
- }
- }
- long cost = System.currentTimeMillis() - start;
- System.out.println("time cost: " + cost + " ms");
- System.out.println("total:" + total.get() + ", pass:" + pass.get() + ", block:" + block.get());
- try {
- TimeUnit.SECONDS.sleep(60);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- System.exit(0);
- }
- }
- }
要想在将变化数据展示在dashboard控制台, 启动时需要配置:
-Dcsp.sentinel.dashboard.server=127.0.0.1:8080
-Dcsp.sentinel.api.port=8719
-Dproject.name=WarmUpFlowDemo
具体接入dashboard, 可参考上一篇博客, Sentinel基本使用--基于QPS流量控制(一), 采用默认快速失败/直接拒绝策略控制超过阈值的流量(结合Dashboard使用)
五, 总结
上面主要讲述了QPS流量控制, 采用Warm Up预热/冷启动方式控制突增流量, 通过在后台console观察数据以及结合dashboard图表的形式, 能很清晰的了解到warm up冷启动方式控制突增流量, 保护资源, 维护系统的稳定性的.
Sentinel基本使用--基于QPS流量控制(二), 采用Warm Up预热/冷启动方式控制突增流量的更多相关文章
- 3. Sentinel源码分析— QPS流量控制是如何实现的?
Sentinel源码解析系列: 1.Sentinel源码分析-FlowRuleManager加载规则做了什么? 2. Sentinel源码分析-Sentinel是如何进行流量统计的? 上回我们用基于并 ...
- Sentinel Dashboard(基于1.8.1)流控规则持久化到Nacos——涉及部分Sentinel Dashboard源码改造
前言 之前虽然也一直在使用sentinel实现限流熔断功能,但却没有好好整理之前看的源码与资料,今天有时间将之前自己整理过的资料写成一篇博文,或者是是一篇关于Sentinel(基于目前最近版本1.8, ...
- [github项目]基于百度地图二次开发实现的车辆监管(包含车辆定位、车辆图片和方向控制,电子围栏,图形绘制等功能)前端实现(不包含后端实现)
前言:基于百度地图javascript版本开发,百度地图中所用的key已承诺仅用于测试,不用于商业用途 注:本文所有代码可以到github上进行下载,github地址:http://map.eguid ...
- ASP.NET Core中使用IOC三部曲(二.采用Autofac来替换IOC容器,并实现属性注入)
前言 本文主要是详解一下在ASP.NET Core中,自带的IOC容器相关的使用方式和注入类型的生命周期. 这里就不详细的赘述IOC是什么 以及DI是什么了.. emm..不懂的可以自行百度. 目录 ...
- 基于Zxing的二维码的二维码扫描之横屏扫描
最近项目条码扫描要改为横屏,网上所搜了一下,然后发现我写的需要改动几行代码就可以了,还是很给力的. 如未查看之前的代码,请移步: 基于Zxing的二维码生成和二维码扫描 修改下面写代码就可以实现横屏条 ...
- 深入理解基于selenium的二次开发
对于做web端自动化测试的人来说,可能接触selenium比QTP还要多,但是我们在做基于selenium的二次开发的时候,经常会说到二次开发是为了易于维护,很多人可能不懂得维护的价值是什么,和到底要 ...
- 基于zxing的二维码(网格)扫描
基于zxing的二维码(网格)扫描 前言:对于二维码扫描我们使用的是开源框架Zxing或者Zbar,这里使用基于zxing的二维码扫描,类似支付宝网格扫描, 二维码原理介绍: 二维码是用某种特定的几何 ...
- Kvm虚拟化的一种打包及部署方案(采用tar包,lvm方式)
Kvm虚拟化的一种打包部署方案(采用tar包,lvm方式) –-–-–-2016年终总结 一 毕业之后跟师兄学到的第一块主要内容,理解花了不少时间.期间经历了shell的入门.linux基础知识入门. ...
- 基于MVC4+EasyUI的Web开发框架形成之旅--权限控制
我在上一篇随笔<基于MVC4+EasyUI的Web开发框架形成之旅--框架总体界面介绍>中大概介绍了基于MVC的Web开发框架的权限控制总体思路.其中的权限控制就是分为“用户登录身份验证” ...
随机推荐
- linux IP 网关配置
1. 关闭selinux 与防火墙 在虚拟机装好之后之后,先关闭selinux与防火墙 关闭selinx,重启生效 vim /etc/selinux/config 修改 SELINUX=disable ...
- koa 基础(二十)nodejs 操作mongodb数据库 --- 新增数据
1.app.js /** * nodejs 操作mongodb数据库 * 1.安装 操作mongodb * cnpm install mongodb --save * 2.引入 mongodb 下面的 ...
- Struts2.3+Spring3.2+Hibernate4.2框架搭建
一.环境 SSH使用的版本:struts2.3.14.spring3.2.2.hibernate4.2.0 数据库:MYSQL tomcat版本:apache-tomcat-7.0.42 二.所需要导 ...
- [go]net/http
常用方法 r.Method == "GET" time.Now().Format("2006-01-02 15:04:05") //文件操作 os.Create ...
- Linux 关机/重启命令
Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE MicrosoftInternetExplorer4 /* Style Definiti ...
- springBoot整合spring、springMVC、mybatis
前文 1.为什么使用springBoot 众所周知,spring是Java在搭建后台时非常实用的框架,其整合了市场上几乎所有的主流框架于一体,使后端编程更加高效.快速: 而SpringBoot更是把s ...
- JAVA处理链表经典问题
定义链表节点Node class Node { private int Data;// 数据域 private Node Next;// 指针域 public Node(int Data) { // ...
- Java 中nextLine()方法没有执行直接跳过解决办法
使用Java的Scanner类nextLne()方法从显示器输入数据时,nextInt()后面的nextLine()直接跳过没有执行: 截图:第三个输入直接跳过 通过上网的查找我终于发现了问题出在哪里 ...
- jenkins介绍及其简单操作
一.jenkins简介 Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能. Jenkins功能包 ...
- zabbix(1)基础知识
一.工作原理 一个监控系统运行的大概的流程是这样的: zabbix agent需要安装到被监控的主机上,它负责定期收集各项数据,并发送到zabbix server端,zabbix server将数据存 ...