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

你好,我是田哥

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

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

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

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.mzph.cn/news/666669.shtml

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

相关文章

高端酒店宴会包间桌位预定小程序h5开源版开发

高端酒店宴会包间桌位预定小程序h5开源版开发 餐厅预定桌位系统,支持多店切换预约,提供全部前后台无加密源代码和数据库 功能特性 为你介绍餐厅预订系统的功能特性 多端适配 采用uniapp,目前适配小程序和微信H5 多店铺 支持多店铺预定 付费和免费预定 支…

『运维备忘录』之 Systemd 命令详解

运维人员不仅要熟悉操作系统、服务器、网络等只是,甚至对于开发相关的也要有所了解。很多运维工作者可能一时半会记不住那么多命令、代码、方法、原理或者用法等等。这里我将结合自身工作,持续给大家更新运维工作所需要接触到的知识点,希望大…

11月最新版付费进群源码自动定位+开源

Nginx 1.22.1 php5.6 mysql5.6 数据库配置&#xff1a;/config/database.php 配置后台域名&#xff1a;config/extra/ip.php 设置伪静态thinkphp 后台账号88886666 密码12345 代码结构 关键代码剖析 <?php // ----------------------------------------------------…

continue语句

一、continue语句 1、continue语句介绍 2、continue语句流程图 3、快速入门案例 4、continue语句的标签

毫米波雷达在汽车领域的原理、优势和未来趋势

1 毫米波雷达的原理 汽车引入毫米波雷达最初主要是为了实现盲点监测和定距巡航。毫米波实质上是电磁波&#xff0c;其频段位于无线电和可见光、红外线之间&#xff0c;频率范围为10GHz-200GHz。工作原理类似一般雷达&#xff0c;通过发射无线电波并接收回波&#xff0c;利用障…

理论与实战:一篇看懂Python词云

实现原理 导入一篇txt文档&#xff0c;使用jieba库对文档中的文字进行分词&#xff0c;计算各个词汇出现的频率&#xff0c;使用wordcloud库按照词汇频率的大小生成词云。 注意&#xff0c;不是使用wordcloud.generate()&#xff0c;这个方法没有按照词汇频率的方式实现词云 停…

Linux 驱动开发基础知识——总线设备驱动模型(七)

个人名片&#xff1a; &#x1f981;作者简介&#xff1a;学生 &#x1f42f;个人主页&#xff1a;妄北y &#x1f427;个人QQ&#xff1a;2061314755 &#x1f43b;个人邮箱&#xff1a;2061314755qq.com &#x1f989;个人WeChat&#xff1a;Vir2021GKBS &#x1f43c;本文由…

极速搭建幻兽帕鲁私服,叫上好友春节假期一起联机畅玩帕鲁

文章目录 前言幻兽帕鲁私服详细部署教程查看服务器开始游戏自定义游戏参数配置 前言 行业资讯 《幻兽帕鲁》的火爆对开发商 Pocketpair 来说&#xff0c;代价是巨大的。该游戏的成功让首席执行官沟部拓郎最近在推特上表示&#xff0c;他可能因服务器运营费用而面临破产。据他透…

山西电力市场日前价格预测【2024-02-04】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2024-02-04&#xff09;山西电力市场全天平均日前电价为367.56元/MWh。其中&#xff0c;最高日前电价为441.08元/MWh&#xff0c;预计出现在18:30。最低日前电价为324.52元/MWh&#xff0c;预计…

代码混淆技术综述与优化方法

摘要 本文介绍了代码混淆的概念和目的&#xff0c;并提供了Python代码混淆的宏观思路。同时&#xff0c;还介绍了一种在线网站混淆Python代码的方法&#xff0c;并给出了混淆前后的示例代码。 引言 在当今信息时代&#xff0c;软件代码的保护显得尤为重要。代码混淆是一种常…

【数位dp】【动态规划】【KMP】1397. 找到所有好字符串

作者推荐 【动态规划】【字符串】【表达式】2019. 解出数学表达式的学生分数 本文涉及知识点 动态规划汇总 LeetCode1397. 找到所有好字符串 给你两个长度为 n 的字符串 s1 和 s2 &#xff0c;以及一个字符串 evil 。请你返回 好字符串 的数目。 好字符串 的定义为&#x…

装饰你的APP:使用Lottie-Android创建动画效果

装饰你的APP&#xff1a;使用Lottie-Android创建动画效果 1. Lottie-Android简介 Lottie-Android是一个强大的开源库&#xff0c;由Airbnb开发&#xff0c;旨在帮助开发者轻松地在Android应用中添加高质量的动画效果。它基于Adobe After Effects软件中的Bodymovin插件&#x…

【Simulink系列】——动态系统仿真 之 离散系统线性离散系统

一、离散系统定义 离散系统是指系统的输入与输出仅在离散的时间上取值&#xff0c;而且离散的时间具有相同的时间间隔。满足下列条件&#xff1a; ①系统&#xff08;的输入输出&#xff09;每隔固定时间间隔才更新一次。固定时间间隔称为采样时间。 ②系统的输出依赖当前的…

2023年09月CCF-GESP编程能力等级认证Python编程三级真题解析

Python等级认证GESP(1~6级)全部真题・点这里 一、单选题(共15题,共30分) 第1题 人们所使用的手机上安装的App通常指的是( )。 A:一款操作系统 B:一款应用软件 C:一种通话设备 D:以上都不对 答案:B 第2题 下列流程图的输出结果是( )。 A:60 B:20 C:5 D…

倾斜摄影轻量化,这样才规范!

自然资源部发布了《倾斜数字摄影测量技术规程》等17项行业标准报批稿公示&#xff0c;其中高频出现的倾斜摄影技术&#xff0c;重回大众视野。 倾斜摄影技术是国际测绘领域近些年发展起来的一项高新技术&#xff0c;它颠覆了以往正射影像只能从垂直角度拍摄的局限&#xff0c;通…

栈--数据结构

初始化栈、入栈、出栈 栈&#xff1a;只允许在一端进行插入或删除操作的线性表 栈顶&#xff08;Top&#xff09; 代码 #include <stdio.h>#define MaxSize 50 typedef int ElemType; typedef struct {ElemType data[MaxSize];//数组int top;//始终指向栈顶的一个变量…

SparkStreaming---入门

文章目录 1.SparkStreaming简介1.1 流处理和批处理1.2 实时和离线1.3 SparkStreaming是什么1.4 SparkStreaming架构图 2.背压机制3.DStream案例实操 1.SparkStreaming简介 1.1 流处理和批处理 流处理和批处理是两种不同的数据处理方式&#xff0c;它们在处理数据的方式和特点…

【C++】类和对象之运算符重载(三)

前言&#xff1a;在前面我们知道在类和对象中有六个默认成员函数&#xff0c;并学习了其中三个构造函数、析构函数、拷贝构造函数&#xff0c;今天我们将进一步的学习.赋值运算符重载。 &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f449; 专栏分类:高质…

Java并发基础:FutureTask全面解析!

内容概要 FutureTask结合了Future和Runnable接口&#xff0c;它能够异步执行任务&#xff0c;提高程序响应性&#xff0c;可以获取任务执行结果&#xff0c;并且支持任务取消机制&#xff0c;提高了灵活性&#xff0c;同时&#xff0c;它简化了并发编程&#xff0c;使多线程开…

【Linux系统 02】Shell脚本

目录 一、Shell概述 二、输入输出 三、分支控制 1. 表达式 2. if 分支 3. case 分支 四、循环控制 1. for 循环 2. while 循环 3. select 循环 五、函数 一、Shell概述 Shell是Linux系统连接用户和操作系统的外壳程序&#xff0c;将用户的输入和请求选择性传递给操…