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

你好,我是田哥

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

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

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

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 多店铺 支持多店铺预定 付费和免费预定 支…

介绍 HTTPS 中间人攻击

介绍 HTTPS 中间人攻击 https协议是由httpssl协议构成的。 客户端和服务端SSL或TLS能够相互通信的基本步骤 确定使用协议的版本 选择加密算法 通过交换和验证数字证书彼此进行身份验证 使用非对称加密技术生成共享密钥,避免密钥分发问题。 SSL或TLS使用共享密钥对消…

软件包模块、服务模块、逻辑卷模块、文件系统模块、playbook剧本,YAML语法规范、playbook剧本案例

ansible ansible模块 yum_repository 用于配置yum 常用选项: file: 指定文件名其他选项,请与文件内容对照 # 在webservers组中的主机上,配置yum[rootpubserver ansible]# ansible webservers -m yum_repository -a "file…

请解释Java中的equals()和hashCode()方法的作用和区别。请解释Java中的AOP(面向切面编程)的作用和原理。

请解释Java中的equals()和hashCode()方法的作用和区别。 在Java中,equals()和hashCode()方法都是用于处理对象相等性(equality)的方法。 equals()方法: equals()方法是Object类中定义的方法,所有的Java类都可以使用该…

vscode连接ssh失败记录(20240202)

问题描述: 1、在使用vscode remote-ssh插件时连接较老版本linux时,出现报错Warning: Missing GLIBC > 2.28! from /lib/x86_64-linux-gnu/libc-2.27.so Error: Missing required dependencies. Please refer to our FAQ https://aka.ms/vscode-rem…

算法随想录第五十天打卡123.买卖股票的最佳时机III , 188.买卖股票的最佳时机IV

123.买卖股票的最佳时机III 这道题一下子就难度上来了,关键在于至多买卖两次,这意味着可以买卖一次,可以买卖两次,也可以不买卖。 视频讲解:动态规划,股票至多买卖两次,怎么求? | …

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

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

什么是 Java 中的 IO 和 NIO?它们之间有什么区别?什么是 Java 中的内存管理和垃圾回收?常见的垃圾回收算法有哪些?

什么是 Java 中的 IO 和 NIO?它们之间有什么区别? 在 Java 中,IO(Input/Output)和NIO(New IO)都是用于处理输入输出操作的API。它们之间有以下区别: IO(传统IO&#xff…

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;利用障…

LeetCode 每日一题 2024/1/29-2024/2/4

记录了初步解题思路 以及本地实现代码&#xff1b;并不一定为最优 也希望大家能一起探讨 一起进步 目录 1/29 514. 自由之路1/30 2808. 使循环数组所有元素相等的最少秒数1/31 2670. 找出不同元素数目差数组2/1 LCP 24. 数字游戏2/2 1686. 石子游戏 VI2/3 1690. 石子游戏 VII2/…

理论与实战:一篇看懂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;本文由…

Linux常见面试题汇总

Linux上如何查询某个端口是否被占用&#xff1f; 在Linux上&#xff0c;你可以使用以下几种方法来查询某个端口是否被占用&#xff1a; 使用netstat命令&#xff1a; netstat -tuln | grep <端口号>这个命令会列出当前正在运行的所有TCP和UDP端口&#xff0c;并过滤出指…

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

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

多线程例子,通过启动三个线程 等三个线程都跑完后打印结果

一个多线程例子&#xff0c;通过启动三个线程 等三个线程都跑完后打印结果 需求描述&#xff1a;开启一个多线程跑3条门店的数据&#xff0c;每个门店都新起一个线程去跑数据&#xff0c;当所有线程跑完后主线程打印结果&#xff0c;记录报错的门店编码 1.线程池配置类 impo…

山西电力市场日前价格预测【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…