若对 Sentinel 还没有一个认知,可以参考前面的博文。
本文主要讲解 Sentinel 容错功能之一 流量控制 。
需要启动好 Sentinel 控制台,以及监控一个消费者。
若对这一步有疑虑,请参考SpringCloud Alibaba - Sentinel入门案例(一)。
流量控制,其原理是监控应用流量的QPS(每秒查询率) 或并发线程数等指标,当达到指定的阈值时
对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。
当我们点击 簇点链路 选择相对应的资源名,点击 +流控,就可为需要的资源添加流控规则。
以下做一个简单的介绍:
对于简单的配置而言,有两个默认项:
至于什么是流控模式,什么是流控效果,后续会讲解。
首先我们选择QPS,单机阈值填写2,点击新增 。
添加成功后我们可以到流控规则里面查看我们设置的流控。
由于这边我们QPS选择了阈值为2,意思是。这个请求路径,每秒只允许2个请求。超出会使用流控效果。而简单配置的流控效果是快速失败。
配置完成,当我快速请求服务的时候,会出现 Blocked by Sentinel (flow limiting) ps(这个可更改,后续讲解)。
接下来尝试点击线程数,阈值也是为2。这句话的意思是:这个请求路径,只允许两个线程访问,否则出发流控。
修改相应的配置,点击启动,这时候我们通过浏览器再次访问,也会出现Blocked by Sentinel (flow limiting)。
sentinel共有三种流控模式,分别是:
直接流控模式是最简单的模式,当指定的接口达到限流条件时开启限流。前面的两个案例都是默认直接流控。
关联流控模式指的是,当指定接口关联的接口达到限流条件时,开启对指定接口开启限流。
前面的例子都是对当前的请求服务进行流控规则的新增,而流控模式中的关联,可以使得其它的请求服务达到阈值,本服务进行流控。
由于关联的服务达到了阈值,所以触发了流控,导致增加规则的本服务无法访问。
上图是关联服务的监控情况,下图是本服务的访问情况。
这边需要诉苦一下,太难了啊,翻了几篇别人写的博客,要嘛写的不清不楚,要嘛干脆就没写,自己折腾了半天,最后还是买了某培训机构的课程才看明白,太难了啊。
上面有提到资源名称默认是请求路径,这个其实是可以更改的,只需要在方法上加上注解
@SentinelResource("value")
修改后,value 的值就是簇点链路的显示的资源名。
链路流控模式指的是,当从某个接口过来的资源达到限流条件时,开启限流。它的功能有点类似于针对
来源配置项,区别在于:针对来源是针对上级微服务,而链路流控是针对上级接口,也就是说它的粒度更细。
这样说的可能不好理解,我来上图,我在控制层有两个方法,同时调用了同一个接口。
这时候我们就可以对这个资源名为 message 的进行链路。
此时的路口资源就是
当入口资源达到阈值的时候,就会启动此资源名为 message 的对应路口资源的流控。
坑来了,不生效了啊我了个亲娘哎。弄了半天,在一个培训视频上看到了解决方案,亲测有效。
从1.6.3 版本开始,Sentinel Web filter默认收敛所有URL的入口context,因此链路限流不生效。
1.7.0 版本开始(对应SCA的2.1.1.RELEASE),官方在CommonFilter 引入了WEB_CONTEXT_UNIFY 参数,用于控制是否收敛context。将其配置为 false 即可根据不同的URL 进行链路限流。
SCA 2.1.1.RELEASE之后的版本,可以通过配置spring.cloud.sentinel.web-context-unify=false即可关闭收敛,我们当前使用的版本是SpringCloud Alibaba 2.1.0.RELEASE,无法实现链路限流。
目前官方还未发布SCA 2.1.2.RELEASE,所以我们只能使用2.1.1.RELEASE,需要写代码的形式实现。
package com.example.nacos.demo.config;
import com.alibaba.csp.sentinel.adapter.servlet.CommonFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FilterContextConfig {
@Bean
public FilterRegistrationBean sentinelFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new CommonFilter());
registration.addUrlPatterns("/*");
// 入口资源关闭聚合
registration.addInitParameter(CommonFilter.WEB_CONTEXT_UNIFY, "false");
registration.setName("sentinelFilter");
registration.setOrder(1);
return registration;
}
}
分别通过两个路口资源进行访问,发现设置的入口资源被限流了。
前面的例子流控效果是默认为快速失败,更改效果,就是更改当流控规则触发的时候,结果的处理。这个不好截图演示,就不演示了。