常见技术难点及方案

news/2024/4/28 20:22:58/文章来源:https://blog.csdn.net/mao1994aa/article/details/136993625

1. 分布式锁

1.1 难点

1.1.1 锁延期

同一时间内不允许多个客户端同时获得锁;

1.1.2 防止死锁

需要确保在任何故障场景下,都不会出现死锁;

1.2.3 可重入

特殊的锁机制,它允许同一个线程多次获取同一个锁而不会被阻塞。

1.2.4 高可用

同时,加锁、释放锁的过程性能开销应尽量低,并保证高可用,避免单点故障。

1.2 技术方案

1.2.1 基于Redis

  • 技术要点
原理Redis的SETNX指令:SETNX(set if not exist)指令用于插入一个键值对。如果键已经存在,则返回False,否则插入成功并返回True。
锁延期Redis 实现分布式锁时,为了确保锁的安全性,引入了 watchdog(看门狗)机制。watchdog 的主要作用是定期重置锁的过期时间,从而避免锁意外过期被其他客户端获取。(在客户端启动)
释放锁同时,可以利用EXPIRE指令为键值对设置过期时间,防止锁忘记释放。
可重入Redis分布式锁实现可重入意味着同一个线程或进程可以多次获取同一个锁而不会被阻塞。这通常是通过在客户端维护一个锁计数器来实现的,每次获取锁时计数器加1,每次释放锁时计数器减1,只有当计数器为0时才真正释放锁。
高可用Redis的RedLock算法:尝试从多个相互独立的Redis实例获取锁,只有当从大多数实例上获取了锁,并且获取锁的时间小于锁的过期时间时,才认为锁获取成功。
  • 技术实践

1.2.2 基于Zookeeper

  • 技术要点
原理

Zookeeper分布式锁:利用Zookeeper的顺序临时节点实现分布式锁和等待队列。

客户端尝试在ZooKeeper的一个特定路径下创建一个临时顺序节点。这个节点是临时的,意味着当客户端会话结束时,ZooKeeper会自动删除它。顺序节点则是ZooKeeper会为其分配一个唯一的、单调递增的序列号。

客户端检查它创建的节点是否是在特定路径下序号最小的节点。如果是,那么它获取到了锁。如果不是,它就需要等待,通常通过监视序号在它之前的节点的删除事件。

锁延期为了保持锁,客户端必须保持与ZooKeeper的会话活动。ZooKeeper的会话有一个超时时间,如果在这个时间内客户端没有与ZooKeeper进行任何交互(如心跳),会话将过期,导致所有与该会话关联的临时节点被删除。因此,为了延期锁,客户端需要定期与ZooKeeper交互以重置会话的超时计时器。
释放锁

当客户端完成其任务并准备释放锁时,它只需删除它之前创建的临时节点。由于该节点是临时的,它的删除不会触发其他客户端的监视事件,除非有其他客户端正在等待成为下一个锁持有者。

如果客户端在持有锁期间崩溃或遇到其他问题,ZooKeeper将自动删除其临时节点(因为会话已过期),从而释放锁。其他等待的客户端将能够获取锁。

可重入

本地锁计数器
客户端维护一个本地锁计数器。每次成功获取锁时,计数器递增;每次释放锁时,计数器递减。

重入逻辑
如果客户端已经持有锁(即本地锁计数器大于0),并且再次尝试获取锁,则只需递增本地锁计数器,而无需与ZooKeeper进行任何额外的交互。

高可用Zookeeper设计的初衷就是为了实现分布式锁服务。
  • 技术实践

Apache Curator是一个流行的ZooKeeper客户端库,它提供了高级的分布式锁实现,包括可重入锁。以下是一个使用Curator实现可重入锁的示例:

Curator is a keeper or custodian of a museum or other collection - A ZooKeeper Keeper.

Apache Curator is a Java/JVM client library for Apache ZooKeeper, a distributed coordination service. It includes a high level API framework and utilities to make using Apache ZooKeeper much easier and more reliable. It also includes recipes for common use cases and extensions such as service discovery and a Java 8 asynchronous DSL.

Welcome to Apache Curator | Apache Curator

import org.apache.curator.framework.CuratorFramework;  
import org.apache.curator.framework.recipes.locks.InterProcessReentrantLock;  public class ZooKeeperReentrantLockExample {  private final CuratorFramework client;  private final InterProcessReentrantLock lock;  public ZooKeeperReentrantLockExample(CuratorFramework client, String lockPath) {  this.client = client;  this.lock = new InterProcessReentrantLock(client, lockPath);  }  public void acquireLock() throws Exception {  lock.acquire(); // 如果当前线程已经持有锁,则重入  }  public boolean tryAcquireLock(long time, TimeUnit unit) throws Exception {  return lock.tryLock(time, unit); // 尝试获取锁,支持重入  }  public void releaseLock() throws Exception {  lock.release(); // 释放锁,如果本地锁计数器减至0,则删除ZooKeeper中的节点  }  
}

2. 限流

2.1 难点

2.1.1 突发流量

在实际应用中,流量往往是不稳定的,存在高峰期和低谷期。如何根据流量的变化动态地调整限流策略,是限流算法需要解决的问题。此外,还需要考虑突发流量的情况,如突然出现的大量请求可能导致系统过载。

2.1.2 平滑

计数器限流算法是一种直观的限流方法,它通过累加在特定时间窗口内的请求数量,并在达到设定的阈值时执行限流操作。然而,这种方法存在一个显著的问题,那就是在时间窗口的末期,如果计数器接近或达到限流阈值,那么新到来的请求很可能会触发限流,即使这些请求在实际上并不会对系统造成过载

观察请求量曲线图,计数器这种限流器会容易呈现出锯齿状而不是平滑的曲线。

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):当事务管理者(TM)确认所有参与者(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 获取排行榜数据

  • 获取排行榜的全部数据:使用ZRANGEZREVRANGE命令来获取排行榜的全部数据。例如,获取得分从高到低的排行榜:
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 加签(签名):私钥加签

  1. 目的:确保数据的完整性和真实性,防止数据在传输过程中被篡改,并确认数据的确由某个特定的发送者发送。
  2. 过程:发送者使用自己的私钥对数据(或数据的哈希值)进行加密,生成一个数字签名。这个签名会附加到原始数据上一起发送。

8.1.2 验签(验证签名):公钥验签

  1. 目的:接收者验证数据的完整性和真实性,确认数据在传输过程中未被篡改,并确认数据确实来自预期的发送者。
  2. 过程:接收者使用发送者的公钥对数字签名进行解密。如果解密成功且得到的数据(或数据的哈希值)与原始数据匹配,那么签名验证通过,说明数据是完整且真实的。

8.2 加密与解密

8.2.1 加密:公钥加密

  1. 目的:保护数据的隐私性,确保只有持有相应私钥的接收者才能读懂数据内容。
  2. 过程:发送者使用接收者的公钥对原始数据进行加密,生成密文。这个密文会发送给接收者。

8.2.2 解密:私钥解密

  1. 目的:接收者使用自己的私钥将密文还原为原始数据,从而读取内容。
  2. 过程:接收者使用自己的私钥对收到的密文进行解密,得到原始数据。

9. 大量数据导入导出

9.1 难点

9.1.1 文件过大

分页查询与导出

  • 对于大数据量的导出,采用分页查询的方式,每次查询并写入一定数量的数据到文件,避免一次性查询全部数据导致内存溢出。
  • 在Spring Boot中,可以使用MyBatis或JPA进行分页查询。

流式处理

  • 使用流式API来处理数据,这样可以减少内存占用,因为数据不是一次性加载到内存中,而是逐步处理。

压缩文件

  • 在导出前对数据进行压缩,如使用ZIP或GZIP格式,以减少文件大小。
  • 前端在接收后解压文件,确保数据的完整性和可读性。

9.1.2 断点重传

分块传输

  • 将大文件分成若干小块,逐块传输。
  • 如果某个块传输失败,只需重新传输该块,而不是整个文件。

记录传输位置

  • 在传输过程中,每个块传输完成后,记录已传输的位置。
  • 如果连接中断,可以从上次记录的位置继续传输。

使用断点续传库

  • 利用现有的断点续传库或框架,如OSS提供的SDK,它们通常已经实现了分块、校验、重传等机制。

9.1.3 进度问题

后端进度跟踪

  • 后端在导出或导入过程中,定期记录并更新进度信息。
  • 可以将进度信息存储在数据库或缓存中,供前端查询。

实时通信

  • 使用WebSocket、SSE或长轮询等技术,建立后端与前端之间的实时通信通道。
  • 后端将进度信息推送给前端,前端实时更新UI展示进度。

API查询进度

  • 前端定期通过API查询特定任务的进度信息。
  • 后端返回最新的进度数据,前端根据数据更新UI。

9.2 技术方案

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

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

相关文章

新火种AI|大厂围剿,“长文本”成不了Kimi的护城河

作者:一号 编辑:美美 长文本之后,Kimi能找到新的“护城河”吗? 过去的一周,由AI技术天才杨植麟的大模型初创企业月之暗面及其产品Kimi所带来的连锁反应,从社交媒体一路冲向了A股,带动了一批“…

【Java程序设计】【C00392】基于(JavaWeb)Springboot的校园生活服务平台(有论文)

基于(JavaWeb)Springboot的校园生活服务平台(有论文) 项目简介项目获取开发环境项目技术运行截图 博主介绍:java高级开发,从事互联网行业六年,已经做了六年的毕业设计程序开发,开发过…

LeetCode_1.两数之和

一、题目描述 二、方法 1.方法1&#xff08;暴力枚举法&#xff09; 利用两个for循环&#xff0c;对数组进行逐一的遍历&#xff0c;直到找到两个数的和为目标值时返回这两个数的下标。以下为c实现的完整代码。 # include<iostream> using namespace std; #include<…

大数据开发扩展shell--尚硅谷shell笔记

大数据开发扩展shell 学习目标 1 熟悉shell脚本的原理和使用 2 熟悉shell的编程语法 第一节 Shell概述 1&#xff09;Linux提供的Shell解析器有&#xff1a; 查看系统中可用的 shell [atguiguhadoop101 ~]$ cat /etc/shells /bin/sh/bin/bash/sbin/nologin/bin/dash/bin/t…

javaWeb项目-火车票订票信息系统功能介绍

项目关键技术 开发工具&#xff1a;IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7 框架&#xff1a;ssm、Springboot 前端&#xff1a;Vue、ElementUI 关键技术&#xff1a;springboot、SSM、vue、MYSQL、MAVEN 数据库工具&#xff1a;Navicat、SQLyog 1、Spring Boot框架 …

【Linux C | 多线程编程】线程的创建、线程ID、线程属性

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; ⏰发布时间⏰&#xff1a;2024-03-22 0…

#Linux(SSH软件安装及简单使用)

&#xff08;一&#xff09;发行版&#xff1a;Ubuntu16.04.7 &#xff08;二&#xff09;记录&#xff1a; &#xff08;1&#xff09;终端键入&#xff08;root权限&#xff09;安装 apt-get install openssh-server 安装时遇到报错 E: Could not get lock /var/lib/dpkg/…

如何用c解决汉诺塔问题!

汉诺塔&#xff08;Tower of Hanoi&#xff09;&#xff0c;又称河内塔&#xff0c;是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子&#xff0c;在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重…

深入解析Spring MVC: 原理、流程【面试版】

什么是SpringMV? 1.是一个基于MVC的web框架&#xff1b; 2.是spring的一个模块&#xff0c;是spring的子容器&#xff0c;子容器可以拿父容器的东西&#xff0c;但是反过来不可&#xff1b; 2.SpringMVC的前端控制器是DispatcherServlet&#xff0c;用于分发请求。使开发变…

Git工具的详细使用

一、环境说明 [rootgit ~]# getenforce Disabled [rootgit ~]# systemctl status firewalld ● firewalld.service - firewalld - dynamic firewall daemonLoaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)Active: inactive (d…

数据库的横表和竖表

先来看个图: 定义如下&#xff1a; 横表&#xff1a;在一行数据中包含了所有的属性&#xff0c;一行就代表了一个完整的实体 竖表&#xff1a;在一行中只存储一个实体的一个属性&#xff0c;多个行组合在一起才组成一个完整的属性适用场景&#xff1a; 横表&#xff1a;对查…

使用easyYapi生成文档

easyYapi生成文档 背景1.安装配置1.1 介绍1.2 安装1.3 配置1.3.1 Export Postman1.3.2 Export Yapi1.3.3 Export Markdown1.3.4 Export Api1.3.6 常见问题补充 2. java注释规范2.1 接口注释规范2.2 出入参注释规范 3. 特定化支持3.1 必填校验3.2 忽略导出3.3 返回不一致3.4 设置…

术语技巧:如何格式化网页中的术语

术语是语言服务中的核心语言资产。快速处理英汉对照的术语是我们在翻译技术学习过程中需要掌握的必备技能。 通常&#xff0c;我们需要把在权威网站上收集到的术语放到word当中&#xff0c;调整正左右对齐的样式&#xff0c;便于打印学习或者转化为Excel表。 如何快速实现这一…

【QT入门】 Qt代码创建布局之setLayout使用

往期回顾&#xff1a; 【QT入门】 Qt代码创建布局之水平布局、竖直布局详解-CSDN博客 【QT入门】 Qt代码创建布局之栅格布局详解-CSDN博客 【QT入门】 Qt代码创建布局之分裂器布局详解-CSDN博客 【QT入门】 Qt代码创建布局之setLayout使用 一、setLayout 1、什么是setLayout …

Day42:WEB攻防-PHP应用MYSQL架构SQL注入跨库查询文件读写权限操作

目录 PHP-MYSQL-Web组成架构 PHP-MYSQL-SQL常规查询 手工注入 PHP-MYSQL-SQL跨库查询 跨库注入 PHP-MYSQL-SQL文件读写 知识点&#xff1a; 1、PHP-MYSQL-SQL注入-常规查询 2、PHP-MYSQL-SQL注入-跨库查询 3、PHP-MYSQL-SQL注入-文件读写 MYSQL注入&#xff1a;&#xff…

酒店能源监测管理系统:实现节能减排与提升管理效率的利器

随着全球能源问题的日益突出和可持续发展理念的深入人心&#xff0c;酒店业也在积极探索节能减排的途径。在这一背景下&#xff0c;酒店能源监测管理系统应运而生&#xff0c;成为了酒店行业提升管理效率、降低能源消耗的重要工具。本文将从多个角度介绍酒店能源监测管理系统的…

yolov9目标检测可视化图形界面GUI源码

一&#xff1a;软件简介 该系统是由微智启软件工作室基于yolov9pyside6开发的目标检测可视化界面系统 功能介绍&#xff1a; 支持图片、摄像头、视频检测、文件夹目标检测支持修改成自己的yolov9模型&#xff0c;自定义识别&#xff08;需是未改进网络训练的数据集&#xff09;…

腾讯云免费云服务器申请流程详解

随着云计算的普及&#xff0c;越来越多的企业和个人开始选择使用云服务器。腾讯云作为国内领先的云计算服务提供商&#xff0c;为用户提供了丰富的云产品和服务。本文将为大家详细介绍腾讯云免费云服务器的申请流程。 一、注册腾讯云账号 首先&#xff0c;需要注册一个腾讯云账…

Linux基础系统设置与备份策略

文章目录 Linux基础系统设置网络设置(手动设置与DHCP自动获取)&#xff1a;nmcli、hostname日期与时间设置&#xff1a;timedatectl、ntpdate语系设置防火墙简易设置 Linux 服务器硬件数据的收集&#xff1a;dmidecode、lspci、lsusb、iostat了解磁盘的健康状态Linux 备份要点确…

Stable Diffusion XL之核心基础内容

Stable Diffusion XL之核心基础内容 一. Stable Diffusion XL核心基础内容1.1 Stable Diffusion XL的主要优化1.2 SDXL整体架构初识1.3 VAE模型1.VAE基本介绍2. VAE基本模型结构3.VAE的训练 1.4 U-Net模型&#xff08;Base部分&#xff09;1. 十四个基本模块概述2. SDXL_Spatia…