django 网站开发实例,网站做的漂亮的企业,服务器免备案,网页制作工具程1. 分布式锁
1.1 难点
1.1.1 锁延期
同一时间内不允许多个客户端同时获得锁#xff1b;
1.1.2 防止死锁
需要确保在任何故障场景下#xff0c;都不会出现死锁#xff1b;
1.2.3 可重入
特殊的锁机制#xff0c;它允许同一个线程多次获取同一个锁而不会被阻塞。
1.2…1. 分布式锁
1.1 难点
1.1.1 锁延期
同一时间内不允许多个客户端同时获得锁
1.1.2 防止死锁
需要确保在任何故障场景下都不会出现死锁
1.2.3 可重入
特殊的锁机制它允许同一个线程多次获取同一个锁而不会被阻塞。
1.2.4 高可用
同时加锁、释放锁的过程性能开销应尽量低并保证高可用避免单点故障。
1.2 技术方案
1.2.1 基于Redis
技术要点
原理Redis的SETNX指令SETNXset 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 NgnixLua
2.3.2.2 RedisLua
思路上就很粗暴比如当前限流为10000QPS/s直接将当前秒作为key每一个请求到达的时候都将这个key自增当一个请求将其自增到10000后就拒绝访问具体的实现见张开涛的《亿级流量网络架构核心技术》p75—-“分布式限流”。 3. 负载均衡 4. 分布式事务
4.1 难点 4.2 技术方案 5. 幂等
5.1 CAS 5.2 数据库Unique Key 6. 分库分表