- 使用 Spring Initializr 创建 Spring Boot 应用程序
- 在Spring Boot中配置Cassandra
- 在 Spring Boot 上配置 Tomcat 连接池
- 将Camel消息路由到嵌入WildFly的Artemis上
在上一节中我们知道Sentinel 支持以下几种规则:流量控制规则、熔断降级规则、系统保护规则、来源访问控制规则 和 热点参数规则。
Sentinel 的所有规则都可以在内存态中动态地查询及修改,修改之后立即生效。同时 Sentinel 也提供相关 API,供您来定制自己的规则策略
本篇文章我们来看一下Sentinel的流量控制规则
**流量控制(Flow Control)**其原理是监控应用流量的 QPS 或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。
限流的直接表现是在执行流控的时候抛出 FlowException
异常。FlowException
是 BlockException
的子类,我们可以捕捉 BlockException
来自定义被限流之后的处理逻辑。
同一个资源可以对应多条限流规则。FlowSlot
会对该资源的所有限流规则依次遍历,直到有规则触发限流或者所有规则遍历完毕。
一条限流规则主要由下面几个因素组成,我们可以组合这些元素来实现不同的限流效果。
Field | 说明 | 默认值 |
---|---|---|
resource | 资源名,资源名是限流规则的作用对象 | |
count | 限流阈值 | |
grade | 限流阈值类型,QPS 或线程数模式 | QPS 模式 |
limitApp | 流控针对的调用来源 | default ,代表不区分调用来源 |
strategy | 调用关系限流策略:直接、链路、关联 | 根据资源本身(直接) |
controlBehavior | 流控效果(直接拒绝 / 排队等待 / 慢启动模式),不支持按调用关系限流 | 直接拒绝 |
流量控制主要有两种统计类型,一种是统计线程数,另外一种则是统计 QPS。类型由 grade
字段来定义。
打开我们的Sentinel DashBoard界面,在侧边栏菜单的簇点链路
中找到我们需要流控的资源,我们这里是/test/hello
,点击后面的+流控
按钮,即可打开新增流控规则的界面。如下图所示
在新增流控规则的窗口中我们直接展开高级选项(这里暂时不讨论集群方式),如下图所示:
我们也可以在流控规则菜单中点击新增流控规则
,只不过这种方式弹出的新增窗口的资源名要自己指定
我们这里先做一个简单的流控测试,我们将单机阈值
直接设置为1,其余保持默认;按照这样的配置如果一秒内的请求数大于1那么资源就会被直接流控,抛出Blocked by Sentinel (flow limiting)
异常。如下图所示:
线程数限流用于保护业务线程数不被耗尽。例如,当应用所依赖的下游应用由于某种原因导致服务不稳定、响应延迟增加,对于调用者来说,意味着吞吐量下降和更多的线程数占用,极端情况下甚至导致线程池耗尽。为应对高线程占用的情况,业内有使用隔离的方案,比如通过不同业务逻辑使用不同线程池来隔离业务自身之间的资源争抢(线程池隔离),或者使用信号量来控制同时请求的个数(信号量隔离)。这种隔离方案虽然能够控制线程数量,但无法控制请求排队时间。当请求过多时排队也是无益的,直接拒绝能够迅速降低系统压力。Sentinel线程数限流不负责创建和管理线程池,而是简单统计当前请求上下文的线程个数,如果超出阈值,新的请求会被立即拒绝。
我们直接打开新增流控规则
窗口,阈值类型选择并发线程数,单机阈值设置为2。如下图所示:
并发线程数测试我们需要使用JMeter来模拟线程进行压力测试,有关JMeter的使用可以参考文章压力测试工具JMeter的简单使用
我们新建一个线程组,在启动的时候同时发送10个请求,如下所示:
我们点击菜单栏上方绿色的启动按钮启动测试,在结果树中查看执行结果,如下图所示:
在新增流控规则
界面的高级选项中有一项流控模式可供选择,分别是直接
、关联
和链路(后期专门介绍链路,本文不具体展开)
当配置资源在运行过程中超过当前规则配置的阈值之后对该资源请求做相应的流控效果。上面基于QPA/并发数的流量控制
与并发线程数流量控制
中的小试牛刀就是基于这种方式处理的
当配置资源在运行过程中超过当前配置规则配置的阈值之后对他所关联的资源请求做相应的流控效果。对于该迷失的效果请看下面的实例
我们修改TestController.java
,在里面我们新增方法sayBye(),然后重启系统。如下图所示:
/**
* @Author Christy
* @Date 2021/8/6 10:17
**/
@RestController
@RequestMapping("/test")
public class TestController {
private static final Logger log = LoggerFactory.getLogger(TestController.class);
@RequestMapping("/hello")
public String sayHello(){
log.info("Hello, Sentinel!");
return "Hello, Sentinel!";
}
@RequestMapping("/bye")
public String sayBye(){
log.info("Bye, Sentinel!");
return "Bye, Sentinel!";
}
}
我们修改前面的柜子,流控模式选择关联,关联资源写/test/bye
,流控效果(后面讲)暂时选快速失败
我们修改JMeter中的线程组,设置循环每秒钟发送10个请求,如下图所示:
修改http请求路径为/test/bye
,如下图所示:
启动JMeter测试,结果如下所示:
从图中我们可以看到对于关联资源/test/bye
可以正常访问,但是对于资源/test/hello
却被限流了,所以对于关联模式这是一种反向流控:当被关联资源达到阈值,会对资源进行流控
当配置资源在运行过程中超过当前配置规则的阈值后对链路中的资源直接抛出失败。这种模式在后面我们单独拿出来讲,这里先忽略。
流控效果选项只是针对QPS来说的,如果我们将阈值类型选择并发线程数
的话可以看到是没有流控效果这一选项的
上面我们演示的例子效果都是直接拒绝,这里就不说了。
我们修改流控规则,阈值类型选择QPS
,单机阈值为10
,流控效果为Warm Up
,预热时长为20
,如下图所示:
通俗一点讲就是我们设置的阈值是10,预热时长是20。那么当大量请求同时涌入系统时,系统会经过20秒钟的预热才会一次处理10个请求,在20秒钟之内先期可能会处理3个、5个、8个再至10个
我们修改线程组线程数为15/s,一直发送。如下图所示:
http请求路径修改为最开始的/test/hello
,如下图所示:
然后们启动JMeter发送请求,注意观察IDEA的控制台输出。
在刚开始的几秒中内每次只请求三次,如下图所示
运行到第6~8秒的时候QPS由4增加到5
在超出20秒以后QPS趋于稳定为10
匀速排队模式就相对简单了。JMeter我们不做改动,按照下图修改规则
这里的超时时间是毫秒,而Warm Up的预热时间单位是秒,这里要注意
控制台每秒打印输出的次数就是我们设置的阈值,这就是匀速排队的效果。
本系列专题源码已经上传至gitee:https://gitee.com/tide001/springcloud_parent,欢迎下载交流
有没有其他方法可以直接使用 terraform 启用这些规则,而无需在 GCP 中创建单独的防火墙规则,然后将标签附加到计算引擎 目前我正在这样做 resource "google_compu
全民国家安全日活动 免费抽随机话费、流量 微信打开链接进入活动 下拉页面点击【我要抽奖】进去完成两个任务获得两次抽奖机会 可抽2-10元话费以及流量 抽奖非必中 仅限移动用户参与 活动期间内每日
随着人们的紧凑生活,从事互联网行业的人大多都把一天的时间安排的满满的,这用户忙碌的时候,根本无心去关注你的推广,只有抓住了用户零零碎碎的时间对其进行推广,同时他也能打发无聊的时间,这样的效果就非常轻
我建立了一个库来做 IGMP 的东西。现在,愚蠢的是,我的图书馆还进行了存在监控以确保其他人仍然是该组的一部分。 IGMP 在较低级别做完全相同的事情。分开消息,轮询路由器它仍然是同一组的一部分,整个
我经营一个具有广告集成功能的媒体网站。最近,我们发现很多人滥用这一点,通过在上传内容上进行流量交换来获取虚假收入。最流行的可能是使用 HitLeap Viewer 应用程序的 HitLeap。 我很好
上下文: 所以我在 AKS 集群中有一个测试脚本;此脚本使用 Azure Active Directory 中的用户的单点登录功能登录到站点。 测试脚本位于集群 A 中,站点位于集群 B 中。还为集群
是否可以指示 Fiddler 仅显示定向到特定主机名的流量?也就是说Fiddler流量可以针对Host进行过滤吗? 最佳答案 请参阅此屏幕截图。位于屏幕的右上方 关于fiddler - 过滤 Fidd
这个问题在这里已经有了答案: Android 8: Cleartext HTTP traffic not permitted (36 个回答) 2年前关闭。 我正在从事一个项目,但我被困在登录/注册页
我有一个 Android VOIP 应用程序。由于某些网络会阻止 VOIP 流量,因此我想找到一些绕过阻止的方法。我认为 VPN 可以做到这一点,但没有任何 VPN 解决方案可以轻松实现。使用 And
我构建了使用 SignalR 的服务器和客户端代码。该网站运行良好,但我在任何浏览器(chrome、IE、Firefox)中都看不到网络流量。我知道网络流量在那里,因为该网站正在运行。 有没有办法在浏
我实现了一个自制的嗅探器(基于 winpcap),并尝试在浏览 HTTPS 网站(gmail 和 facebook)时使用它来嗅探 TCP 连接上的端口 443,但我的代码无法检测到任何流量。 我研究
是否可以使用 Android 手机收集同一小区内手机的 IMEI 或唯一手机 ID?可能已经有一些 hack 可以使用 osmocom ...我正在寻找的是一个易于工作的解决方案来扫描交通(通过计算汽
此 Android 代码是否是在通话期间测试 http 网络可用性的正确方法,或者它是否排除了应包含的网络,反之亦然: public boolean isOnline() { Telephon
我需要能够加密从 Web 服务器到数据库服务器的 MySQL 流量。我知道如何根据 my.cnf 中的服务器和客户端设置将 MySQL 设置为使用 SSL,但是,这需要使用 PHP 中的 mysql_
我想查看所有传出 USB 的流量,并可能根据内容策略阻止进出 USB 的数据交易。这将如何完成?有什么方法可以在 C# 中实现此目的,还是它更像是 C++ 类型的问题? 最佳答案 您可以使用类似 Cr
我需要捕获进程进行的 TCP 通信。但是,我不能只运行该进程,查找其 PID,然后捕获。我需要获取启动后立即发生的通信。 它显然是通过未知端口(不是 80)向另一个进程发出 JSON 请求,该进程注册
如果我有一个名为 www.testsite.com 的页面,并且我使用 url 中的查询字符串链接到该页面,是否可以以某种方式将相同的查询字符串附加到所有传出链接/流量? 例如,假设我像这样链接到该页
我在我的机器上运行本地 HTTP 代理服务器并执行一些日志记录。我也想记录 SSL 流量。为此,我运行了另一个用 Python 编写的代理服务器,它充当 SSL 服务器,带有我的自签名证书,HTTP
我正在编写一个应该检测 VPN 流量的程序。据我了解这个主题,似乎隧道协议(protocol)的检测就像防火墙规则一样容易,使用它们的专用端口: PPTP: 端口 1723/TCP OpenVPN:端
所以,情况是:我想知道程序将请求发送到什么路径。使用 Wireshark,我只能知道它发送的是 https 请求和相应的域,但不知道路径。 我认为即使不破解程序也可以至少检查出站 https 流量。
我是一名优秀的程序员,十分优秀!