充电桩项目实战:短信功能 分布式限流

news2024/11/28 4:34:35

你好,我是田哥

最近,我在对充电桩项目进行微服务升级中,肯定会遇到一些问题

前面分享了:充电桩项目实战:搞定多数据源!

题外话:如果想年后找到更好的工作,推荐看这篇文章

Java后端面试复习规划表,5万字

462358c42a976f70ca4b257cf54c0fdd.png
登录界面

在做充电桩项目时,其中用户的登录、注册等都需要用到短信这个功能,所以,我们在开发之前要做一些相对深入的考虑。

比如:

  • 短信模板如何存储?

  • 常见存储方式有哪些?

  • 用户发送次数是否要限制?

  • 如何限制?

短信发送后,采取的了60秒后能再次重发,这么设计还有个好处,就是规避有些人恶意攻击系统,频繁发送短信,短信一条也就几分钱,但是量上来了,这个成本就不能小看了。

通常3分/条,如果100条那就是3块,10000条就是300块,100w条那就是3万块

但是,这个60秒也还不能完全杜绝这类事情发生,只是说这个量级变了,一个用户每隔60秒发一次,一小时就可以发60次,一条24*60=1440次,10个用户都这么恶搞,那就是每天短信成本变成:

每天10个用户恶搞,14400*3=43200,换算下来432,恶搞一个月就是432*30 = 一万多了。

所以,我们还可以对用户进行每天次数限制,每月次数限制。比如:每天每个用户的某个功能发短信的次数限制在8次,或者20次。至少也能规避掉前面带来的问题。

其实,上述问题也可以说不能完全规避掉,只能说在不影响用户使用的前提下,我们可以尽可能规避。所以,我们可以采取一个分布式限流技术,就是每一个用户每天或者每分钟或每小时,最多只能发送xx次-----限流

分布式限流解决方案

分布式限流方案有以下几种:

1. 基于令牌桶算法的限流

● 优点:实现简单,算法成熟,可以平滑限流请求,具有较高的容错性和稳定性。

● 缺点:限流粒度较粗,无法应对瞬时流量突增的情况。

● 适用场景:对于不需要严格限制每个请求的时间间隔的情况,可以使用基于令牌桶算法的限流方案。

2. 基于漏桶算法的限流

● 优点:实现简单,可以平滑限流请求,具有较高的容错性和稳定性。

● 缺点:限流粒度较粗,无法应对瞬时流量突增的情况。

● 适用场景:对于不需要严格限制每个请求的时间间隔的情况,可以使用基于漏桶算法的限流方案。

3. 基于计数器的限流

● 优点:实现简单,可以较为准确地控制请求的速率。

● 缺点:无法平滑限流请求,容易因瞬时流量突增而导致系统压力过大。

● 适用场景:对于需要严格控制每个请求的时间间隔的情况,可以使用基于计数器的限流方案。

4. 基于分布式缓存的限流

● 优点:可以分布式地存储和管理限流规则,适用于大规模分布式系统。

● 缺点:需要依赖分布式缓存系统,增加了系统的复杂性。

● 适用场景:对于需要分布式地管理限流规则的大规模系统,可以使用基于分布式缓存的限流方案。

5. 基于流量控制网关的限流

● 优点:可以集中管理和控制流量,支持多种限流策略,适用于大规模分布式系统。

● 缺点:需要引入额外的流量控制网关,增加了系统的复杂性。

● 适用场景:对于需要集中管理和控制流量的大规模系统,可以使用基于流量控制网关的限流方案。

不同的限流方案适用于不同的场景,我们需要根据具体的业务需求和系统架构来选择合适的方案。假设我们采用每小时用户最多只能发送6次短信,那我们可以采取滑动窗口来解决。

关于滑动窗口模型图:

a17264b2d8f2f69a903c08ff89af7bde.png
滑动窗口

在我们的充电桩项目中,采用的是Redisson来实现限流的。

public boolean limitBySlidingWindow(String key,long rate, long rateInterval, RateIntervalUnit rateIntervalUnit) {
        RRateLimiter rateLimiter = redissonClient.getRateLimiter(key);
        rateLimiter.trySetRate(RateType.OVERALL, rate, rateInterval, rateIntervalUnit);
        if (rateLimiter.tryAcquire()) {
            return false;
        } else {
            // 触发限流处理
            return true;
        }
    }

trySetRate()方法参数介绍

  1. RateType mode:速率类型,表示限流的模式,例如固定速率(Fixed)或滑动窗口速率(Sliding Window)。

  2. long rate:速率值,表示每秒允许的请求数量。

  3. long rateInterval:速率间隔,表示滑动窗口的时间长度,单位由 rateIntervalUnit 参数指定。

  4. RateIntervalUnit rateIntervalUnit:速率间隔单位,表示滑动窗口时间长度的单位,例如秒(Seconds)、分钟(Minutes)等。这里可能很多人不太理解这个速率类型,下面来聊聊速率类型的区别。

速率类型

固定速率(Fixed)和滑动窗口速率(Sliding Window)是两种常见的限流算法,它们在实现上有一些区别。

1. 固定速率(Fixed):
  • 原理:固定速率算法根据预设的速率限制来控制请求的处理速度。它通过设置一个固定的请求处理时间间隔,确保在单位时间内只处理一定数量的请求。

  • 示例:假设我们有一个API接口,我们希望限制每秒最多只能处理10个请求。使用固定速率算法,我们可以设置一个时间间隔为100毫秒,即每个请求之间至少需要等待100毫秒才能被处理。这样,即使有大量请求同时到达,我们也只会在每100毫秒内处理一个请求,从而保证不超过每秒10个请求的限制。

2. 滑动窗口速率(Sliding Window):
  • 原理:滑动窗口算法通过维护一个时间窗口来控制请求的处理速度。它将时间划分为多个小的时间窗口,每个窗口都有一个对应的请求处理数量限制。当请求到达时,会根据当前时间所在的窗口来决定是否允许处理该请求。

  • 示例:假设我们仍然希望限制每秒最多只能处理10个请求。使用滑动窗口算法,我们可以将时间划分为1秒内的10个等长的小窗口,每个窗口持续100毫秒。每个窗口都有一个计数器,用于记录在该窗口内处理的请求数量。当一个新的请求到达时,我们会检查当前时间所在的窗口,如果该窗口的计数器未达到限制(例如10个请求),则允许处理该请求,并将计数器加一;否则,拒绝该请求。随着时间的流逝,每个窗口都会逐渐向前滑动,旧的窗口将被丢弃,新的窗口将被创建,从而实现对请求的处理速度进行限制。

总结:固定速率算法通过设置固定的请求处理时间间隔来限制请求的处理速度,而滑动窗口算法通过维护一个时间窗口来控制请求的处理速度。两者都可以实现对请求的处理速度进行限制,但具体实现方式和效果略有不同。

估计很多人看了这段话还是不太清楚我们到底要选择哪一种?

两种速率的优缺点

固定速率的优点:

● 实现简单:固定速率算法的实现相对简单,只需要设置一个时间间隔,确保每个请求之间有足够的处理时间。

● 预测性强:由于时间间隔是固定的,所以可以很容易地预测系统的处理能力,便于进行资源规划和分配。固定速率的缺点:

● 不够灵活:在高并发情况下,固定速率可能会导致资源浪费,因为它不考虑实际的请求情况,即使请求量减少,也会保持相同的处理速度。

● 无法应对突发流量:当遇到突发流量时,固定速率可能无法及时响应,因为它不能根据实际情况动态调整处理速度。

滑动窗口速率的优点:

● 灵活性高:滑动窗口算法可以根据实际的请求情况动态调整处理速度,更加灵活地应对不同的流量模式。

● 资源利用率高:通过动态调整时间窗口的大小,滑动窗口算法可以更有效地利用系统资源,避免在请求量少时的资源浪费。

滑动窗口速率的缺点:

● 实现复杂:相比于固定速率,滑动窗口算法的实现更为复杂,需要考虑窗口的大小和滑动的策略。

● 性能开销大:由于需要维护一个时间窗口的数据结构,滑动窗口算法可能会引入额外的性能开销。

总的来说,固定速率算法适合对处理速度要求较为稳定的场景,而滑动窗口速率算法则更适合对处理速度有较高灵活性要求的场景。

短信模块设计

在充电桩项目中短信模块设计,整体流程如下

34d0fbf99f59c447dcab043f437ae0b8.png
短信模块设计

用到了策略模式和模板方法模式。关于策略模式和模板方法模式之前我已经分享过,所以,参考之前的文章即可。

加入我的学习圈子,即可解锁充电桩项目:设计文档、源码、原型图。+V:tj20120622

回复77,免费获取《面试小抄》

回复电子书,免费获取《200本后端必读书籍》

推荐

MySQL 开发规范,非常详细,建议收藏!

16k面试中的10个问题

从0开始搭建公司技术栈,yyds

全程面试辅导,保驾护航!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1425591.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

了解Ansible自动化运维工具及模块的使用

一、Ansible的相关知识 1.1 Ansible工具的了解 Ansible是一个基于Python开发的配置管理和应用部署工具,现在也在自动化管理领域大放异彩。它融合了众多老牌运维工具的优点,Pubbet和Saltstack能实现的功能,Ansible基本上都可以实现。Ansible…

如何使用内网穿透工具在公网实现实时监测DashDot服务器仪表盘

文章目录 1. 本地环境检查1.1 安装docker1.2 下载Dashdot镜像 2. 部署DashDot应用3. 本地访问DashDot服务4. 安装cpolar内网穿透5. 固定DashDot公网地址 本篇文章我们将使用Docker在本地部署DashDot服务器仪表盘,并且结合cpolar内网穿透工具可以实现公网实时监测服务…

如何通过CVE漏洞编码找到对应的CVE漏洞详情及源码修改地址

背景: 最近正在使用docker进行一些cve漏洞的复现,有时候就要通过CVE的漏洞编码,找到对应的漏洞详情,以及漏洞的源码修改 以我上一篇文章的CVE-2020-17518编码为例 Apache Flink文件上Apache Flink文件上 方法: 通…

【C++4】内存管理

前言 💓作者简介: 加油,旭杏,目前大二,正在学习C,数据结构等👀 💓作者主页:加油,旭杏的主页👀 ⏩本文收录在:再识C进阶的专栏&#x1…

初识C语言·动态内存开辟

目录 1 为什么要有动态内存开辟 2 malloc函数的使用 3 free函数的使用 4 calloc函数的使用 5 realloc函数的使用 6 常见的动态内存开辟的错误 1)对空指针的解引用 2)对动态内存开辟空间的越界访问 我们使用了calloc函数开辟了10个整型空间&…

【MyBatis】MyBatis是什么?作用?怎么实现?

一、MyBatis是什么 MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain …

spring-boot-admin的介绍和使用

概述 Spring Boot 有一个非常好用的监控和管理的源软件,这个软件就是 Spring Boot Admin。该软件能够将 Actuator 中的信息进行界面化的展示,也可以监控所有 Spring Boot 应用的健康状况,提供实时警报功能。 主要的功能点有: 显…

排序(4)——快速排序

五、快速排序 1.简介 快速排序是Hoare于1962年提出的,主要采取了分治的思想。快速排序首先确定一个基准值,然后以这个选出的基准值为标准,将整个数组进行按大小进行区分,使得小于该基准值的位于其一侧,大于基准值的位…

超越GPT4 Turbo?科大讯飞发布星火认知大模型3.5版本

简介 1月30日,科大讯飞举行星火认知大模型V3.5升级发布会。科大讯飞董事长刘庆峰、研究院院长刘聪正式发布基于首个全国产算力训练的讯飞星火V3.5,七大核心能力全面提升。 功能展示多模交互 多模理解:上传图片素材,大模型完成识…

C++/数据结构:二叉搜索树的实现与应用

目录 一、二叉搜索树简介 二、二叉搜索树的结构与实现 2.1二叉树的查找与插入 2.2二叉树的删除 2.3二叉搜索树的实现 2.3.1非递归实现 2.3.2递归实现 三、二叉搜索树的k模型和kv模型 一、二叉搜索树简介 二叉搜索树又称二叉排序树,它或者是一棵空树&#xff0…

vue——实现多行粘贴到table事件——技能提升

最近在写后台管理系统时,遇到一个需求,就是要从excel表格中复制多行内容,然后粘贴到后台系统中的table表格中。 如下图所示:一次性复制三行内容,光标放在红框中的第一个框中,然后按ctrlv粘贴事件&#xff0…

路由备份聚合排错

目录 实验拓扑图 实验要求 实验排错 故障一 故障现象 故障分析 故障解决 故障二 故障现象 故障分析 故障解决 故障三 故障现象 故障分析 故障解决 故障四 故障现象 故障分析 故障解决 故障五 故障现象 故障分析 故障解决 实验拓扑图 实验要求 按照图示配…

Typora导出html文件图片自动转换成base64

Typora导出html文件图片自动转换成base64 一、出现问题二、解决方案三、编码实现3.1.创建Java项目3.2.代码3.3.打包成Jar包 四、如何使用endl 一、出现问题 typora 导出 html 的时候必须带有原图片,不方便交流学习,文件太多显得冗余,只有将图…

Docker中安装MySql的遇到的问题

目录 一、mysql查询中文乱码问题 1. 进入mysql中进行查看数据库字符集 2. 修改 my.cnf 中的配置 3. 重启mysql容器,使得容器重新加载配置文件 4. 测试结果 二、主从同步中遇到的问题 2.1 Slave_IO_Running:Connecting 的解决方案 1. 确定宿主机防火墙开放my…

node.js与express.js创建项目以及连接数据库

搭建项目 一、技术准备 node版本:16.16.0 二、安装node成功后,安装express,命令如下: npm install -g express 或者: npm install --locationglobal express 再安装express的命令工具: npm install --location…

PVE安装后报错:NO IOMMU Detected解决办法

1、首先在BIOS中确定图形界面卡,打开了VT-D功能。 2、修改grub vim /etc/default/grub 找到:GRUB_CMDLINE_LINUX_DEFAULT"quiet" 然后修改为 GRUB_CMDLINE_LINUX_DEFAULT"quiet intel_iommuon" 3、使用命…

巨人踏步,港口自动驾驶提速向前打开行业新空间

按照吞吐量排名,全世界最大的50个港口,中国占了29个。在中国的港口和码头上,一场进化正在发生:人在这个生态中占的比重越来越少,技术接管的要素正在越来越多。像是最具代表性的全球综合自动化程度最高的码头——上海洋…

笔记本电脑Win11重装系统教程

在笔记本电脑Win11操作过程中,用户如果遇到很严重的系统问题,就可以重新正常的Win11系统,快速解决Win11系统问题。但是,部分新手用户不知道不知道如何操作才能给Win11笔记本电脑重装系统?以下小编分享笔记本电脑Win11重…

深入理解TCP网络协议(2)

目录 1.TCP的状态转换 1.1 LISTEN状态和ETABLISHED状态 ​编辑2.TIME_WAIT 和 CLOSE_WAIT 2.滑动窗口 1.TCP的状态转换 我们通过上图可以看到TCP状态转换的详细过程.在实际开发的过程中,我们不需要了解的这么细致.为了方便大家的理解,我挑几个主要的状态来给大家聊一下 1.…

易语言系列学习1

通过本文章你会学习到 如果 如果真 获取编辑框内容 关闭本程序 监听按键让它等价于点击某个按钮 运算:或 且 非(注意中间要有一个空格,否则会报错) 效果 .版本 2.程序集 窗口程序集_启动窗口.子程序 _按钮2_被单击. 如果真 (编…