如何基于 Nacos 和 Sentinel ,实现灰度路由和流量防护一体化
基于Alibaba Nacos和Sentinel,实现灰度路由和流量防护一体化的解决方案,发布在最新的 Nepxion Discovery 5.4.0 版,具体参考:
源码主页,请访问 源码主页
指南主页,请访问 指南主页
文档主页,请访问 文档主页
Nepxion Discovery框架在实现灰度发布和路由功能前提下,结合Nacos和Sentinel,对流量再实施一层防护措施,更能达到企业级的流量安全控制的目的。它的功能包括:
- 封装远程配置中心和本地规则文件的读取逻辑,即优先读取远程配置,如果不存在或者规则错误,则读取本地规则文件。动态实现远程配置中心对于规则的热刷新
- 封装NacosDataSource和ApolloDataSource,支持Nacos和Apollo两个远程配置中心,零代码实现Sentinel功能。更多的远程配置中心,请参照Sentinel官方的DataSource并自行集成
- 支持原生的流控规则、降级规则、授权规则、系统规则、热点参数流控规则
- 支持扩展LimitApp的机制,通过动态的Http Header方式实现组合式防护机制,包括基于服务名、基于灰度组、基于灰度版本、基于灰度区域、基于机器地址和端口等防护机制,支持自定义任意的业务参数组合实现该功能,例如,根据传入的微服务灰度版本号+用户名,组合在一起进行熔断
- 支持微服务侧Actuator、Swagger和Rest三种方式的规则写入
- 支持控制台侧基于微服务名的Actuator、Swagger和Rest三种方式的批量规则写入
- 支持开关关闭上述功能spring.application.strategy.sentinel.enabled=true,默认是关闭的
[Nacos] 阿里巴巴中间件部门开发的新一代集服务注册发现中心和配置中心为一体的中间件。它是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施,支持几乎所有主流类型的“服务”的发现、配置和管理,更敏捷和容易地构建、交付和管理微服务平台
[Sentinel] 阿里巴巴中间件部门开发的新一代以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性的分布式系统的流量防卫兵。它承接了阿里巴巴近10年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等
环境搭建及依赖引入
服务端在Discovery框架原有依赖的基础上,再引入如下依赖
<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注解
参照下面代码,为接口方法增加@SentinelResource注解,value为sentinel-resource,blockHandler和fallback是防护其作用后需要执行的方法
@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规则
Sentinel在配置中心订阅的Key格式,如下:
1. Nacos的Key格式:Group为元数据中配置的[组名],Data Id为[服务名]-[规则类型]
2. Apollo的Key格式:[组名]-[服务名]-[规则类型]
Sentinel规则的用法,请参照Sentinel官方文档
流控规则
增加服务discovery-guide-service-b的规则,Group为discovery-guide-group,Data Id为discovery-guide-service-b-sentinel-flow,规则内容如下:
[
{
"resource": "sentinel-resource",
"limitApp": "default",
"grade": 1,
"count": 1,
"strategy": 0,
"refResource": null,
"controlBehavior": 0,
"warmUpPeriodSec": 10,
"maxQueueingTimeMs": 500,
"clusterMode": false,
"clusterConfig": null
}
]
如图所示
降级规则
增加服务discovery-guide-service-b的规则,Group为discovery-guide-group,Data Id为discovery-guide-service-b-sentinel-degrade,规则内容如下:
[
{
"resource": "sentinel-resource",
"limitApp": "default",
"count": 2,
"timeWindow": 10,
"grade": 0,
"passCount": 0
}
]
如图所示
授权规则
增加服务discovery-guide-service-b的规则,Group为discovery-guide-group,Data Id为discovery-guide-service-b-sentinel-authority,规则内容如下:
[
{
"resource": "sentinel-resource",
"limitApp": "discovery-guide-service-a",
"strategy": 0
}
]
如图所示
系统规则
增加服务discovery-guide-service-b的规则,Group为discovery-guide-group,Data Id为discovery-guide-service-b-sentinel-system,规则内容如下:
[
{
"resource": null,
"limitApp": null,
"highestSystemLoad": -1.0,
"highestCpuUsage": -1.0,
"qps": 200.0,
"avgRt": -1,
"maxThread": -1
}
]
如图所示
热点参数流控规则
增加服务discovery-guide-service-b的规则,Group为discovery-guide-group,Data Id为discovery-guide-service-b-sentinel-param-flow,规则内容如下:
[
{
"resource": "sentinel-resource",
"limitApp": "default",
"grade": 1,
"paramIdx": 0,
"count": 1,
"controlBehavior": 0,
"maxQueueingTimeMs": 0,
"burstCount": 0,
"durationInSec": 1,
"paramFlowItemList": [],
"clusterMode": false
}
]
如图所示
基于灰度路由和Sentinel-LimitApp扩展的防护机制
该方式对于上面5种规则都有效,这里以授权规则展开阐述
授权规则中,limitApp,如果有多个,可以通过“,”分隔。"strategy": 0 表示白名单,"strategy": 1 表示黑名单
基于服务名的防护机制
修改配置项Sentinel Request Origin Key为服务名的Header名称,修改授权规则中limitApp为对应的服务名,可实现基于服务名的防护机制
配置项,该配置项默认为n-d-service-id,可以不配置
spring.application.strategy.service.sentinel.request.origin.key=n-d-service-id
增加服务discovery-guide-service-b的规则,Group为discovery-guide-group,Data Id为discovery-guide-service-b-sentinel-authority,规则内容如下,表示所有discovery-guide-service-a服务允许访问discovery-guide-service-b服务
[
{
"resource": "sentinel-resource",
"limitApp": "discovery-guide-service-a",
"strategy": 0
}
]
基于灰度组的防护机制
修改配置项Sentinel Request Origin Key为灰度组的Header名称,修改授权规则中limitApp为对应的组名,可实现基于组名的防护机制
配置项
spring.application.strategy.service.sentinel.request.origin.key=n-d-service-group
增加服务discovery-guide-service-b的规则,Group为discovery-guide-group,Data Id为discovery-guide-service-b-sentinel-authority,规则内容如下,表示隶属my-group组的所有服务都允许访问服务discovery-guide-service-b
[
{
"resource": "sentinel-resource",
"limitApp": "my-group",
"strategy": 0
}
]
基于灰度版本的防护机制
修改配置项Sentinel Request Origin Key为灰度版本的Header名称,修改授权规则中limitApp为对应的版本,可实现基于版本的防护机制
配置项
spring.application.strategy.service.sentinel.request.origin.key=n-d-service-version
增加服务discovery-guide-service-b的规则,Group为discovery-guide-group,Data Id为discovery-guide-service-b-sentinel-authority,规则内容如下,表示版本为1.0的所有服务都允许访问服务discovery-guide-service-b
[
{
"resource": "sentinel-resource",
"limitApp": "1.0",
"strategy": 0
}
]
基于灰度区域的防护机制
修改配置项Sentinel Request Origin Key为灰度区域的Header名称,修改授权规则中limitApp为对应的区域,可实现基于区域的防护机制
配置项
spring.application.strategy.service.sentinel.request.origin.key=n-d-service-region
增加服务discovery-guide-service-b的规则,Group为discovery-guide-group,Data Id为discovery-guide-service-b-sentinel-authority,规则内容如下,表示区域为dev的所有服务都允许访问服务discovery-guide-service-b
[
{
"resource": "sentinel-resource",
"limitApp": "dev",
"strategy": 0
}
]
基于机器地址和端口的防护机制
修改配置项Sentinel Request Origin Key为灰度区域的Header名称,修改授权规则中limitApp为对应的区域值,可实现基于机器地址和端口的防护机制
配置项
spring.application.strategy.service.sentinel.request.origin.key=n-d-service-address
增加服务discovery-guide-service-b的规则,Group为discovery-guide-group,Data Id为discovery-guide-service-b-sentinel-authority,规则内容如下,表示地址和端口为192.168.0.88:8081和192.168.0.88:8082的服务都允许访问服务discovery-guide-service-b
[
{
"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方式进行适配类创建
@Bean
public ServiceSentinelRequestOriginAdapter ServiceSentinelRequestOriginAdapter() {
return new MyServiceSentinelRequestOriginAdapter();
}
增加服务discovery-guide-service-b的规则,Group为discovery-guide-group,Data Id为discovery-guide-service-b-sentinel-authority,规则内容如下,表示版本为1.0且传入的Http Header的user=zhangsan,同时满足这两个条件下的所有服务都允许访问服务discovery-guide-service-b
[
{
"resource": "sentinel-resource",
"limitApp": "1.0&zhangsan",
"strategy": 0
}
]
运行效果
- 当传递的Http Header中user=zhangsan,当全链路调用中,API网关负载均衡discovery-guide-service-a服务到1.0版本后再去调用discovery-guide-service-b服务,最终调用成功
如图所示
- 当传递的Http Header中user=lisi,不满足条件,最终调用在discovery-guide-service-b服务端被拒绝掉
如图所示
- 当传递的Http Header中user=zhangsan,满足条件之一,当全链路调用中,API网关负载均衡discovery-guide-service-a服务到1.1版本后再去调用discovery-guide-service-b服务,不满足version=1.0的条件,最终调用在discovery-guide-service-b服务端被拒绝掉
如图所示
基于Swagger的Sentinel规则推送
分为基于单个服务实例和基于服务名对应的多个服务实例的Sentinel规则推送
基于单个服务实例的Sentinel规则推送
直接访问该服务实例的Swagger主页即可
如图所示
基于服务名对应的多个服务实例的Sentinel规则推送
需要开启discovery-console服务,并访问其Swagger主页即可
如图所示
作者介绍:任浩军, 10 多年开源经历,Github ID:@HaojunRen,Nepxion 开源社区创始人,Nacos Group Member,Spring Cloud Alibaba & Nacos & Sentinel Committer ,曾就职于平安银行平台架构部,负责银行 PaaS 系统基础服务框架研发。
王伟华, 10 余年 Java 开发,Github ID:@vipweihua,对微服务架构研究多年,当前更多关注于微服务中的网关、限流熔断、灰度路由等,现就职于平安银行平台架构部,从事银行 PaaS 系统基础服务框架研发。
阿里云双11领亿元补贴,拼手气抽iPhone 11 Pro、卫衣等好礼,点此参与:http://t.cn/Ai1hLLJT
本文作者:任浩军
本文为云栖社区原创内容,未经允许不得转载。
如何基于 Nacos 和 Sentinel ,实现灰度路由和流量防护一体化的更多相关文章
- 双剑合璧 Nacos 结合 Sentinel 实现流量安全控制
Alibaba Sentinel 是一款高性能且轻量级的流量控制.熔断降级解决方案.是面向分布式服务架构的高可用流量控制组件. Sentinel 官网:https://sentinelguard.io ...
- 基于 Istio 的全链路灰度方案探索和实践
作者|曾宇星(宇曾) 审核&校对:曾宇星(宇曾) 编辑&排版:雯燕 背景 微服务软件架构下,业务新功能上线前搭建完整的一套测试系统进行验证是相当费人费时的事,随着所拆分出微服务数量的不 ...
- Nacos系列:基于Nacos的注册中心
前言 所谓注册中心,其实是分布式架构演进过程中的产物,在系统中充当一个协调者的角色.但是,为什么需要这样一个协调者的角色呢?我们先来看一个例子,以便理解为什么分布式架构中需要有注册中心. 案例 小明和 ...
- Nacos系列:基于Nacos的配置中心
前言 在看正文之前,我想请你回顾一下自己待过的公司都是怎么管理配置的,我想应该会有以下几种方式: 1.硬编码 没有什么配置不配置的,直接写在代码里面,比如使用常量类 优势:对开发友好,开发清楚地知道代 ...
- Spring Cloud Alibaba生态探索:Dubbo、Nacos及Sentinel的完美结合
@ 目录 背景 一.项目框架 1.1 采用IDEA和Maven多模块进行项目搭建 1.2 模块管理及版本管理 二.微服务公共接口 2.1 定义一个公共接口Api 2.2 pom.xml 2.3 Goo ...
- spring cloud 实现基于Nacos权重的负载均衡
package com.water.step.service.user.nacos; import com.alibaba.nacos.api.exception.NacosException; im ...
- 基于nacos注册中心的ribbon定制规则
前面说到基于nacos的注册发现有可以扩展实现我们自己的负载均衡算法(Nacos数据模型),来实现同集群调用,是基于spring.cloud.nacos.discovery.cluster-name参 ...
- 流量染色与gRPC服务托管 微服务协作开发、灰度发布之流量染色 灰度发布与流量染色
大规模微服务场景下灰度发布与流量染色实践 https://mp.weixin.qq.com/s/UBoRKt3l91ffPagtjExmYw [go-micro]微服务协作开发.灰度发布之流量染色 - ...
- 基于Opentracing+Jaeger全链路灰度调用链
当网关和服务在实施全链路分布式灰度发布和路由时候,我们需要一款追踪系统来监控网关和服务走的是哪个灰度组,哪个灰度版本,哪个灰度区域,甚至监控从Http Header头部全程传递的灰度规则和路由策略.这 ...
随机推荐
- leetcode-165周赛-1275-找出井字棋的获胜者
题目描述: 自己的提交: class Solution: def tictactoe(self, moves: List[List[int]]) -> str: p = [[0] * 3 for ...
- django 邮箱发送
在django中提供了邮件接口 QQ邮箱配置 qq邮箱地扯:https://mail.qq.com settings文件 # 邮箱配置 EMAIL_USE_SSL = True EMAIL_HOST ...
- PHPCMS如何修改网站名称,网站关键词,网站描述
首先需要登录网站后台,填写管理员用户名密码之后,点击登 点击phpcms后台顶部的"设置"按钮,如下图所示. 然后点击"相关设置"下的"站点管理&qu ...
- 使用Ueditor点击上传图片时显示延迟的问题
最近在做一个项目,需要用到Ueditor,但是在点击上传图片的时候,总是隔了4-5秒才显示文件框 查了一些资料,最后发现,只需在 修改:(1) dialog/images/image.js 把imag ...
- 【Flutter学习】页面布局之列表和表格处理
一,概述 Flutter中拥有30多种预定义的布局widget,常用的有Container.Padding.Center.Flex.Row.Colum.ListView.GridView.按照< ...
- Linux系统之-介绍,主要特性
Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户.多任务.支持多线程和多CPU的操作系统.它能运行主要的UNIX工具软件.应用程序和网络协议.它支持32位 ...
- GIT上传下载报错:[You do not have permission to pull from the repository]的解决方案!
第一步:打开我的电脑 第二步:选择此电脑,右击弹出框点击属性进入控制面板 第三步:进入控制面板 第四步:搜索管理凭据 第五步:编点击右侧按钮,进行编辑用户名和密码的操作添加凭据 git:https:/ ...
- jquery+javascript触发a标签的点击事件
今天项目经理跟我说window.open()在一些浏览器上会被拦截,当时的解决方案是:用a标签的target="_blank"属性也可以打开窗体页面 于是解决了A问题出现了B问题: ...
- *.tar 用 tar –xvf 解压 *.gz 用 gzip -d或者gunzip 解压 *.tar.gz和*.tgz 用 tar –xzf 解压 *.bz2 用 bzip2 -d或者用bunzip2 解压 、*.tar.bz2用tar –xjf 解压
解压: 1.*.tar 用 tar –xvf 解压, --skip-old-files跳过已经存在的文件,压缩用tar -cvf 2.*.bz2 用 bzip2 -d或者用bunzip2 解压 3.* ...
- Jmeter 5.1命令行执行bat文件
一.编写run_jmeter,bat @echo off::设置参数::参考命令:jmeter -n -t d:\123.jmx -l result.jtl -e -o d:\report\repor ...