文章目录

  • 1 前言
  • 2 测试过程
  • 3 过程分析
  • 4 源码简单分析

1 前言

在1.8.0之前的版本中,Sentinel的降级策略可以选择RT,也就是平均响应时间的降级策略。从网上也能了解到基本规则就是:

平均响应时间 (DEGRADE_GRADE_RT):当资源的平均响应时间超过阈值(DegradeRule 中的 count,以 ms 为单位)之后,资源进入准降级状态。接下来如果持续进入 5 个请求,它们的 RT 都持续超过这个阈值,那么在接下的时间窗口(DegradeRule 中的 timeWindow,以 s 为单位)之内,对这个方法的调用都会自动地返回(抛出 DegradeException)。在下一个时间窗口到来时, 会接着再放入5个请求, 再重复上面的判断.

当请求处理时间较长的时候,熔断情况有时候和我的理解不太相符,所以看看到底是什么逻辑。
不过新版中RT已经被慢调用比例替代了,本篇就当满足下好奇心。水平有限,有错误还请指出。

2 测试过程

  1. 首先就先开一个SpringBoot的服务,配置Sentinel地址,处理3s:

    @GetMapping("/testa")
    public String testA() throws InterruptedException {Thread.sleep(3000);return "testA";
    }
    
  2. 然后开启Sentinel控制台,在里面给/testa资源添加降级策略:

    现在已配置的参数有:时间窗口2s,响应时间3s,响应阈值0.1s。
  3. 使用JMeter来测试,添加线程组使用Http请求测试,参数如下:

    这样就会有100个请求分10s进行发送,也就是每秒会均匀请求10次。然后启动,在Sentinel控制台中记录下了这一波请求的实时监控每秒成功和拒绝的QPS。

3 过程分析

把上面图中的各个数据提取出表格:

1s 2s 3s 4s 5s 6s 7s 8s 9s 10s 11s
通过 4 10 10 10 1 0 4 0 3 7 0
拒绝 0 0 0 0 9 10 6 10 7 3 6

每一列都是1s的时间段,并且每秒内都有10个请求,共100个请求。
绘制时间线段图进行分析。

绘图注释

  • 每秒线段上均匀分布10个请求
  • 每个请求在每0.1s的开始发送
  • 每一段表示一秒
  • 图中表格每一秒和线段每一段位置对应
  • 圆圈表示请求,里面的数字只用于标识,不是具体第几个请求
  • 图中时间窗口(StatisticNode的rollingCounterInSecond)内的请求表示处理完成后会用于计算所在bucket的avgRt

从第一期请求t1开始,由于业务需要3s来处理,所以在第一个请求结束前的期间(t1 ~ t2),Sentinel统计的平均响应时间一直是0,所以会放行所有请求。也就能看到前4秒所有的请求都通过了:


t2时刻,第一个请求结束,因为时间窗口中的bucket是复用的,响应时间3s加入到了t2时刻时间窗口的一个bucket,请求5进入时计算平均响应时间(3s / 成功请求数(此刻是1))超过阈值,开始统计接下来的请求数passCount。
到请求8时passCount为4,仍然通过,也是第5s唯一通过的请求:


请求9进入后,passCount达到5,被拒绝。这时会熔断一个时间窗口的时长2s,也可以看到在第6s内的所有请求都被拒绝:


熔断结束后,这一时刻的时间窗口内有请求10~请求16,此时avgRt直接是超过阈值的。所以直接开始计算passCount,会通过4个请求(请求17~20),对应表格中的第7s:


在第二次熔断结束的时刻,此时时间窗口内没有完成请求的记录,因为最近的有可能被记录的请求17~20还没有处理完成,所以此时avgRt是0:


对于第二次熔断之后之后的请求21~26,avgRt一直为0所以也不会计算passCount,所以全部通过,第9s内通过请求21~23共三个,请求24~26在第10s。之后在两次熔断之间的请求17处理完成,此时导致avgRt超时


和之前一样,请求27~30会通过,并计算了passCount,之后的请求31(未画出)会被拒绝并开始熔断。所以第10s内通过的有请求24~30共7个:

4 源码简单分析

完整代码可以去idea双击shift搜索对应类自己逐层进入方法,断点调试查看,会更加清晰。
熔断降级从DegradeSlot类的entry方法开始,调用了checkDegrade方法:

for (DegradeRule rule : rules) {if (!rule.passCheck(context, node, count)) {throw new DegradeException(rule.getLimitApp(), rule);}
}

这里面对每个规则检查,进入passCheck方法就是核心逻辑。这个方法返回true就是熔断状态(省略了其他两个熔断策略的代码):

在一些地方加入了输出内容的断点,在LeapArray的values方法也添加了输出断点打印当前时间窗口的两个bucket内容(格式:0: value=…, windowStart=…),不在这里展示了。

再启动一次Jmeter上文设置过的线程组,控制台打印如下,有兴趣的可以结合分析下(successCount > 0的会输出两遍相同的时间窗口内容):

23:49:05.234
0: value=p: 0, b: 0, w: 0, windowStart=23:49:05.000
1: value=p: 0, b: 0, w: 0, windowStart=23:48:31.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:05.336
0: value=p: 1, b: 0, w: 0, windowStart=23:49:05.000
1: value=p: 0, b: 0, w: 0, windowStart=23:48:31.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:05.434
0: value=p: 2, b: 0, w: 0, windowStart=23:49:05.000
1: value=p: 0, b: 0, w: 0, windowStart=23:48:31.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:05.554
0: value=p: 3, b: 0, w: 0, windowStart=23:49:05.000
1: value=p: 0, b: 0, w: 0, windowStart=23:49:05.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:05.636
0: value=p: 3, b: 0, w: 0, windowStart=23:49:05.000
1: value=p: 1, b: 0, w: 0, windowStart=23:49:05.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:05.734
0: value=p: 3, b: 0, w: 0, windowStart=23:49:05.000
1: value=p: 2, b: 0, w: 0, windowStart=23:49:05.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:05.836
0: value=p: 3, b: 0, w: 0, windowStart=23:49:05.000
1: value=p: 3, b: 0, w: 0, windowStart=23:49:05.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:05.936
0: value=p: 3, b: 0, w: 0, windowStart=23:49:05.000
1: value=p: 4, b: 0, w: 0, windowStart=23:49:05.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:06.035
0: value=p: 0, b: 0, w: 0, windowStart=23:49:06.000
1: value=p: 5, b: 0, w: 0, windowStart=23:49:05.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:06.137
0: value=p: 1, b: 0, w: 0, windowStart=23:49:06.000
1: value=p: 5, b: 0, w: 0, windowStart=23:49:05.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:06.235
0: value=p: 2, b: 0, w: 0, windowStart=23:49:06.000
1: value=p: 5, b: 0, w: 0, windowStart=23:49:05.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:06.336
0: value=p: 3, b: 0, w: 0, windowStart=23:49:06.000
1: value=p: 5, b: 0, w: 0, windowStart=23:49:05.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:06.435
0: value=p: 4, b: 0, w: 0, windowStart=23:49:06.000
1: value=p: 5, b: 0, w: 0, windowStart=23:49:05.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:06.534
0: value=p: 5, b: 0, w: 0, windowStart=23:49:06.000
1: value=p: 0, b: 0, w: 0, windowStart=23:49:06.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:06.634
0: value=p: 5, b: 0, w: 0, windowStart=23:49:06.000
1: value=p: 1, b: 0, w: 0, windowStart=23:49:06.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:06.735
0: value=p: 5, b: 0, w: 0, windowStart=23:49:06.000
1: value=p: 2, b: 0, w: 0, windowStart=23:49:06.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:06.835
0: value=p: 5, b: 0, w: 0, windowStart=23:49:06.000
1: value=p: 3, b: 0, w: 0, windowStart=23:49:06.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:06.935
0: value=p: 5, b: 0, w: 0, windowStart=23:49:06.000
1: value=p: 4, b: 0, w: 0, windowStart=23:49:06.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:07.036
0: value=p: 0, b: 0, w: 0, windowStart=23:49:07.000
1: value=p: 5, b: 0, w: 0, windowStart=23:49:06.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:07.135
0: value=p: 1, b: 0, w: 0, windowStart=23:49:07.000
1: value=p: 5, b: 0, w: 0, windowStart=23:49:06.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:07.236
0: value=p: 2, b: 0, w: 0, windowStart=23:49:07.000
1: value=p: 5, b: 0, w: 0, windowStart=23:49:06.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:07.336
0: value=p: 3, b: 0, w: 0, windowStart=23:49:07.000
1: value=p: 5, b: 0, w: 0, windowStart=23:49:06.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:07.434
0: value=p: 4, b: 0, w: 0, windowStart=23:49:07.000
1: value=p: 5, b: 0, w: 0, windowStart=23:49:06.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:07.533
0: value=p: 5, b: 0, w: 0, windowStart=23:49:07.000
1: value=p: 0, b: 0, w: 0, windowStart=23:49:07.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:07.634
0: value=p: 5, b: 0, w: 0, windowStart=23:49:07.000
1: value=p: 1, b: 0, w: 0, windowStart=23:49:07.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:07.735
0: value=p: 5, b: 0, w: 0, windowStart=23:49:07.000
1: value=p: 2, b: 0, w: 0, windowStart=23:49:07.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:07.834
0: value=p: 5, b: 0, w: 0, windowStart=23:49:07.000
1: value=p: 3, b: 0, w: 0, windowStart=23:49:07.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:07.935
0: value=p: 5, b: 0, w: 0, windowStart=23:49:07.000
1: value=p: 4, b: 0, w: 0, windowStart=23:49:07.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:08.038
0: value=p: 0, b: 0, w: 0, windowStart=23:49:08.000
1: value=p: 5, b: 0, w: 0, windowStart=23:49:07.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:08.136
0: value=p: 1, b: 0, w: 0, windowStart=23:49:08.000
1: value=p: 5, b: 0, w: 0, windowStart=23:49:07.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:08.234
0: value=p: 2, b: 0, w: 0, windowStart=23:49:08.000
1: value=p: 5, b: 0, w: 0, windowStart=23:49:07.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:08.335
0: value=p: 3, b: 0, w: 0, windowStart=23:49:08.000
1: value=p: 5, b: 0, w: 0, windowStart=23:49:07.500
successCount: 1
0: value=p: 3, b: 0, w: 0, windowStart=23:49:08.000
1: value=p: 5, b: 0, w: 0, windowStart=23:49:07.500
avgRt = 6073.0
passCount over RT: 123:49:08.434
0: value=p: 4, b: 0, w: 0, windowStart=23:49:08.000
1: value=p: 5, b: 0, w: 0, windowStart=23:49:07.500
successCount: 2
0: value=p: 4, b: 0, w: 0, windowStart=23:49:08.000
1: value=p: 5, b: 0, w: 0, windowStart=23:49:07.500
avgRt = 4551.0
passCount over RT: 223:49:08.536
0: value=p: 5, b: 0, w: 0, windowStart=23:49:08.000
1: value=p: 0, b: 0, w: 0, windowStart=23:49:08.500
successCount: 3
0: value=p: 5, b: 0, w: 0, windowStart=23:49:08.000
1: value=p: 0, b: 0, w: 0, windowStart=23:49:08.500
avgRt = 3034.0
passCount over RT: 323:49:08.636
0: value=p: 5, b: 0, w: 0, windowStart=23:49:08.000
1: value=p: 1, b: 0, w: 0, windowStart=23:49:08.500
successCount: 4
0: value=p: 5, b: 0, w: 0, windowStart=23:49:08.000
1: value=p: 1, b: 0, w: 0, windowStart=23:49:08.500
avgRt = 3036.25
passCount over RT: 423:49:08.733
0: value=p: 5, b: 0, w: 0, windowStart=23:49:08.000
1: value=p: 2, b: 0, w: 0, windowStart=23:49:08.500
successCount: 5
0: value=p: 5, b: 0, w: 0, windowStart=23:49:08.000
1: value=p: 2, b: 0, w: 0, windowStart=23:49:08.500
avgRt = 3036.6
Forbidden and cut!23:49:08.835
------cut------23:49:08.934
------cut------23:49:09.035
------cut------23:49:09.136
------cut------23:49:09.235
------cut------23:49:09.331
------cut------23:49:09.434
------cut------23:49:09.534
------cut------23:49:09.635
------cut------23:49:09.735
------cut------23:49:09.836
------cut------23:49:09.935
------cut------23:49:10.034
------cut------23:49:10.133
------cut------23:49:10.233
------cut------23:49:10.334
------cut------23:49:10.435
------cut------23:49:10.533
------cut------23:49:10.634
------cut------23:49:10.734
------cut------23:49:10.835
0: value=p: 0, b: 5, w: 0, windowStart=23:49:10.000
1: value=p: 0, b: 3, w: 0, windowStart=23:49:10.500
successCount: 8
0: value=p: 0, b: 5, w: 0, windowStart=23:49:10.000
1: value=p: 0, b: 3, w: 0, windowStart=23:49:10.500
avgRt = 3028.125
passCount over RT: 123:49:10.936
0: value=p: 0, b: 5, w: 0, windowStart=23:49:10.000
1: value=p: 1, b: 3, w: 0, windowStart=23:49:10.500
successCount: 9
0: value=p: 0, b: 5, w: 0, windowStart=23:49:10.000
1: value=p: 1, b: 3, w: 0, windowStart=23:49:10.500
avgRt = 3365.0
passCount over RT: 223:49:11.036
0: value=p: 0, b: 0, w: 0, windowStart=23:49:11.000
1: value=p: 2, b: 3, w: 0, windowStart=23:49:10.500
successCount: 5
0: value=p: 0, b: 0, w: 0, windowStart=23:49:11.000
1: value=p: 2, b: 3, w: 0, windowStart=23:49:10.500
avgRt = 3633.4
passCount over RT: 323:49:11.137
0: value=p: 1, b: 0, w: 0, windowStart=23:49:11.000
1: value=p: 2, b: 3, w: 0, windowStart=23:49:10.500
successCount: 6
0: value=p: 1, b: 0, w: 0, windowStart=23:49:11.000
1: value=p: 2, b: 3, w: 0, windowStart=23:49:10.500
avgRt = 3532.6666666666665
passCount over RT: 423:49:11.234
0: value=p: 2, b: 0, w: 0, windowStart=23:49:11.000
1: value=p: 2, b: 3, w: 0, windowStart=23:49:10.500
successCount: 7
0: value=p: 2, b: 0, w: 0, windowStart=23:49:11.000
1: value=p: 2, b: 3, w: 0, windowStart=23:49:10.500
avgRt = 3460.285714285714
Forbidden and cut!23:49:11.336
------cut------23:49:11.435
------cut------23:49:11.535
------cut------23:49:11.634
------cut------23:49:11.733
------cut------23:49:11.834
------cut------23:49:11.935
------cut------23:49:12.035
------cut------23:49:12.136
------cut------23:49:12.234
------cut------23:49:12.336
------cut------23:49:12.436
------cut------23:49:12.535
------cut------23:49:12.634
------cut------23:49:12.735
------cut------23:49:12.835
------cut------23:49:12.934
------cut------23:49:13.033
------cut------23:49:13.134
------cut------23:49:13.234
------cut------23:49:13.338
0: value=p: 0, b: 3, w: 0, windowStart=23:49:13.000
1: value=p: 0, b: 5, w: 0, windowStart=23:49:12.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:13.436
0: value=p: 1, b: 3, w: 0, windowStart=23:49:13.000
1: value=p: 0, b: 5, w: 0, windowStart=23:49:12.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:13.533
0: value=p: 2, b: 3, w: 0, windowStart=23:49:13.000
1: value=p: 0, b: 0, w: 0, windowStart=23:49:13.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:13.633
0: value=p: 2, b: 3, w: 0, windowStart=23:49:13.000
1: value=p: 1, b: 0, w: 0, windowStart=23:49:13.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:13.735
0: value=p: 2, b: 3, w: 0, windowStart=23:49:13.000
1: value=p: 2, b: 0, w: 0, windowStart=23:49:13.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:13.834
0: value=p: 2, b: 3, w: 0, windowStart=23:49:13.000
1: value=p: 3, b: 0, w: 0, windowStart=23:49:13.500
successCount: 0
avgRt = 0.0
avgRt < RT23:49:13.935
0: value=p: 2, b: 3, w: 0, windowStart=23:49:13.000
1: value=p: 4, b: 0, w: 0, windowStart=23:49:13.500
successCount: 1
0: value=p: 2, b: 3, w: 0, windowStart=23:49:13.000
1: value=p: 4, b: 0, w: 0, windowStart=23:49:13.500
avgRt = 3035.0
passCount over RT: 123:49:14.034
0: value=p: 0, b: 0, w: 0, windowStart=23:49:14.000
1: value=p: 5, b: 0, w: 0, windowStart=23:49:13.500
successCount: 2
0: value=p: 0, b: 0, w: 0, windowStart=23:49:14.000
1: value=p: 5, b: 0, w: 0, windowStart=23:49:13.500
avgRt = 3036.0
passCount over RT: 223:49:14.134
0: value=p: 1, b: 0, w: 0, windowStart=23:49:14.000
1: value=p: 5, b: 0, w: 0, windowStart=23:49:13.500
successCount: 3
0: value=p: 1, b: 0, w: 0, windowStart=23:49:14.000
1: value=p: 5, b: 0, w: 0, windowStart=23:49:13.500
avgRt = 3037.0
passCount over RT: 323:49:14.234
0: value=p: 2, b: 0, w: 0, windowStart=23:49:14.000
1: value=p: 5, b: 0, w: 0, windowStart=23:49:13.500
successCount: 4
0: value=p: 2, b: 0, w: 0, windowStart=23:49:14.000
1: value=p: 5, b: 0, w: 0, windowStart=23:49:13.500
avgRt = 3037.25
passCount over RT: 423:49:14.334
0: value=p: 3, b: 0, w: 0, windowStart=23:49:14.000
1: value=p: 5, b: 0, w: 0, windowStart=23:49:13.500
successCount: 4
0: value=p: 3, b: 0, w: 0, windowStart=23:49:14.000
1: value=p: 5, b: 0, w: 0, windowStart=23:49:13.500
avgRt = 3037.25
Forbidden and cut!23:49:14.435
------cut------23:49:14.535
------cut------23:49:14.634
------cut------23:49:14.734
------cut------23:49:14.834
------cut------23:49:14.933
------cut------23:49:15.034
------cut------23:49:15.134
------cut------

【原理/Sentinel】RT降级策略原理相关推荐

  1. Sentinel 熔断降级原理

    Sentinel 熔断降级原理 一.概述 对于熔断这个概念,我们并不陌生,比如股市熔断机制,当股指波幅达到规定的熔断点时,交易所为控制风险采取的暂停交易措施.亦或者是电流熔断,当通过的电流超出导线所能 ...

  2. sentinel 控制台讲解-降级规则-降级策略:RT

    上图表示 需要1秒持续进入至少5个请求,并且 程序的平均响应时间大于 设定的阈值,就会触发降级,打开断路器,等时间窗口结束(秒),就会关闭降级 注意 Sentinel 默认统计的 RT 上限是 490 ...

  3. 路由策略原理及配置请查收......

    路由协议在发布.接收和引入路由信息时,根据实际组网需求实施一些策略,以便对路由信息进行过滤和改变路由信息的属性,如: 1.控制路由的接收和发布 只发布和接收必要.合法的路由信息,以控制路由表的容量,提 ...

  4. 极光实时监听怎么调用_源码分析 Sentinel 实时数据采集实现原理(图文并茂)

    本篇将重点关注 Sentienl 实时数据收集,即 Sentienl 具体是如何收集调用信息,以此来判断是否需要触发限流或熔断. Sentienl 实时数据收集的入口类为 StatisticSlot. ...

  5. Redis 复制、Sentinel的搭建和原理说明(转)

    Redis 复制.Sentinel的搭建和原理说明 转自:http://www.cnblogs.com/zhoujinyi/p/5570024.html. 背景: Redis-Sentinel是Red ...

  6. _031_Redis_Redis 复制、Sentinel的搭建和原理说明

    转自https://www.cnblogs.com/zhoujinyi/p/5570024.html,感谢作者的无私分享. Redis 复制.Sentinel的搭建和原理说明 背景: Redis-Se ...

  7. Redis哨兵Sentinel的搭建和原理说明

    原文地址:http://www.cnblogs.com/zhoujinyi/p/5570024.html 背景: Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案,当用Red ...

  8. vwap 公式_VWAP算法标准VWAP策略原理

    标准VWAP策略原理 标准的VWAP策略是一种静态策略,即在交易开始之前,利用已有信息确定提交策略,交易开始之后按照此策略进行交易,而不考虑交易期间的信息. 需要买入的股票数量记为V,区间的划分与预测 ...

  9. Mysql索引原理剖析与优化策略

    Mysql索引原理剖析与优化策略 1.索引的本质  在⽣产环境中,随着数据量不断的增⻓,SQL执⾏速度会越来越慢,常⻅的⼿段就是通过索引来提升查询速度,那么究竟为什么要添加索引?应该如何正确添加索引? ...

最新文章

  1. Linux系统/boot目录破损无法启动怎么办
  2. 重磅直播 | PointDSC:基于特征匹配的点云配准方法(CVPR2021)
  3. tensorflow1.0中的改善
  4. HtmlUnit动态执行js函数
  5. ABAP-AVL-OO方法中的ALV的如何自己添加按钮及其响应
  6. Centos最小化装机网络问题
  7. 空白世界地图打印版_考研准考证打印什么时候_中国研究生招生信息网官网
  8. vsftp 虚拟用户测试
  9. 写给人类的机器学习 2.2 监督学习 II
  10. 【Flink】Flink Exceeded checkpoint tolerable failure threshold
  11. java.lang.NoClassDefFoundError: org/apache/log4j/Priority的问题解决
  12. 项目经理必须知道什么是PERT网络分析(计划评审技术)
  13. cad老是弹出命令中发生异常_打开CAD是时出现错误报告怎么解决?
  14. 安卓渗透测试工具——drozer安装使用教程
  15. linux种子搜索关键字,基于 DHT 网络的磁力链接和BT种子的搜索引擎架构
  16. FairyGUI笔记 :MovieClip(三)
  17. scanf 与 printf 输入输出函数
  18. 武汉加油!中国加油!小峯加油!大家加油!
  19. C4D R25 UV的展开与导出
  20. 一招解决A卡下载安卓模拟器问题

热门文章

  1. 【zeppelin 输出限制】ZEPPELIN_INTERPRETER_OUTPUT_LIMIT
  2. win10好使的软件
  3. php 判断文章重复率,(一)、社区反垃圾化之文字重复率检测
  4. 一加6T手机外形曝光
  5. 阿狸的童话,我的梦:伤感日志分享
  6. 一名程序员韭菜的自我修养
  7. Java,API文档
  8. ITF跆拳道考试内容
  9. iptables centos
  10. 五分钟学GIS | 室内导航