互联网高并发之限流

互联网高并发解决方案-高并发服务限流-纯手写打造RateLimiter注解框架 使用RateLimiter实现令牌桶限流 RateLimiter是guava提供的基于令牌桶算法的实现类,可以非常简单的完成限流特技,并且根据系统的实际情况来调整生成token的速率。 通常可应用于抢购限流防止冲垮系统;限制某接口、服务单位时间内的访问量,譬如一些第三方服务会对用户访问量进行限制;限制网速,单位时间内只允许上传下载多少字节等。 下面来看一些简单的实践,需要先引入guava的maven依赖。 <parent> <groupId>org.springfram 阅读详情

互联网高并发之限流

RPC远程调用 可以跨平台  一般采用HTTP协议  底层使用socket技术 只要语言支持socket技术,就可以进行通讯

开放平台一般采用http协议,因为支持更多的语言

 

本地调用只支持Java语言与Java语言开发使用虚拟机与虚拟机之间通讯 rmi

 

高并发限流解决方案

为啥要限流?

秒杀 双十一  服务安全(流量攻击 DDOS) 雪崩效应 

限流为了保护服务

高并发限流解决方案限流算法(令牌桶、漏桶、计数器)、应用层解决限流(Nginx)

限流算法

常见的限流算法有:令牌桶、漏桶。计数器也可以进行粗暴限流实现。

计数器

  它是限流算法中最简单最容易的一种算法,比如我们要求某一个接口,1分钟内的请求不能超过10次,我们可以在开始时设置一个计数器,每次请求,该计数器+1;如果该计数器的值大于10并且与第一次请求的时间间隔在1分钟内,那么说明请求过多,如果该请求与第一次请求的时间间隔大于1分钟,并且该计数器的值还在限流范围内,那么重置该计数器

 

public class LimitService {

    private int limtCount = 60;// 限制最大访问的容量
    AtomicInteger atomicInteger = new AtomicInteger(0); // 每秒钟 实际请求的数量
    private long start = System.currentTimeMillis();// 获取当前系统时间
    private int interval = 60;// 间隔时间60秒

    public boolean acquire() {
        long newTime = System.currentTimeMillis();
        if (newTime > (start + interval)) {
            // 判断是否是一个周期
            start = newTime;
            atomicInteger.set(0); // 清理为0
            return true;
        }
        atomicInteger.incrementAndGet();// i++;
        return atomicInteger.get() <= limtCount;
    }

    static LimitService limitService = new LimitService();

    public static void main(String[] args) {

        ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
        for (int i = 1; i < 100; i++) {
            final int tempI = i;
            newCachedThreadPool.execute(new Runnable() {

                public void run() {
                    if (limitService.acquire()) {
                        System.out.println("你没有被限流,可以正常访问逻辑 i:" + tempI);
                    } else {
                        System.out.println("你已经被限流呢  i:" + tempI);
                    }
                }
            });
        }
    }

}

 

滑动窗口计数

 

滑动窗口计数有很多使用场景,比如说限流防止系统雪崩。相比计数实现,滑动窗口实现会更加平滑,能自动消除毛刺。
滑动窗口原理是在每次有访问进来时,先判断前 N 个单位时间内的总访问量是否超过了设置的阈值,并对当前时间片上的请求数 +1。

 

 

 

相对于传统的 对于临界值的打破  传统计数器缺点:临界问题 可能违背定义固定速率原则  

 

每隔10s移动一次

 

 

令牌桶算法

Token  guava限流 令牌算法 

令牌桶算法是一个存放固定容量令牌的桶,按照固定速率往桶里添加令牌。令牌桶算法的描述如下:

假设限制2r/s,则按照500毫秒的固定速率往桶中添加令牌;

桶中最多存放b个令牌,当桶满时,新添加的令牌被丢弃或拒绝;

当一个n个字节大小的数据包到达,将从桶中删除n个令牌,接着数据包被发送到网络上;

如果桶中的令牌不足n个,则不会删除令牌,且该数据包将被限流(要么丢弃,要么缓冲区等待)。

 

 

 令牌桶算法(Token)

  令牌桶分为两个动作

     动作1 固定速录往桶中存入令牌

     动作2 客户端如果想访问请求,先从桶中获取token

 

 客户端只有拿到令牌 才可以 访问服务器端 这是关键哦,获取不到就走降级

 

桶中的令牌也会满了哦,满了就不在装了。不能无限装的,有容量。

 

一个存  一个取

 

使用RateLimiter实现令牌桶限流

RateLimiter是guava提供的基于令牌桶算法的实现类,可以非常简单的完成限流特技,并且根据系统的实际情况来调整生成token的速率。

通常可应用于抢购限流防止冲垮系统;限制某接口、服务单位时间内的访问量,譬如一些第三方服务会对用户访问量进行限制;限制网速,单位时间内只允许上传下载多少字节等。

 

 

 

 pom:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.toov5</groupId>
  <artifactId>springboot-guava</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.0.RELEASE</version>
	</parent>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>com.google.guava</groupId>
			<artifactId>guava</artifactId>
			<version>25.1-jre</version>
		</dependency>
	</dependencies>
</project>

  

 service

package com.toov5.service;

import org.springframework.stereotype.Service;

@Service
public class OrderService {
    
    public boolean addOrder() {
      System.out.println("db...正在操作订单表数据库");    
      return true;
    }
}

controller

package com.toov5.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.google.common.util.concurrent.RateLimiter;
import com.toov5.service.OrderService;

@RestController
public class IndexController {
  @Autowired
  private OrderService orderService;
 //create方法中传入一个参数 以秒为单位固定的速率值 1r/s 往桶中存入一个令牌
  RateLimiter rateLimiter = RateLimiter.create(1);  //独立线程!它自己是个线程
   
  //相当于接口每秒只能接受一个客户端请求
  @RequestMapping("/addOrder")
    public String addOrder() {
        //限流放在网关 获取到当前 客户端从桶中获取对应的令牌 结果表示从桶中拿到令牌等待时间
        //如果获取不到令牌 就一直等待
        double acquire = rateLimiter.acquire();
        System.out.println("从桶中获取令牌等待时间"+acquire);
        //业务逻辑处理
        boolean addOrderResult = orderService.addOrder();
        if (addOrderResult) {
            return "恭喜抢购成功!";
        }
        
        return "抢购失败!";
    }
}

启动:

package com.toov5;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App {
  public static void main(String[] args) {
    SpringApplication.run(App.class, args);
      
}
}

 

运行访问:

加速点击 后面就有等待了 存放到token 不够用了就得等待了

 

 

这样一直等待也不好 设置服务降级处理

规定时间内没有获取到临牌 走降级  

修改添加:

package com.toov5.controller;

import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.google.common.util.concurrent.RateLimiter;
import com.toov5.service.OrderService;

@RestController
public class IndexController {
  @Autowired
  private OrderService orderService;
 //create方法中传入一个参数 以秒为单位固定的速率值 1r/s 往桶中存入一个令牌
  RateLimiter rateLimiter = RateLimiter.create(1);  //独立线程!它自己是个线程
   
  //相当于接口每秒只能接受一个客户端请求
  @RequestMapping("/addOrder")
    public String addOrder() {
        //限流放在网关 获取到当前 客户端从桶中获取对应的令牌 结果表示从桶中拿到令牌等待时间
        //如果获取不到令牌 就一直等待
        double acquire = rateLimiter.acquire();
        System.out.println("从桶中获取令牌等待时间"+acquire);
      boolean   tryAcquire=rateLimiter.tryAcquire(500,TimeUnit.MILLISECONDS);  //如果在500sms没有获取到令牌 直接走降级
      if (!tryAcquire) {
        System.out.println("别抢了,等等吧!");
        return "别抢了,等等吧!";
    }
        //业务逻辑处理
        boolean addOrderResult = orderService.addOrder();
        if (addOrderResult) {
            System.out.println("恭喜抢购成功!");
            return "恭喜抢购成功!";
        }
        
        return "抢购失败!";
    }
}

 

运行结果:

 

 获取后就从桶中删除了token 

 

 

漏桶算法

漏桶作为计量工具(The Leaky Bucket Algorithm as a Meter)时,可以用于流量整形(Traffic Shaping)和流量控制(TrafficPolicing),漏桶算法的描述如下:

一个固定容量的漏桶,按照常量固定速率流出水滴;

如果桶是空的,则不需流出水滴;

可以以任意速率流入水滴到漏桶;

如果流入水滴超出了桶的容量,则流入的水滴溢出了(被丢弃),而漏桶容量是不变的。

令牌桶和漏桶对比:

令牌桶是按照固定速率往桶中添加令牌,请求是否被处理需要看桶中令牌是否足够,当令牌数减为零时则拒绝新的请求;

漏桶则是按照常量固定速率流出请求,流入请求速率任意,当流入的请求数累积到漏桶容量时,则新流入的请求被拒绝;

令牌桶限制的是平均流入速率(允许突发请求,只要有令牌就可以处理,支持一次拿3个令牌,4个令牌),并允许一定程度突发流量;

漏桶限制的是常量流出速率(即流出速率是一个固定常量值,比如都是1的速率流出,而不能一次是1,下次又是2),从而平滑突发流入速率;

令牌桶允许一定程度的突发,而漏桶主要目的是平滑流入速率;

两个算法实现可以一样,但是方向是相反的,对于相同的参数得到的限流效果是一样的。

另外有时候我们还使用计数器来进行限流,主要用来限制总并发数,比如数据库连接池、线程池、秒杀的并发数;只要全局总请求数或者一定时间段的总请求数设定的阀值则进行限流,是简单粗暴的总数量限流,而不是平均速率限流。

 

 应用层可以 Nginx http_limit   应用层限流  (这一种运维解决,前三种 网关里面加代码)

 

以固定的速率从桶中流出水滴  以任意的速率往桶中放水滴 桶中的容量大小是不会发生改变的

 

   

 

令牌桶算法以平均速率访问,漏桶算法平滑访问。

 

posted @ 2018-11-20 19:11 toov5 阅读( ...) 评论( ...) 编辑 收藏
java发送短信系列之限制日发送次数 主要为大家详细介绍了java发送短信系列之限制日发送次数,详细介绍了限制每日向同一个用户(根据手机号和ip判断)发送短信次数的方法,感兴趣的小伙伴们可以参考一下 立即下载

相关推荐

安时积分法和开路电压法结合估算锂电池SOC

基于安时积分法和开路电压法结合的锂电池SOC估计Simulink仿真建模,利用安时积分法计算放电过程中的SOC,在搁置状态利用开路电压法进行SOC修正。

qq_39304296的博客 2554

说一说,接口中的几种限流实现

为什么需要限流? 按照服务的调用方,可以分为以下几种类型服务 1、与用户打交道的服务 比如web服务、对外API,这种类型的服务有以下几种可能导致机器被拖垮: 用户增长过快(这是好事) 因为某个热点事件(微博热搜) 竞争对象爬虫 恶意的刷单 这些情况都是无法预知的,不知道什么时候会有10倍甚至20倍的流量进来,如果遇到此类情况,扩容是根本来不及的,弹性扩容也是来不及的; 2、对内的RPC服务 一个服务A的接口可能被BCDE多个服务进行调用,在B服务发生突发流量时,直接把A服务给调用挂了,导致A服务对CDE也

zzwAriel的博客 2900

C++学习(四六六)Multiple parse contexts are available for this file

Note: Multiple parse contexts are available for this file. Choose the preferred one from the editor menu 参考: "Multiple parse contexts" in Qt creator | Qt ForumHi Do you use sessions? https://bugreports.qt.io/browse/QTCREATORBUG-18521 Anyway, its not.

hankern的专栏 4610

实现接口的限流各种算法

当然在现在的分布式架构下,我们可以通过服务的快速熔断,降级,隔离,限流等方式来应对单个微服务崩溃而导致整个服务不可用的情况,如果你使用的是SpringCloud,你可以使用Hystrix,如果你使用的是SpringCloud-alibaba,那么你可以使用Sentinel来帮助你实现接口的限流,但是,如果我们不依赖于其它组件,那该如何去实现接口的限流呢?实现接口限流的方法有很多,我大概带着大家一起探讨一下。计数器法是限流算法里最简单也是最容易实现的一种算法。比如我们规定,对于 A 接口来说,我们 1 分钟的

zhiyikeji的博客 4744

药物重定位实战:如何用反向找靶技术挖掘老药新用(附Python代码示例)

本文详细介绍了药物重定位中的反向找靶技术,通过分子相似性计算、机器学习模型和结构对接等方法,挖掘已有药物的新治疗潜力。附Python代码示例,帮助读者快速实现从分子结构到潜在靶标的智能预测,显著提升药物研发效率。

weixin_28726671的博客 259

机器学习——径向基函数(RBF)神经网络

目录 一、什么是基函数 二、什么是径向基函数 三、为什么RBF神经网络使用一个径向基函数作为隐含层的激活函数 四、参数训练 五、RBF网络vs BP网络和 SVM 一、什么是基函数 著名的傅里叶变换是指:n个有参(权值)的正、余弦三角函数基的和式可以等价的表示任意一个周期函数,这里的“基”和我们数学中说的坐标基或向量基含义相同,即坐标空间中任意一个向量都可以用基向量的线性和表示出来。 因此,我们引入函数空间的概念,函数空间中的每个连续函数可以表示为基函数的线性组合,就像向量空间中的每..

CHWB2580的博客 6272

限流实现方案

限流实现方案 api限流实现

lsblsb的专栏 1万+

gnss变形监测基础(四)

监测站的数据采样率指的是监测站在单位时间内收集数据的频率,通常以赫兹(Hz)为单位。在GNSS变形监测中,数据采样率决定了监测系统能够捕捉到的变形动态变化的详细程度和时间分辨率。例如,一个采样率为1Hz的GNSS监测站意味着它每秒钟收集一次位置数据;而一个采样率为10Hz的监测站则每秒钟收集10次位置数据。较高的采样率能够提供更细致的时间序列数据,有助于分析快速变化的动态过程,如地震活动或建筑物的振动响应。然而,较高的采样率也意味着数据量更大,可能需要更多的存储空间和更强大的数据处理能力。

我的博客 1293

接口限流算法及解决方案

参考: 接口限流算法:漏桶算法&amp;amp;amp;amp;令牌桶算法 redisson实现分布式限流 一、限流算法 1. 漏桶算法 2. 令牌桶算法 二、令牌桶算法VS漏桶算法 三、解决方案 1. 使用Guava的RateLimiter进行限流控制(单机) 2. 使用Semphore进行并发流控(单机) 3. redisson实现分布式限流 工作中对外提供的API ...

漏水亦凡的专栏 5013

Allegro因为精度问题导致走线连接不上的解决办法

在用Allegro做PCB设计的时候,尤其是从其它单板上导数据过来的时候,有时会因为精度不一致导致连接不上,如下图。一般来说,可以逐个重新连接一下,但是如果连接点位比较多的话,需要花费较多时间。下面介绍如何使用Allegro自带的功能解决这个问题,具体操作如下。和Convert Figure Stackups to vias。因为精度问题导致走线连接不上的解决办法。线和过孔因为精度有微小的连接偏差。

weixin_54787054的博客 2611

【YOLOv12改进trick】高效多尺度卷积注意力EMCAD_Block模块引入YOLOv12,实现涨点和效率提升,含创新点Python代码

EMCAD引入YOLOv12模块,实现高效多尺度注意力模块引入到YOLOv12中的快速涨点及效率提升

向上生长的程序媛的博客 852

微服务-服务限流-开发实战

学习思路 各种限流方式应用场景及优缺点 具体实现 一、各种限流方式应用场景及优缺点 限流:在了解了系统的负荷之后,如果访问流量超过负荷那么将导致服务整体被压垮,为保证服务可用预防突发流量,在流量到达设置指标时允许摒弃部分以保证服务运行正常 总流量限流:一般以服务资源为标准,在有限资源的基础上设置最高上限;如:在服务器数量、配置一定的条件下,通过压测等手段设置系统访问阈值 按用户或客户端I...

重点在于记录 668

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

互联网高并发解决方案02-高并发服务限流特技

高并发服务限流特技 在开发高并发系统时有三把利器用来保护系统:缓存、降级和限流。缓存的目的是提升系统访问速度和增大系统能处理的容量,可谓是抗高并发流量的银弹;而降级是当服务出问题或者影响到核心流程的性能则需要暂时屏蔽掉,待高峰或者问题解决后再打开;而有些场景并不能用缓存和降级来解决,比如稀缺资源(秒杀、抢购)、写服务(如评论、下单)、频繁的复杂查询(评论的最后几页),因此需有一种手段来限制...

qq_35524586的博客 396

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

互联网高并发解决方案-高并发服务限流

高并发服务限流特技 在开发高并发系统时有三把利器用来保护系统:缓存、降级和限流。缓存的目的是提升系统访问速度和增大系统能处理的容量,可谓是抗高并发流量的银弹;而降级是当服务出问题或者影响到核心流程的性能则需要暂时屏蔽掉,待高峰或者问题解决后再打开;而有些场景并不能用缓存和降级来解决,比如稀缺资源(秒杀、抢购)、写服务(如评论、下单)、频繁的复杂查询(评论的最后几页),因此需有一种手段来限制这些场景的并发/请求量,即限流。 为什么要互联网项目要限流 互联网雪崩效应解决方案 服务降级: 在高..

魔法革1996 300

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

互联网高并发解决方案(2)--高并发服务限流特技

RPC和本地JAVA调用的区别 RPC远程调用:一般是可以跨平台使用的,采用Socket技术,只要语言支持socket技术就可以进行互相通信。其实就是socket+反射实现的。 本地调用:只能支持Java语言与Java语言开发,使用虚拟机进行通讯。 高并发服务的限流特技(解决高并发,请求多,用户等待时间长) 雪崩效应:服务的请求数超过了服务器的最大线程数(线程池缓存队列满了)。默认的情况下,只有一个线程池维护所有的服务接口,如果大量的请求访问同一个接口,达到了服务器的默认极限,可能会导致其他的服务无法

YHJ 2139

互联网三高-高并发之限流算法与实战

摘要:本文系统介绍了高并发系统中的限流技术。首先分析了限流的必要性,指出当流量超过系统承载能力时,主动拒绝请求比优化处理速度更重要。随后详细讲解四大限流算法(固定窗口、滑动窗口、漏桶、令牌桶)的原理与实现,对比各自优缺点。接着深入解析Guava RateLimiter和Sentinel的源码与实战应用,包括单机与分布式限流方案。最后总结了生产环境调优经验和面试常见问题,强调限流应与其他治理手段配合使用,形成完整的并发控制体系。

hong4760的专栏 750

Java开发秒杀大型互联网企业高并发限流特技

引言 高并发(High Concurrency)是互联网分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计保证系统能够同时并行处理很多请求。 高并发相关常用的一些指标有响应时间(Response Time),吞吐量(Throughput),每秒查询率QPS(Query Per Second),并发用户数等。 响应时间:系统对请求做出响应的时间。例如系统处理一个HTTP请求需要200ms,这个200ms就是系统的响应时间。 吞吐量:单位时间内处理的请求数量。 QPS:每秒响应请求数。在互联

keeper42的博客 195

java 高并发_Java开发秒杀大型互联网企业高并发限流特技

引言高并发(High Concurrency)是互联网分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计保证系统能够同时并行处理很多请求。高并发相关常用的一些指标有响应时间(Response Time),吞吐量(Throughput),每秒查询率QPS(Query Per Second),并发用户数等。响应时间:系统对请求做出响应的时间。例如系统处理一个HTTP请求需要200ms,这个2...

weixin_39796868的博客 112

面向接口限流与资源保护策略的互联网系统高并发设计与多语言工程实践分享

限流是保护系统,而不是业务惩罚策略选择必须结合业务负载特性监控与动态调整不可缺失接口限流与资源保护策略,使系统在高并发场景下仍能保持稳定和可控。通过在多语言实现中统一限流语义,结合动态调整和降级策略,并配合完善监控,系统才能在流量激增时,保护核心业务、维持用户体验。希望这篇关于接口限流与资源保护的工程实践分享,能为你在高并发互联网系统设计中,提供长期可落地、可维护的思路与方法。

2501_94186637的博客 313

互联网高并发分布式架构,究竟如何限流?

高并发编程、分布式框架、Spring等常用框架可以说是现在Java后端求职的必备技能。每一个技术方向的背后都包含了众多技术细节,以开发一个分布式系统来说,需要分布式存储/...

shenjian58的博客 611

从高并发限流到多维度流量控制体系落地的互联网系统工程实践随笔与多语言语法思考

限流不仅是防止崩溃,更是保障核心业务连续性的工程手段。通过用户、接口、业务维度限流,结合漏桶、令牌桶、分布式算法和动态阈值,并配合降级与熔断,系统从“脆弱高并发节点”升级为“可控韧性体系”。希望这篇围绕高并发流控的工程随笔,为正在构建互联网系统的工程师提供偏长期、偏系统性的参考,而不仅仅停留在简单 RPS 限制或单机策略实现层面。

2501_94186637的博客 327
上一篇: 互联网高并发之Hystrix实现服务隔离和降级
下一篇: 手写RateLimiter
Art&Code
博客等级 码龄7年 77粉丝 554原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值