如何基于 Nacos 和 Sentinel ,实现灰度路由和流量防护一体化
技术干货每日送达!
封装远程配置中心和本地规则文件的读取逻辑,即优先读取远程配置,如果不存在或者规则错误,则读取本地规则文件。动态实现远程配置中心对于规则的热刷新;
封装 NacosDataSource 和 ApolloDataSource ,支持 Nacos 和 Apollo 两个远程配置中心,零代码实现 Sentinel 功能。更多的远程配置中心,请参照 Sentinel 官方的 DataSource 并自行集成;
支持原生的流控规则、降级规则、授权规则、系统规则、热点参数流控规则;
支持微服务侧 Actuator、Swagger 和 Rest 三种方式的规则写入;
支持控制台侧基于微服务名的 Actuator、Swagger 和 Rest 三种方式的批量规则写入;
支持开关关闭上述功能
spring.application.strategy.sentinel.enabled=true ,默认是关闭的。
环境搭建及依赖引入
<dependency>
<groupId>com.nepxion</groupId>
<artifactId>discovery-plugin-strategy-starter-service-sentinel</artifactId>
<version>${discovery.version}</version>
</dependency>
<dependency>
<groupId>com.nepxion</groupId>
<artifactId>discovery-plugin-strategy-sentinel-starter-nacos</artifactId>
<!-- <artifactId>discovery-plugin-strategy-sentinel-starter-apollo</artifactId> -->
<version>${discovery.version}</version>
</dependency>
原生 Sentinel 注解
@RestController
@ConditionalOnProperty(name = DiscoveryConstant.SPRING_APPLICATION_NAME, havingValue = "discovery-guide-service-b")
public class BFeignImpl extends AbstractFeignImpl implements BFeign {
private static final Logger LOG = LoggerFactory.getLogger(BFeignImpl.class);
@Override
@SentinelResource(value = "sentinel-resource", blockHandler = "handleBlock", fallback = "handleFallback")
public String invoke(@PathVariable(value = "value") String value) {
value = doInvoke(value);
LOG.info("调用路径:{}", value);
return value;
}
public String handleBlock(String value, BlockException e) {
return value + "-> B server sentinel block, cause=" + e.getClass().getName() + ", rule=" + e.getRule() + ", limitApp=" + e.getRuleLimitApp();
}
public String handleFallback(String value) {
return value + "-> B server sentinel fallback";
}
}
原生 Sentinel 规则
1. Nacos的Key格式:Group为元数据中配置的[组名],Data Id为[服务名]-[规则类型]
2. Apollo的Key格式:[组名]-[服务名]-[规则类型]
流控规则
[
{
"resource": "sentinel-resource",
"limitApp": "default",
"grade": 1,
"count": 1,
"strategy": 0,
"refResource": null,
"controlBehavior": 0,
"warmUpPeriodSec": 10,
"maxQueueingTimeMs": 500,
"clusterMode": false,
"clusterConfig": null
}
]
降级规则
[
{
"resource": "sentinel-resource",
"limitApp": "default",
"count": 2,
"timeWindow": 10,
"grade": 0,
"passCount": 0
}
]
授权规则
[
{
"resource": "sentinel-resource",
"limitApp": "discovery-guide-service-a",
"strategy": 0
}
]
系统规则
[
{
"resource": null,
"limitApp": null,
"highestSystemLoad": -1.0,
"highestCpuUsage": -1.0,
"qps": 200.0,
"avgRt": -1,
"maxThread": -1
}
]
热点参数流控规则
[
{
"resource": "sentinel-resource",
"limitApp": "default",
"grade": 1,
"paramIdx": 0,
"count": 1,
"controlBehavior": 0,
"maxQueueingTimeMs": 0,
"burstCount": 0,
"durationInSec": 1,
"paramFlowItemList": [],
"clusterMode": false
}
]
基于灰度路由和 Sentinel-LimitApp 扩展的防护机制
基于服务名的防护机制
spring.application.strategy.service.sentinel.request.origin.key=n-d-service-id
[
{
"resource": "sentinel-resource",
"limitApp": "discovery-guide-service-a",
"strategy": 0
}
]
基于灰度组的防护机制
spring.application.strategy.service.sentinel.request.origin.key=n-d-service-group
[
{
"resource": "sentinel-resource",
"limitApp": "my-group",
"strategy": 0
}
]
基于灰度版本的防护机制
spring.application.strategy.service.sentinel.request.origin.key=n-d-service-version
[
{
"resource": "sentinel-resource",
"limitApp": "1.0",
"strategy": 0
}
]
基于灰度区域的防护机制
spring.application.strategy.service.sentinel.request.origin.key=n-d-service-region
[
{
"resource": "sentinel-resource",
"limitApp": "dev",
"strategy": 0
}
]
基于机器地址和端口的防护机制
spring.application.strategy.service.sentinel.request.origin.key=n-d-service-address
[
{
"resource": "sentinel-resource",
"limitApp": "192.168.0.88:8081,192.168.0.88:8082",
"strategy": 0
}
]
自定义业务参数的组合式防护机制
// 版本号+用户名,实现组合式熔断
public class MyServiceSentinelRequestOriginAdapter extends DefaultServiceSentinelRequestOriginAdapter {
@Override
public String parseOrigin(HttpServletRequest request) {
String version = request.getHeader(DiscoveryConstant.N_D_SERVICE_VERSION);
String user = request.getHeader("user");
return version + "&" + user;
}
}
@Bean
public ServiceSentinelRequestOriginAdapter ServiceSentinelRequestOriginAdapter() {
return new MyServiceSentinelRequestOriginAdapter();
}
[
{
"resource": "sentinel-resource",
"limitApp": "1.0&zhangsan",
"strategy": 0
}
]
基于 Swagger 的 Sentinel 规则推送
基于单个服务实例的 Sentinel 规则推送
基于服务名对应的多个服务实例的 Sentinel 规则推送
干货分享
•001:《Java并发与高并发解决方案》学习笔记;•002:《深入JVM内核——原理、诊断与优化》学习笔记;•003:《Java面试宝典》•004:《Docker开源书》•005:《Kubernetes开源书》•006:《DDD速成(领域驱动设计速成)》•007:全部•008:加技术讨论群
近期热文
••••••
想知道更多?长按/扫码关注我吧↓↓↓喜欢就点个"在看"呗^_^