Demo 结构
这个 demo 主要分为部分:Ingress 流量入口以及一个 Java 示例应用。
Demo 应用是一个 Java Web 应用(Spring Boot + MyBatis),会有一些 Web 接口,里面会有一些服务调用及 DB 调用操作;同时应用也有一些模拟的自动触发的调用流量。几个 API:
/hello?name=xxx
: 可以带一个 URL 参数name
,返回值为Hello, ${name}
/time
: 返回当前时间/exception
: 随机模拟请求异常,异常的请求会返回 500/products
: 商品服务,返回当前所有商品;这个 API 会随机产生调用时长(50ms-500ms),可用于模拟慢调用/getProduct?id=xxx
: 商品服务,根据 id 返回商品信息
准备工作
- 在 ACK 集群中安装 ack-ahas-sentinel-pilot
- 在 ACK 集群中部署 demo(也可以使用自己的 Java 应用),示例 YAML:
kind: Deployment
metadata:
name: ahas-sentinel-demo
spec:
replicas: 1
selector:
matchLabels:
app: ahas-sentinel-demo
template:
metadata:
annotations:
ahasPilotAutoEnable: "on"
ahasAppName: "ahas-sentinel-demo"
labels:
app: ahas-sentinel-demo
spec:
containers:
- name: ahas-sentinel-demo
image: registry.cn-hangzhou.aliyuncs.com/sentinel-docker-repo/ahas-token-client-test:0.2.1
imagePullPolicy: Always
resources:
limits:
cpu: '2'
memory: 4Gi
requests:
cpu: '1'
memory: 4Gi
---
# 这个 ClusterIP 类型的 Service 会通过 Ingress 来透出
apiVersion: v1
kind: Service
metadata:
name: ahas-sentinel-demo-service
spec:
ports:
- name: http
port: 8088
protocol: TCP
targetPort: 8088
selector:
app: ahas-sentinel-demo
type: ClusterIP
如何接入 AHAS 流量防护:将以下 annotations 添加到 spec > template > metadata
层级下。其中 ahasAppName
代表应用名称,会展示在 AHAS 控制台上。
ahasPilotAutoEnable: "on"
ahasAppName: "ahas-sentinel-demo"
配置后,应用正常拉起,同时进入 AHAS 控制台,切到对应的 region,可以看到指定应用。
- 集群中安装 Ingress,并进行相应的配置(配置管理>配置项)。在
kube-system
命名空间下,找到nginx-configuration
这个 ConfigMap,在里面新增两个配置:
- key:
use-sentinel
, value:true
,代表开启 AHAS Ingress 防护插件。 - key:
sentinel-params
, value:--app=ahas-sentinel-ingress-demo
,为接入的 Ingress 网关指定网关名称,会展示在 AHAS Nginx/Ingress 防护控制台。
新增配置并保存后,Ingress 会自动接入到 AHAS 流量防护中。在 AHAS Nginx/Ingress 防护控制台 可以看到对应的网关。
- 配置 Ingress 路由
Demo 应用是一个 Java Web 应用,后端服务接口为 8080。我们创建一条路由,通过 Ingress 将 Web 服务暴露出来,便于我们访问。
配置好以后,我们可以用对应的域名或 IP 访问 /hello
这个路径(如 http://demo.c515327a9cb3440748abe27e9d3af47d5.cn-hangzhou.alicontainer.com/hello
这种),有成功返回则代表 ready。
Ingress 防护
将 Ingress 接入到 AHAS 流量防护后,我们进入 AHAS Nginx/Ingress 防护控制台 对应网关应用内,可以看到实时的流量访问(默认会有心跳流量)。默认 AHAS 会按 host 维度采集流量并展示监控。
我们下面来演示一下,如何自定义一组请求分组,并对这个请求分组进行监控和流控。首先我们进入“请求分组管理”页面,新建一个请求分组。这里我们给请求分组起个名,会作为资源名展示监控,规则配置也针对这个名称;同时我们配置 URL 匹配模式为“精确”,匹配串为 hello
,这个代表所有 URL path 为 /hello
的请求(严格匹配),都会计入这个请求分组,如 http://xxx.com/hello
。如果需要根据前缀来区分服务(如 /user/xxx
代表用户服务),可以考虑前缀匹配或正则匹配模式。
我们下面来演示一下,如何自定义一组请求分组,并对这个请求分组进行监控和流控。首先我们进入“请求分组管理”页面,新建一个请求分组。这里我们给请求分组起个名,会作为资源名展示监控,规则配置也针对这个名称;同时我们配置 URL 匹配模式为“精确”,匹配串为 hello
,这个代表所有 URL path 为 /hello
的请求(严格匹配),都会计入这个请求分组,如 http://xxx.com/hello
。如果需要根据前缀来区分服务(如 /user/xxx
代表用户服务),可以考虑前缀匹配或正则匹配模式。
配置完毕后,我们再通过 Ingress 请求我们刚才的 /hello
API,会发现在监控页面能看到 hello-group
这个请求分组的访问。我们给这个请求分组配置一条 QPS=300 的限流规则:
可在‘规则管理’窗口查看设置的规则
然后我们通过PTS控制台 触发请求访问:
1.进入快速压测
2.设置压测参数
3.压测中
4.防护效果
监控页面也可以看到有请求被拒绝:
Ingress 层限流后默认的行为是返回 429 状态码,目前暂时不支持通过控制台配置返回行为,后续版本会进行支持。
整个 Nginx/Ingress 防护配置的流程:
主动降级
主动降级的场景比较明确,活动前提前把一些非关键接口降级掉,直接返回特定的内容(相当于 mock 掉)。
针对其中一个 Web API(如 /time
)新建主动降级规则,在行为配置页面,选择一个 Web 行为(之前没有配过就新增),然后保存规则:
此时再触发请求,会发现请求会直接返回我们指定的状态码和内容。活动结束后,将规则关闭或删除,该 API 又可以恢复正常服务。
限流
同样找一个 Web API,在上面配置单机限流规则,并配置防护触发后的返回,然后频繁触发请求即可。比如针对 /exception
这个接口:
熔断
熔断规则建议在 consumer 侧(RPC 调用端或 SQL 客户端)配置,建议针对弱依赖服务(非核心可降级)进行配置。
- 异常熔断可以用
/exception
这个 Web 接口 - 慢调用熔断可以用
com.alibaba.csp.sentinel.demo.service.ProductService:getAllProducts()
这个模拟 RPC 接口调用(由/products
Web API 触发)
示例配置,资源名为 com.alibaba.csp.sentinel.demo.service.ProductService:getAllProducts()
:
上面的规则效果:对于这个 RPC 调用,统计维度为 20s 内的量,最小请求数目 5 代表至少这 20s 请求5次才会触发熔断规则;熔断规则的条件是,请求时长超过 100ms 的会被记为慢调用,如果这20s内慢调用的占比超过 60%,则会触发熔断。触发熔断后,该调用会直接被拒绝(默认抛异常),直到过了熔断时长 5s 以后,再来请求时会允许1个请求通过,进行探测;若请求 RT 正常,则认为远端服务已经恢复,此时对该服务的调用会恢复正常;否则会认为未恢复,重置会熔断状态。
如何决定慢调用 RT:可以通过 RT 监控进行观察,或根据业务需要进行评估
Web 热点参数流控
Web 热点参数流控可以用 /hello?name=xxx
这个 API 做示例。我们在 场景防护-Web 场景规则 中找到 /hello
这个接口(需要之前访问过),然后点右侧的“+”号,新增 Web 参数流控规则。
以下的规则示例,会针对 URL 参数里面的 name 对应的每个参数值,自动统计其中的热点访问,并分别对热点参数限制 QPS 为 1(每秒钟对应参数的请求不超过1次):
我们用一个脚本循环模拟非常多的请求参数,然后连续刷几次这个脚本(效果就是有一部分请求参数 QPS > 1):
set -e
for i in {1..10000}
do
# 这里替换成实际的域名或 IP
curl "localhost:8088/hello?name=foo${i}"
done
可以看到有几波请求被拒绝:
同时在热点参数 block 监控页面,可以看到被拒绝的 top 参数展示(交互还在优化中):
并发控制(隔离规则)
这个可以用 ab 模拟 Web 并发请求进行演示,但关键在于让客户理解以下几点:
- 并发控制可以防止某个慢调用占满整个线程池,挤占所有正常资源
- 并发数可近似由
concurrency=RT*QPS
来估算,可适当放大 - 无论核心与非核心接口都适用,一般建议在 consumer 侧(RPC 调用端或 SQL 客户端)配置