限流模拟

简介: 限流模拟

作为后端程序员日常工作中难免会遇到要跟消息队列打交道的时候,而且在当下微服务的场景下,很多服务的性能不是我们自己能控制的。

这不阿粉最近就遇到了一个场景,由于上游服务流量增加,发送到消息队列的消息增多,阿粉在处理消息的时候需要依赖下游的一个服务,可是谁想到下游的服务效率太差,消息太多处理不过来,CPU 居高不下。

看过我们昨天文章的小伙伴应该都知道,这个时候我们就需要进行限流了,为了避免将下游的服务打垮,我们来进行单机限流操作。这里我们来模拟一下操作过程,首先我们通过一段伪代码来模拟大流量,然后通过配置 sentinel 的控制台来配置规则从而实现单机 QPS 20 的限制。

创建 SpringBoot 服务

首先我们创建一个 SpringBoot 服务,在 pom.xml 文件中增加下面的配置
image.png
然后我们提供一个对外的 http 接口,通过访问接口来触发我们的限流代码,接口代码如下

代码如下:

package com.example.demo.controller;

import com.alibaba.csp.sentinel.SphO;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class LoginController {

  @GetMapping(value = "/login")
  public void login(String username, String password) {
    System.out.println("login");
    //模拟一百万条消息
    for (int i = 0; i < 1000000; i++) {
      boolean entry = false;
      try {
        entry = SphO.entry("HelloWorld");
        while (!entry) {
          try {
            Thread.sleep(50);
            System.out.println("entry false");
            entry = SphO.entry("HelloWorld");
          } catch (InterruptedException e) {

          }
        }
        System.out.println("entry true");
      } catch (Exception e) {

      } finally {
        if (entry) {
          SphO.exit();
        }
      }
    }
  }
}

调用接口过后,通过循环一百万次来模拟大流量,这里我们要解释以下几个内容

1.SphO.entry("HelloWorld"):是 Sentinel 的资源控制器,"HelloWord" 是资源的名称,资源 是 sentinel 的一个很重要的概念,所有的限流都是针对资源的操作;SphO.entry() 返回值是布尔值,为 true 表示资源可用,没有被限流,为 false 表示资源被限流;
2.这里模拟在被限流了过后,程序等待一段时间,再去判断是否限流,只有在资源未被限流的时候,才能继续处理;
3.微信图片_20220514093216.jpg
在 finally 里面需要进行 SphO.exit(); 操作,当被限流了以后,也就是SphO.entry() == true 后一定要执行 SphO.exit(); 否则代码会创建多个Entry 对象,程序运行时间长了过后会导致内存泄露,引发 FullGC。
这个时候我们启动一个服务,调用一下接口,可以看到效果如下,很快就会运行完,并没有达到限流的效果,那是因为我们此刻还没有配置限流规则,所以没有触发到限流的逻辑。微信图片_20220514093216.jpg

配置 sentinel 控制台

接下来我们安装一下 sentinel 的控制台,通过控制台来配置限流规则,从而达到限流的目的,控制台的搭建很简单,我们通过官方地址下载指定版本的 jar 然后本地运行即可。通过地址 https://github.com/alibaba/Sentinel/releases/download/1.8.4/sentinel-dashboard-1.8.4.jar 进行下载。

然后通过命令

java -Dserver.port=8081 -Dcsp.sentinel.dashboard.server=localhost:8081 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.4.jar

运行即可,如下所示e1e5adb9d648fb866ee8b7d9ef2262d2.jpg
这里我们通过指定 8081 端口,用于访问 sentinel,启动成功过后,通过浏览器我们可以进行登录,默认的初始账号和密码都是 sentinel。
26040259fd128ee04c6949d33efa49bc.jpg
因为上面的命令我们指定了 sentinel-dashboard 项目,所以默认只会看到 sentinel-dashboard 这个项目,这个时候我们需要,修改代码,在 pom.xml 中增加下面的配置
image.png
然后在 JVM 的启动参数中增加

-Dcsp.sentinel.dashboard.server=localhost:8081

指明 sentinel 的地址和端口号,再启动我们的应用。启动完过后,我们要手动调用一下接口,然后就可以看到我们的程序项目连接到 sentinel 了。不过此时只是我们程序和 sentinel 连接成功,还没有限流规则,接下来我们要配置一下限流规则。

2dde6d9fad3d7c6f24e60e118012e333.jpg
按照上图配置好了过后,我们再调用一次接口,可以看到此时我们的处理速度明显慢了下来,每秒只有 20 个 QPS 能获取资源了,至此我们基于 sentinel 的单机限流QPS 20 的目标完成。
b4b0627c4e82b2fc1f0b4fe25c9d0f7d.jpg

目录
相关文章
|
5月前
|
缓存 算法 Java
限流算法 - 基本实现
限流算法 - 基本实现
56 0
|
1月前
|
NoSQL 算法 Java
接口限流是一种控制访问频率的技术
在高并发场景下,合理的接口限流、防重复提交及接口防抖机制对保障系统稳定性至关重要。本文介绍了如何利用AOP在不改变业务代码的前提下,灵活添加这些功能。具体包括:通过`@AccessLimit`注解实现接口限流,利用Redis进行计数与控制;通过`@RepeatSubmit`注解防止重复提交,确保数据一致性;通过`@AntiShake`注解实现接口防抖,提升用户体验。此外,提供了基于Redisson和Spring Cloud的实现示例。
29 4
|
5月前
|
安全 NoSQL Redis
RateLimiter 限流 —— 通过切面对单个用户进行限流和黑名单处理
RateLimiter 限流 —— 通过切面对单个用户进行限流和黑名单处理
76 2
|
消息中间件 算法 Sentinel
只需5分钟,了解常见的四种限流算法
只需5分钟,了解常见的四种限流算法
248 4
|
5月前
|
存储 算法 NoSQL
常见限流算法及其实现
在分布式系统中,随着业务量的增长,如何保护核心资源、防止系统过载、保证系统的稳定性成为了一个重要的问题。限流算法作为一种有效的流量控制手段,被广泛应用于各类系统中。本文将详细介绍四种常见的限流算法、两种常用的限流器工具,从原理、源码的角度进行分析。
359 0
|
存储 算法 Java
限流常见的算法有哪些呢?
限流常见的算法有哪些呢?
58 0
|
5月前
|
算法 Go API
限流算法~
限流算法~
59 1
|
5月前
|
缓存 算法 NoSQL
常见限流算法解读
常见限流算法解读
|
算法
限流常见的算法有哪些?
常见的限流算法有以下几种:
76 0
|
算法
平稳限流?突发限流?还是时间窗口?三种限流算法分析与对比
漏桶限流算法和令牌桶限流算法是两种常见的限流算法,它们的原理和实现方式有所不同。 漏桶限流算法 漏桶限流算法是一种固定容量的桶,水以恒定的速率流出,来限制请求的流量。当请求到来时,会先加入到漏桶中,漏桶以恒定的速率处理请求,处理不了的请求会被丢弃。 以下是漏桶限流算法的流程图:
109 0