2.2 方法
2.2.1 计数器
原理 | 计数器算法通过记录时间窗口内的请求数量来进行限流。当请求数量超过设定的阈值时,新的请求将被拒绝。 |
优点 | 简单直观,易于实现。 |
缺点 | 无法应对突发流量,因为一旦达到阈值,后续请求无论多少都会被拒绝。此外,随着流量增长,精度可能下降。 |
2.2.2 基于滑动窗口的计数器
原理 | 将时间窗口划分为多个小的时间段(格子),每个格子内有一个计数器。随着时间推移,窗口会滑动,抛弃最老的时间段并纳入新的时间段。限流基于整个窗口内的请求总数。 |
优点 | 相比于固定窗口计数器算法,滑动窗口能更好地应对突发流量,因为每个时间段都有独立的计数器。 |
缺点 | 实现相对复杂,需要维护多个计数器和时间窗口的状态。 |
2.2.3 令牌桶
原理 | 令牌桶中存放着一定数量的令牌,每个令牌代表一个请求权限。请求到达时,如果桶中有令牌则取走令牌并允许请求通过;否则请求被拒绝或等待。 |
优点 | 能够应对突发流量,因为桶中的令牌可以累积并在需要时快速发放。适用于需要灵活调整限流速率的场景。 |
缺点 | 如果令牌发放过快,可能导致系统过载;如果发放过慢,则可能浪费系统资源。 |
2.2.4 漏斗算法
原理 | 想象一个固定容量的桶,请求作为水流进入桶中。如果桶已满,新的请求(水流)会被丢弃或等待直到桶中有空间。 |
优点 | 能够平滑突发流量,确保系统的稳定性。对于下游系统来说,流量是恒定的,有助于处理请求。 |
缺点 | 可能导致延迟,因为即使系统有能力处理更多请求,漏桶也会限制流量的速率。 |
比较两者的特点,漏桶算法更侧重于强制限制数据的传输速率,确保系统接收的请求速率稳定。而令牌桶算法则在限制平均传输速率的同时,允许一定程度的突发传输,以适应流量变化的实际情况。
在适用场景上,漏斗算法更多地用于保护系统,防止因流量过大而崩溃。而令牌桶算法则更适用于那些需要应对突发流量的场景,比如在秒杀活动中,用户的请求速率不固定,令牌桶算法可以确保系统既能处理稳定的请求流,又能应对突发的请求高峰
2.3 方案
2.3.1 单机限流
2.3.1.1 Guava限流
- Guava RateLimiter———-限制时间窗口内的凭据速率
- 平滑突发限流(SmoothBurst)
- 平滑预热限流(SmoothWarningUp)
- 主要方法:RateLimiter.create()和limiter.acquire()
2.3.2 分布式限流
2.3.2.1 Ngnix+Lua
2.3.2.2 Redis+Lua
思路上就很粗暴!比如当前限流为10000QPS/s,直接将当前秒作为key,每一个请求到达的时候都将这个key自增,当一个请求将其自增到10000后,就拒绝访问!具体的实现见张开涛的《亿级流量网络架构核心技术》p75—-“分布式限流”。
3. 负载均衡
4. 分布式事务
4.1 难点
4.2 技术方案
4.2.1 两阶段提交(2PC)
原理 | 两阶段提交(Two-phase Commit,2PC),通过引入协调者(Coordinator)来协调参与者的行为,并最终决定这些参与者是否要真正执行事务。 |
过程 | **准备:**首先协调者询问参与者事务是否执行成功,参与者发回事务执行结果。 **提交或者回滚:**然后如果事务在每个参与者上都执行成功,事务协调者发送通知让参与者提交事务;否则,协调者发送通知让参与者回滚事务。(标黄的部分可能会失败) * 第一阶段(prepare):即所有的参与者RM准备执行事务并锁住需要的资源。参与者ready时,向TM报告已准备就绪。 |
- 第二阶段 (commit/rollback):当事务管理者™确认所有参与者(RM)都ready后,向所有参与者发送commit命令。
|
| 实现 | |
| 优点 | |
| 缺点 | |
4.2.2 补偿事务(TCC)
原理 | |
过程 | |
实现 | |
优点 | |
缺点 |
5. 幂等
5.1 CAS
5.2 数据库Unique Key
6. 排行榜
6.1 基于Redis sortedset
对于排行榜,Redis的有序集合(Sorted Set)是一个非常适合的数据结构。有序集合中的每个元素都是唯一的,并且关联着一个分数。Redis正是根据分数来为集合中的元素进行从小到大的排序。
6.1.1 存储排行榜数据
使用ZADD
命令将用户得分添加到有序集合中。例如:
ZADD leaderboard 100 user1
ZADD leaderboard 150 user2
ZADD leaderboard 90 user3
6.1.2 获取排行榜数据
- 获取排行榜的全部数据:使用
ZRANGE
或ZREVRANGE
命令来获取排行榜的全部数据。例如,获取得分从高到低的排行榜:
ZREVRANGE leaderboard 0 -1 WITHSCORES
- 获取指定位置的排名:使用
ZREVRANK
命令来获取指定用户在排行榜中的位置(从高到低排序):
ZREVRANK leaderboard user2
- 获取指定用户的得分:使用
ZSCORE
命令来获取指定用户的得分:
ZSCORE leaderboard user2
6.1.3 更新用户得分
ZINCRBY leaderboard 10 user2 # 给user2增加10分
6.1.4 移除用户得分
如果需要从排行榜中移除某个用户的得分,可以使用ZREM
命令:
ZREM leaderboard user2
6.1.5 定时任务与持久化
- 定时任务:你可以使用Redis的键空间通知(Keyspace Notifications)配合外部程序来监听排行榜的变化,实现定时任务,比如每天重置排行榜等。
- 持久化:确保Redis配置了合适的持久化策略(如RDB或AOF),以防止数据丢失。
7. 分库分表
8. 加签/验签 or 加密/解密
8.1 加签与验签
8.1.1 加签(签名):私钥加签
- 目的:确保数据的完整性和真实性,防止数据在传输过程中被篡改,并确认数据的确由某个特定的发送者发送。
- 过程:发送者使用自己的私钥对数据(或数据的哈希值)进行加密,生成一个数字签名。这个签名会附加到原始数据上一起发送。
8.1.2 验签(验证签名):公钥验签
- 目的:接收者验证数据的完整性和真实性,确认数据在传输过程中未被篡改,并确认数据确实来自预期的发送者。
- 过程:接收者使用发送者的公钥对数字签名进行解密。如果解密成功且得到的数据(或数据的哈希值)与原始数据匹配,那么签名验证通过,说明数据是完整且真实的。
8.2 加密与解密
8.2.1 加密:公钥加密
- 目的:保护数据的隐私性,确保只有持有相应私钥的接收者才能读懂数据内容。
- 过程:发送者使用接收者的公钥对原始数据进行加密,生成密文。这个密文会发送给接收者。
8.2.2 解密:私钥解密
- 目的:接收者使用自己的私钥将密文还原为原始数据,从而读取内容。
- 过程:接收者使用自己的私钥对收到的密文进行解密,得到原始数据。
9. 大量数据导入导出
9.1 难点
9.1.1 文件过大
分页查询与导出:
- 对于大数据量的导出,采用分页查询的方式,每次查询并写入一定数量的数据到文件,避免一次性查询全部数据导致内存溢出。
- 在Spring Boot中,可以使用MyBatis或JPA进行分页查询。
流式处理:
- 使用流式API来处理数据,这样可以减少内存占用,因为数据不是一次性加载到内存中,而是逐步处理。
压缩文件:
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
.(img-gZj5i7Jv-1714197302068)]
[外链图片转存中…(img-XrEGXLB2-1714197302068)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!