概述
摘 要
随着近些年系统稳定性要求越来越高,而系统限流则是其中提高系统稳定性的手段之一,而在众多限流平台中Sentinel凭着丰富功能特性和多次阿里双十一的线上实践,成为最热门限流平台之一,本文就Sentinel相关特性进行分析并测试并对底层原理进行分析,为后续相关系统建设积累经验。
关 键 词:
限流;熔断;自适应保护;Sentinel;流量控制
3. 应用集成测试
因Sentinel其他功能特性都是围绕着流量控制、熔断降级、自适应保护这三个点扩展而来,所以本次主要验证此3个功能点
3.1 测试环境准备
3.1.1 软件测试环境说明
硬件环境
-
中央处理器:Intel Core i7 2.5 GHz
-
内存:16GB
-
硬盘:512GB
-
显示器:NVIDIA GeForce GT 750M 2 GB 图形卡
-
网卡:100Mbit/s
软件环境
-
操作系统: mac os 10.14.6、Ubuntu Linux 14.04
-
Zookeeper:3.4.6
-
开发软件:IDEA 2020.3
-
JDK版本:1.8.0_151
-
Sentinel版本:1.8.1
3.1.2 测试架构概述
为了使调研结果能覆盖更多真实场景,因此采用单节点和多节点集成Sentinel进行测试,以下是单节点和多节点测试架构。
3.1.2.1 单节点测试架构
见图4单节点测试架构图,主要分为4部分,分别为
- 应用系统:
此系统集成Sentinel相关jar包,并提供流量控制、熔断降级、自适应保护测试接口
- 测试脚本:
用于模拟用户请求,调用应用系统提供的测试接口,三个文件分别对应三个功能接口
- Sentinel控制台服务端:
提供了机器发现以及健康管理、流量监控、限流规则管理与下发的功能,应用系统启动时会指定此服务的地址,会把相关信息进行上报,上报之后控制台也有了应用的地址信息,那么在规则下发时就能定位到具体服务实例
- Sentinel控制台WEB端
Sentinel控制台对应的WEB端,提供了图形化的界面,对应用系统服务进行规则配置、以及监控应用系统运行情况
图4 单节点测试架构,sentinel-springbot-demo为应用系统名称
3.1.2.2 多节点测试架构
见图5,多节点只是扩展应用系统部署数量以支撑更多的请求,其他配置与图4单节点测试架构一样
图5 多节点测试架构
3.1.3 测试代码说明
3.1.3.1 应用系统配置说明
见代码块1,在应用系统的application.properties文件中指定了应用的端口和名称,后续测试会请求此端口进行测试
#应用名称
spring.application.name=sentinel-springboot-demo
#应用端口
server.port=****8094
代码块1 应用系统部分配置
3.1.3.2 流量控制核心代码说明
见代码块2,在FlowService中,查看SentinelResource注解,定义资源名称为testFlow,如果未进行流控,则进入testFlow方法,返回passed,如果进行了流控进入exceptionFlowHandler方法返回block
@Service
@Slf4j
public class FlowService {
/**
* @description:流量控制测试
* @param: origin
* @return: java.lang.String
*/
@SentinelResource(value = "testFlow", entryType = EntryType.IN, blockHandler = "exceptionFlowHandler")
public String testFlow(String origin) {
//请求未被限流则进入此方法,返回passed结果
System.out.println(String.format("Passed for resource testFlow, requestDate:%s , origin is %s", LocalDateTime.now(), origin));
return "passed";
}
public String exceptionFlowHandler(String origin, BlockException ex) {
//请求被限流则进入此方法,返回block结果
System.out.println(String.format("request block error,requestDate:%s , param:%s ", LocalDateTime.now(), origin));
return "block";
}
}
代码块2 流量控制核心测试代码
见代码块3,在TestController中定义了testFlow接口,url为/testFlow,来接收http请求进行测试
@RestController
public class TestController {
@Autowired
private FlowService demoService;
/**
*
* @description:限流测试
**/
@GetMapping(value = "/testFlow")
public String testFlow(@RequestParam("origin") String origin) {
return demoService.testFlow(origin);
}
}
代码块3 流量控制测试接口
3.1.3.3 系统降级核心代码说明
见代码块4,在FlowService中,通过SentinelResource注解,定义资源名称为queryUserInfoSlowRequest,同时queryUserInfoSlowRequest方法为核心业务处理方法,在此方法中通过随机数来随机模拟接口执行耗时不稳定,执行耗时区间在40-60ms之间,具体查看sleep方法,如果大于50ms则进行次数记录,以便于测试结果比对,如果系统进行了熔断则进入exceptionHandler方法,等待一定时间后进入熔断恢复逻辑,并重置进入熔断的时间,同时为了验证结果的便捷性,提供了restSlowValue方法,对相关参数进行重置,这样可以快速验证降级结果
@Service
@Slf4j
public class FlowService {
double count = 0;
double slowRatioThreshold = 0;
double slowRatioThresholdCount = 0;
long failStartTime = 0;
/**
* @description:熔断降级测试
* @param:
* @return: java.lang.String
*/
@SentinelResource(value = "queryUserInfoSlowRequest", blockHandler = "exceptionHandler")
public String queryUserInfoSlowRequest() {
long start = System.currentTimeMillis();
++count;
if (failStartTime != 0) {
System.out.println("request fusing recovery time: " + (System.currentTimeMillis() - failStartTime) + " ms");
failStartTime = 0;
sleep(1000 * 2);
}
sleep(ThreadLocalRandom.current().nextInt(40, 60));
long end = System.currentTimeMillis();
long callTime = end - start;
//调用时间
if (callTime > 50) {
slowRatioThresholdCount += 1;
}
slowRatioThreshold = slowRatioThresholdCount / count;
System.out.println("request success time: " + (end - start) + " ms count:" + count + " slowRatioThreshold:" + slowRatioThreshold);
return "success";
}
// Block 异常处理函数,参数最后多一个 BlockException,其余与原函数一致.
public String exceptionHandler(BlockException ex) {
if (failStartTime == 0) {
failStartTime = System.currentTimeMillis();
}
System.out.println("request fusing time: " + LocalDateTime.now() + " ms");
sleep(ThreadLocalRandom.current().nextInt(5, 10));
return "Oops ";
}
//接收指定毫秒数进行休眠处理
public static void sleep(int timeMs) {
try {
TimeUnit.MILLISECONDS.sleep(timeMs);
} catch (InterruptedException e) {
// ignore
}
}
/**
* @description:重置降级的相关参数,主要为了更好复现熔断结果
* @return: java.lang.String
*/
public String restSlowValue() {
count = 0;
slowRatioThreshold = 0;
slowRatioThresholdCount = 0;
failStartTime = 0;
return "success";
}
}
代码块4 系统降级核心测试代码
见代码块5,定义queryUserInfoSlowRequest接口,url为/queryUserInfoSlowRequest,接收外部http请求进行测试,也提供了辅助测试接口restSlowValue接口,url为/restSlowValue,便于对相关参数进行重置
RestController
public class TestController {
@Autowired
private FlowService demoService;
/**
* @description:熔断降级测试
* @author: dongweizhao
* @date: 2021/6/30 3:07 下午
* @param:
* @return: void
*/
@RequestMapping(value = "/queryUserInfoSlowRequest")
public String queryUserInfoSlowRequest() {
return demoService.queryUserInfoSlowRequest();
}
/**
* @description:重置降级的相关参数,主要为了更好复现熔断结果
* @return: void
*/
@GetMapping(value = "/restSlowValue")
public String restSlowValue() {
return demoService.restSlowValue();
}
}
代码块5 系统降级测试接口
3.1.3.4 系统自适应保护核心代码说明
见代码块6,系统自适应保护是Sentinel提供的整个系统级的控制功能,只需要在控制进行配置参数,请求任意接口测试即可,秉着测试便捷性、覆盖更多场景,后续此接口会结合其他接口进行自适应保护测试,如下代码表示如果系统未进行保护则进入testSysProtect方法,打印对应字符串,返回passed,否则直接抛出系统异常
@Service
@Slf4j
public class FlowService {
/**
* @description:系统自适应保护测试接口
* @author: dongweizhao
* @date: 2022/1/29 3:03 下午
* @param: origin
* @return: java.lang.String
*/
public String testSysProtect(String origin) {
System.out.println(String.format("Passed for resource testSysProtect, requestDate:%s , origin is %s", LocalDateTime.now(), origin));
return "passed";
}
}
代码块6 系统自适应保护测试代码
见代码块7,定义testSysProtect接口,url为/testSysProtect,接收外部http请求进行测试
@RestController
public class TestController {
@Autowired
private FlowService demoService;
/**
* @description:自适应保护接口
* @author: dongweizhao
* @date: 2021/6/30 3:07 下午
* @param:
* @return: void
*/
@GetMapping(value = "/testSysProtect")
public String testSysProtect(@RequestParam("origin") String origin) {
return demoService.testSysProtect(origin);
}
}
代码块7 系统自适应保护测试接口
3.1.3.5 测试脚本说明
见图6,另存附录A中test.zip,并进行解压,会看到解压后以下脚本文件,此脚本由shell脚本语言编写,此脚本在Linux、Macos系统中通过终端命令行即可执行,Windows需要安装git或者Linux、Macos虚拟机,本论文使用Macos系统进行执行,下面就脚本一一说明
图6 附录A test.zip包含的测试脚本文件
3.1.3.5.1 start_dashboard.sh
此脚本为启动Sentinel控制台脚本,可以看到设置启动端口为8080,名称为sentinel-dashboard,并且会在脚本当前目录执行sentinel-dashboard-1.8.1.jar,所以控制台包必须与此脚本在同一目录
#!/bin/bash
nohup java -Dserver.port=****8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.1.jar &
3.1.3.5.2 start_macos.sh
此脚本为在Macos系统中启动应用系统,在启动命令中指定了Sentinel控制台的ip和端口,并且指定应用名称为sentinel-springboot-demo,并且会在脚本当前目录执行sentinel-springboot-demo.jar,所以应用系统包必须与此脚本在同一目录
#!/bin/bash
nohup java -Dcsp.sentinel.dashboard.server=127.0.0.1:8080 -Dproject.name=sentinel-springboot-demo -jar sentinel-springboot-demo.jar &
3.1.3.5.3 start_ubuntu.sh
此脚本为在Ubuntu系统中启动应用系统,在启动命令中指定了Sentinel控制台的ip和端口,因为控制台是在Masos系统进行了部署,所以ip地址需要指定Macos系统地址,其他与3.1.3.5.2章节start_macos.sh脚本一致
#!/bin/bash
nohup java -Dcsp.sentinel.dashboard.server=10.211.55.2:8080 -Dproject.name=sentinel-springboot-demo -jar sentinel-springboot-demo.jar &
3.1.3.5.4 queryUserInfoSlowRequest_local.sh
此脚本为熔断降低测试脚本,名称中local本地测试,即在Macos系统中进行测试,结合3.1.3.3章节中系统降级代码分析,首先请求了restSlowValue接口重置相关参数,紧接着在循环中持续调用queryUserInfoSlowRequest接口进行测试,注意:内容的循环次数为1000000只是为了模拟用户不间断的请求,没有其它含义
#!/bin/bash
### 基于分组规则测试脚本
curl http://127.0.0.1:8094/restSlowValue;
for (( i = **0; i < **1000000; i++ )); do
curl http://127.0.0.1:8094/queryUserInfoSlowRequest
done
3.1.3.5.5 queryUserInfoSlowRequest_remote.sh
此脚本为在Ubuntu系统测试脚本与queryUserInfoSlowRequest_local.sh作用等同,唯一的区别就是IP不同,IP地址为Ubuntu部署的应用系统IP地址
#!/bin/bash
curl http://10.211.55.5:8094/restSlowValue;
### 基于分组规则测试脚本
for (( i = **0; i < **1000000; i++ )); do
curl http://10.211.55.5:8094/queryUserInfoSlowRequest
done
3.1.3.5.6 testFlow_local.sh
此脚本为流量控制测试脚本,名称中local本地测试,即在Macos系统中进行测试,结合3.1.3.2章节中流量控制代码分析,在循环中调用testFlow接口进行测试,注意:内容的循环次数为1000000只是为了模拟用户不间断的请求,没有其它含义,请求参数origin无任何意义
#!/bin/bash
### 基于分组规则测试脚本
for (( i = **0; i < **1000000; i++ )); do
curl http://127.0.0.1:8094/testFlow?origin=appA
done
3.1.3.5.7 testFlow_remote.sh
此脚本为在Ubuntu系统测试脚本与3.1.3.5.6 testFlow_local.sh作用等同,唯一的区别就是IP不同,IP地址为Ubuntu部署的应用系统IP地址
#!/bin/bash
### 基于分组规则测试脚本
for (( i = **0; i < **1000000; i++ )); do
curl http://10.211.55.5:8094/testFlow?origin=appB
done
3.1.3.5.8 testSysProtect_local.sh
此脚本为自适应保护测试脚本,名称中local本地测试,即在Macos系统中进行测试,结合****3.1.3.4自适应保护代码分析,在循环中调用testSysProtect接口进行测试,注意:内容的循环次数为1000000只是为了模拟用户不间断的请求,没有其它含义,求参数origin无任何意义
#!/bin/bash
### 基于分组规则测试脚本
for (( i = **0; i < **1000000; i++ )); do
curl http://127.0.0.1:8094/testSysProtect?origin=appA
done
3.1.3.5.9 testSysProtect_remote.sh
此脚本为在Ubuntu系统测试脚本与testSysProtect_local.sh作用等同,唯一的区别就是IP不同,此地址为Ubuntu部署的应用系统IP地址
#!/bin/bash
### 基于分组规则测试脚本
for (( i = **0; i < **1000000; i++ )); do
curl http://10.211.55.5:8094/testSysProtect?origin=appA
done
3.1.4 控制台启动
3.1.4.1 控制台概述
此控制台为Sentinel官方提供的一个轻量级开源控制台,他提供了应用机器发现以及健康管理、流量监控、限流规则管理与下发
3.1.4.2 下载控制台jar
https://github.com/alibaba/Sentinel/releases/download/1.8.1/sentinel-dashboard-1.8.1.jar ,点击以上链接从github进行下载
3.1.4.3 启动控制台
下载附录A并解压test压缩包,拷贝****sentinel-dashboard-1.8.1.jar至test文件夹内,在终端执行"sh start_dashboard.sh"脚本启动控制台
sh start_dashboard.sh
3.1.4.4 查看启动结果
见图7,执行"tail -f nohup.out" 查询Sentinel控制台启动启动日志,如果出现Started字样,则表示启动成功
图7 Sentinel控制台启动日志
见图8图9,打开浏览器输入http://localhost:8080地址,即可打开控制台登录界面,输入sentinel/sentinel,即可登录成功。
图8 Sentinel控制台登录界面
图9 Sentinel登陆成功界面
3.1.5 应用系统启动
3.1.5.1 应用系统概述
此应用系统为了验证Sentinel特性,特此开发的测试系统,此系统基于spring-boot开发,他提供了本次论文要调研的功能特性相关集成示例和测试脚本,具体代码已存放在Github中,可自行下载,地址如下:https://github.com/dongweizhao/sentinel-springboot-demo/,为了论文调研方便性和结果的快速验证,基于部署包进行验证
3.1.5.2 应用系统部署包下载
https://github.com/dongweizhao/sentinel-springboot-demo/raw/ha/src/test/jar/sentinel-springboot-demo.jar ,点击以上链接从github进行下载
3.1.5.3 启动应用系统
拷贝sentinel-springboot-demo.jar至test文件夹内,在命令行执行"start_macos.sh"脚本启动
3.1.5.4 查看启动结果
见图10,执行"tail -f nohup.out" 查询启动日志,如果出现Started字样,则表示启动成功
图10 应用系统启动成功日志
3.2 单节点集成限流测试
3.2.1 流量控制测试
在测试程序test_script目录下,分别执行testFlow_local.sh、testFlow_remote.sh脚本
3.2.1.1 执行测试脚本
首先在test_script目录下执行testFlow_local.sh,因为Sentinel是在接受到应用的第一次访问,才进行应用信息上报
sh testFlow_local.sh
3.2.1.2 规则配置
见图11,在控制台,点击流控规则菜单,进行限流规则配置,以下表示每秒最大通过请求为5
图11 流量控制配置界面
3.2.1.3 测试结果
见图12,查看根据返回结果可以看到请求执行5次,则进行了限流
图12 流量控制限流结果,passed表示未进行限流,block表示进行了限流
3.2.1.4 总结
结果符合预期,测试通过
3.2.2 熔断降级测试
由于在流量控制应用系统信息已上报至Sentinel控制台,所以省略前面几步,从配置规则开始
3.2.2.1规则配置
见图13,在降级规则菜单中新增如下规则,在2000ms内执行请求100次,如果接口执行时间大于50ms,并且比例超过0.2,进行熔断10s
图13 限流降级配置界面
3.2.2.2执行测试脚本
在test_script目录下执行queryUserInfoSlowRequest_local.sh脚本
sh queryUserInfoSlowRequest_local.sh
3.2.2.3结果查看
执行"tail -f nohup.out "查看测试结果,见图14,可以看到次数100并且比例大于0.2时,进行了熔断
图14 限流降级日志,count表示请求次数,slowRatioThreshold表示耗时大于50ms的阈值
见图15,熔断恢复时间在10s左右,没法100%保证10s,因为系统负载还有io等等原因,只能尽可能接近
图15 熔断恢复日志,recovery time表示熔断时长
见图16,通过控制台图表可以看出熔断期间通过qps为0
图16 Sentinel控制台中限流降级监控图表
3.2.2.4总结
结果符合预期,测试通过
3.2.3 系统自适应保护测试
3.2.3.1 规则配置
由于自适应保护是系统级的,需要对所有请求的接口进行请求限流,所以Sentinel对spring boot框架进行了适配,不需要单独为每个接口配置,具体原理会在分析章节进行剖析,因此在控制台选择对应维度进行配置即可,见图17,这里选择入口QPS进行测试,因为测试结果较为直观,qps设置为2
图17 系统自适应保护配置界面
3.2.3.2 请求测试
3.2.3.2.1 单一接口请求测试
在test_script目录下执行testFlow_local.sh接口进行测试 ,见图18,执行的日志为1秒两次,多余的请求已在入口处进行拦截
图18 单接口自适应保护测试日志
见图19,图表中也能看出来每秒通过QPS为2
图19 Sentinel控制台中单接口自适应保护限流监控图表
3.2.3.2.2 多接口并发请求测试
在test_script目录下执行testFlow_local.sh testSysProtect_local.sh脚本
sh testFlow_local.sh
sh testSysProtect_local.sh
见图20,查看2个接口执行的日志分别为1秒1次,总通过为1秒2次,多余的请求已在入口处进行拦截
图20 多接口自适应保护测试日志
见图21,查看监控图表与每个接口通过qps为1,符合预期
图21 Sentinel控制台中多接口自适应保护限流监控图表
3.2.3.3 结论
通过单一接口和多接口请求测试,通过qps都与配置qps值相等,测试结果符合预期。
3.3 多节点集成限流测试
3.3.1 环境准备
使用2台节点进行测试验证,分别为:Macos与Ubuntu虚拟机
3.3.1.1 部署Ubuntu系统测试程序
见图22,拷贝测试包至Ubuntu系统的指定目录,并进行启动
图22 Ubuntu操作系统下应用系统启动日志
3.3.1.2 部署Macos系统测试程序
- 启动控制台程序
见图23,执行start_dashboard.sh脚本,启动控制台程序
图23 Macos操作系统下Sentinel控制台启动日志
- 启动测试应用系统
见图24,执行start_macos.sh脚本,启动程序
图24 Macos操作系统应用系统启动日志
3.3.2 流量控制测试
3.3.2.1 执行测试脚本
见图25,在Macos系统测试程序test_script目录下,分别执行testFlow_local.sh、testFlow_remote.sh脚本
图25 执行流量控制测试脚本
3.3.2.2 规则配置
见图26,在控制台配置,点击流控规则菜单,选择对应节点进行限流规则配置,以下表示每秒最大通过请求为6
图26 基于控制台配置流量控制
3.3.2.3 结果查看
见图27,Macos执行日志,同一秒只有6条“Passed for resource testFlow”开头日志
图27 Macos系统中流量控制测试日志,“Passed for resource testFlow”表示放行请求
见图28,Ubuntu执行日志,同一秒只有6条“Passed for resource testFlow”开头日志
图28 Ubuntu系统中流量控制测试日志
见图29,因为总共有2个节点,每个节点qps控制为6,控制台总通过qps为12
图29 控制台流量控制监控报表
3.3.2.4 总结
结果符合预期,测试通过
3.3.3 熔断降级测试
3.3.3.1 执行测试脚本
见图30,在Macos系统测试程序test_script目录下,分别执行以下脚本
sh queryUserInfoSlowRequest_local.sh
sh queryUserInfoSlowRequest_remote.sh
图30 执行熔断降级测试脚本
3.3.3.2 规则配置
见图31,在控制台配置,点击降级规则菜单,选择对应节点进行限流规则配置,在2000ms内执行请求50次,如果接口执行时间大于50ms,并且比例超过0.2,进行熔断10s
图31 基于控制台配置熔断降级
3.2.3.3 结果查看
见图32,如下图Macos系统中执行到50次并且慢调用比例大于0.2进行了熔断10s
图32 Macos系统中熔断降级测试日志,count表示请求次数,slowRatioThreshold表示耗时大于50ms的阈值,recovery time表示熔断时长
见图33,执行到50次并且慢调用比例大于0.2进行了熔断10s
图33 Ubunt系统中熔断降级测试日志
图34,通过控制台图表可以看出熔断期间通过qps为0
图34 控制台熔断降级监控报表
3.3.3.4 总结
结果符合预期,测试通过
3.3.4 系统自适应保护测试
3.3.4.1 规则配置
见图35,选择不同进行配置,qps为2
图35 基于控制台配置自适应保护
3.3.4.2 执行测试脚本
见图36,在Macos系统测试程序test_script目录下,分别执行testSysProtect_local.sh、testSysProtect_remote.sh、testFlow_local.sh、testFlow_remote.sh脚本
图36执行自适应保护测试脚本
3.3.4.3 结果查看
见图37,Macos执行日志,每秒通过请求2个
图37 Macos系统中自适应保护日志
见图38,Ubuntu执行日志,每秒通过请求2个
图38 Ubuntu系统中自适应保护日志
见图39,Sentinel控制台实时统计结果,请求2个接口,每个接口qps为2,总qps为4
图39 控制台熔断降级监控报表
3.3.4.4 总结
结果符合预期,测试通过
链接
分布式系统并发请求限流平台Sentinel功能特性调研(上篇)
作者微信
最后
以上就是犹豫期待为你收集整理的分布式系统并发请求限流平台Sentinel功能特性调研-集成测试(中篇)摘 要关 键 词:3. 应用集成测试链接作者微信的全部内容,希望文章能够帮你解决分布式系统并发请求限流平台Sentinel功能特性调研-集成测试(中篇)摘 要关 键 词:3. 应用集成测试链接作者微信所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复