From afd8b859b1c8e2a59710d353f33f50f979f994b3 Mon Sep 17 00:00:00 2001 From: MY <715711877@qq.com> Date: Mon, 16 Mar 2020 21:05:42 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20=E5=88=86=E5=B8=83?= =?UTF-8?q?=E5=BC=8F=E7=9B=B8=E5=85=B3=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SUMMARY.md | 2 + assets/202031620440.png | Bin 0 -> 53248 bytes assets/202031620538.jpg | Bin 0 -> 30720 bytes .../Zookeeper.md" | 83 +-------- .../rabbitMQ.md" | 10 -- .../Redis.md" | 65 +------ ...03\345\274\217\344\272\213\345\212\241.md" | 60 +++++++ .../\345\210\206\345\270\203\345\274\217.md" | 160 ++++++++++++++++++ ...73\347\273\237\350\256\276\350\256\241.md" | 53 ++++++ 9 files changed, 277 insertions(+), 156 deletions(-) create mode 100644 assets/202031620440.png create mode 100644 assets/202031620538.jpg create mode 100644 "\350\275\257\344\273\266\345\267\245\347\250\213/\346\236\266\346\236\204/\347\263\273\347\273\237\350\256\276\350\256\241/\345\210\206\345\270\203\345\274\217.md" create mode 100644 "\350\275\257\344\273\266\345\267\245\347\250\213/\346\236\266\346\236\204/\347\263\273\347\273\237\350\256\276\350\256\241/\347\263\273\347\273\237\350\256\276\350\256\241.md" diff --git a/SUMMARY.md b/SUMMARY.md index 5b16e96bef..49beac211a 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -85,6 +85,8 @@ - [架构](./软件工程/架构/架构.md) - [编程范式](./软件工程/架构/编程范式.md) - [设计原则](./软件工程/架构/设计原则.md) + - [系统设计](./软件工程/架构/系统设计/系统设计.md) + - [分布式](./软件工程/架构/系统设计/分布式.md) - [组件构建原则](./软件工程/架构/组件构建原则.md) - [软件架构](./软件工程/架构/软件架构.md) - [实现细节](./软件工程/架构/实现细节.md) diff --git a/assets/202031620440.png b/assets/202031620440.png new file mode 100644 index 0000000000000000000000000000000000000000..0e780ad1783aef56b6e00bcf47a87ce5434ba4a5 GIT binary patch literal 53248 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 acquireTimeout) { - return false; - } - // 通过setnx的方式来获取锁 - if (template.opsForValue().setIfAbsent(LOCK_KEY, identifyValue, expireTime, TimeUnit.MILLISECONDS)) { - // 获取锁成功 - return true; - } - // 获取锁失败,继续自旋 - } - } - - public void release() { - if (identifyValue == null){ - throw new IllegalStateException("没有获取锁"); - } - // 删除的时候验证value,必须确保释放的锁是自己创建的 - if (!identifyValue.equals(template.opsForValue().get(LOCK_KEY))){ - throw new IllegalStateException("锁的value不一致"); - } - template.delete(LOCK_KEY); - } -} -``` - -### 与zookeeper比较 - -相对比来说Redis比Zookeeper性能要好,从可靠性角度分析,Zookeeper可靠性比Redis更好。因为Redis有效期不是很好控制,可能会产生有效期延迟 \ No newline at end of file +原理同HashMap \ No newline at end of file diff --git "a/\346\225\260\346\215\256\345\272\223\347\263\273\347\273\237/\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" "b/\346\225\260\346\215\256\345\272\223\347\263\273\347\273\237/\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" index d474475da1..166c75a946 100644 --- "a/\346\225\260\346\215\256\345\272\223\347\263\273\347\273\237/\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" +++ "b/\346\225\260\346\215\256\345\272\223\347\263\273\347\273\237/\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241.md" @@ -11,15 +11,26 @@ ![批注 2019-10-31 194221](/assets/批注%202019-10-31%20194221.png) - 一致性(Consistency):服务A、B、C三个结点都存储了用户数据, 三个结点的数据需要保持同一时刻数据一致性。 + - 对系统的一个数据更新成功之后,如果所有用户都能够读取到最新的值,该系统就被认为具有强一致性 - 可用性(Availability):服务A、B、C三个结点,其中一个结点宕机不影响整个集群对外提供服务,如果只有服务A结 点,当服务A宕机整个系统将无法提供服务,增加服务B、C是为了保证系统的可用性。 + - 对于用户的每一个操作请求总是能够在有限的时间内返回结果 - 分区容忍性(Partition Tolerance):分区容忍性就是允许系统通过网络协同工作,分区容忍性要解决由于网络分区导致数据的不完整及无法访问等问题。 +最多只能同时满足其中两项 + ![202031017918](/assets/202031017918.png) +分布式系统中,分区容忍性必不可少,因为需要总是假设网络是不可靠的,所以CAP理论实际上是要在可用性和一致性之间做权衡 + +- 保证一致性(CP),不能访问未同步完成的节点,也就失去了部分可用性 +- 保证可用性(AP),允许读取所有节点的数据,但是数据可能不一致 + ## BASE理论 - BA:(Basically Available ),基本可用 + - 分布式系统在出现故障的时候,保证核心可用,允许损失部分可用性 - S:( Soft State),软状态,状态可以在一段时间内不同步 + - 允许系统不同节点的数据副本之间进行同步的过程存在时延 - E:(Eventually Consistent ),最终一致,在一定的时间窗口内, 最终数据达成一致即可 ## 柔性事务与刚性事务 @@ -27,6 +38,35 @@ - 柔性事务满足BASE理论(基本可用,最终一致) - 刚性事务满足ACID理论 +## Paxos + +对多个节点产生的值,该算法能保证只选出唯一一个值 + +### 节点类型 + +- 提议者(Proposer):提议一个值 +- 接受者(Acceptor):对每个提议进行投票 +- 告知者(Learner):被告知投票的结果,不参与投票过程 + +![202031620538](/assets/202031620538.jpg) + +## Raft + +分布式一致性协议,主要是用来竞选主节点 + +有三种节点:Follower、Candidate 和 Leader。Leader 会周期性的发送心跳包给 Follower。每个 Follower 都设置了一个随机的竞选超时时间,一般为 150ms~300ms,如果在这个时间内没有收到 Leader 的心跳包,就会变成 Candidate,进入竞选阶段 + +当 Candidate获得超过半数票时,就成为Leader节点 +如果有多个Candidate获得相同的票数,则重新开始投票 +每个节点设置的随机竞选超时时间不同,因此下一次再次出现多个 Candidate 并获得同样票数的概率很低 + +### 数据同步 + +- 自客户端的修改都会被传入 Leader。此时该修改还未被提交,只是写入日志中 +- Leader 会把修改复制到所有 Follower +- Leader 会等待大多数的 Follower 也进行了修改,然后才将修改提交 +- 此时 Leader 会通知的所有 Follower 让它们也提交修改,此时所有节点的值达成一致 + ## 解决方案 ### 两阶段提交(2PC) @@ -39,6 +79,10 @@ - 优点:实现强一致性 - 缺点:整个事务的执行需要由协调者在多个节点之间去协调 + - 所有事务参与者在等待其它参与者响应的时候都处于同步阻塞等待状态,无法进行其它操作 + - 协调者如果发生故障会造成很大影响 + - 当在提交阶段网络发生异常,只有部分参与者commit了消息,造成数据不一致 + - 任意一个节点失败就会导致整个事务失败 ### 三阶段提交(3PC) @@ -59,6 +103,22 @@ ![批注 2019-10-31 201018](/assets/批注%202019-10-31%20201018.png) +#### 本地消息表 + +- 在分布式事务操作的一方完成写业务数据的操作之后向本地消息表发送一个消息,本地事务能保证这个消息一定会被写入本地消息表中 +- 之后将本地消息表中的消息转发到消息队列中,如果转发成功则将消息从本地消息表中删除,否则继续重新转发 +- 分布式事务操作的另一方从消息队列中读取一个消息,并执行消息中的操作 + +![202031620440](/assets/202031620440.png) + +#### 补偿的方式 + +- 生产者一定要将数据投递到MQ服务器中(消息确认机制) +- MQ消费者消息能够正确消费消息,采用手动ACK模式(当消费者消费消息失败,则不确认消息,消息进行重试) +- 当生产者出错回滚,发送到补偿队列的消息会检测生产者的数据是否提交成功,如果没有,则补偿队列的消费者会重新执行一遍生产者没有提交的事务 + +![批注 2020-03-16 164628](/assets/批注%202020-03-16%20164628.png) + ## LCN ### 原理 diff --git "a/\350\275\257\344\273\266\345\267\245\347\250\213/\346\236\266\346\236\204/\347\263\273\347\273\237\350\256\276\350\256\241/\345\210\206\345\270\203\345\274\217.md" "b/\350\275\257\344\273\266\345\267\245\347\250\213/\346\236\266\346\236\204/\347\263\273\347\273\237\350\256\276\350\256\241/\345\210\206\345\270\203\345\274\217.md" new file mode 100644 index 0000000000..64bf0cb213 --- /dev/null +++ "b/\350\275\257\344\273\266\345\267\245\347\250\213/\346\236\266\346\236\204/\347\263\273\347\273\237\350\256\276\350\256\241/\345\210\206\345\270\203\345\274\217.md" @@ -0,0 +1,160 @@ +# 分布式 + +## 分布式锁 + +在分布式场景下,需要同步的进程可能位于不同的节点上,那么就需要使用分布式锁 + +阻塞锁使用一个互斥量来实现: + +- 0代表其他进程在使用锁 +- 1代表未锁定 + +可以用一个整数表示,或者也可以用某个数据是否存在来表示 + +### 数据库唯一索引 + +获得锁时向表中插入一条记录,释放锁时删除这条记录 + +- 锁没有失效时间,容易死锁 +- 是非阻塞的,获取锁失败就报错 +- 不可重入 + +### redis setnx + +1.获取锁的时候,对某个key执行setnx,加锁(如果设置成功(获得锁)返回1,否则返回0),并使用expire命令为锁添加一个超时时间,超过该时间则自动释放锁,锁的value值为一个随机生成的UUID,通过此在释放锁的时候进行判断。 + +2.获取锁的时候还设置一个获取的超时时间(防止死锁),若超过这个时间则放弃获取锁。 + +3.释放锁的时候,通过UUID判断是不是该锁,若是该锁,则执行delete进行锁释放 + +#### 实现 + +```java +public class RedisLock { + + private StringRedisTemplate template; + + private static final String LOCK_KEY = "LOCK"; + + private String identifyValue; + + public RedisLock(StringRedisTemplate template) {this.template = template;} + + /** + * @param acquireTimeout 获取锁之前的超时时间 + * @param expireTime 锁的过期时间 + * @return + */ + public boolean lock(long acquireTimeout, long expireTime) { + // 获取锁的时间 + long inTime = System.currentTimeMillis(); + identifyValue = UUID.randomUUID().toString(); + for (; ; ) { + // 判断获取锁是否超时 + if (System.currentTimeMillis() - inTime >= acquireTimeout) { + return false; + } + // 通过setnx的方式来获取锁 + if (template.opsForValue().setIfAbsent(LOCK_KEY, identifyValue, expireTime, TimeUnit.MILLISECONDS)) { + // 获取锁成功 + return true; + } + // 获取锁失败,继续自旋 + } + } + + public void release() { + if (identifyValue == null){ + throw new IllegalStateException("没有获取锁"); + } + // 删除的时候验证value,必须确保释放的锁是自己创建的 + if (!identifyValue.equals(template.opsForValue().get(LOCK_KEY))){ + throw new IllegalStateException("锁的value不一致"); + } + template.delete(LOCK_KEY); + } +} +``` + +#### 与zookeeper比较 + +相对比来说Redis比Zookeeper性能要好,从可靠性角度分析,Zookeeper可靠性比Redis更好。因为Redis有效期不是很好控制,可能会产生有效期延迟 + + +### redis redlock + +使用了多个 Redis 实例来实现分布式锁,这是为了保证在发生单点故障时仍然可用 + +计算获取锁消耗的时间,只有消耗的时间小于锁的过期时间,并且从大多数(N / 2 + 1)实例上获取了锁,才认为获取锁成功 +如果获取锁失败,就到每个实例上释放锁 + +### zookeeper临时节点 + +多个进程同时在zookeeper.上创建同一个相同的节点(/lock) , 因为zookeeper节点是唯一的,如果是唯一的话,那么同时如果有多个客户端创建相同的节点/lock的话,最终只有看谁能够快速的抢资源,谁就能创建/lock节点,这个时候节点类型应该使用临时类型。 + +当一个进程释放锁后(关闭zk连接或者会话超时),临时节点会被删除,等待锁的其他进程会收到节点被删除的通知,这些等待的进程会重新参与到竞争 + +需要注意的是,要根据业务设置锁等待时间,避免死锁 + +#### 实现 + +- 上锁 + +```java +public void lock() { + // 尝试获取锁,如果成功,就真的成功了 + if (tryLock()) { + System.out.println(Thread.currentThread().getName() + "获取锁成功"); + // 否则等待锁 + } else { + waitLock(); + // 当等待被唤醒后重新去竞争锁 + lock(); + } +} +private boolean tryLock() { + try { + // 通过zk创建临时节点的成功与否来表示是否获得锁 + zkClient.createEphemeral("/lock"); + return true; + } catch (Exception e) { + return false; + } +} +private void waitLock() { + // 监听节点被删除的事件 + zkClient.subscribeDataChanges("/lock", new IZkDataListener() { + @Override + public void handleDataDeleted(String s) throws Exception { + // 如果节点被删除,唤醒latch + if (latch != null) { + latch.countDown(); + } + } + }); + // 如果zk有lock这个锁 + if (zkClient.exists("/lock")) { + // 在这里进行等待,直至被上面的事件监听唤醒 + latch = new CountDownLatch(1); + try { + latch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + // 等待完成删除所有监听事件,避免监听器堆积影响性能 + zkClient.unsubscribeAll(); +} +``` + +- 释放锁 + +```java +public void release() { + if (zkClient != null) { + // 关闭zk客户端,临时节点也随之被删除,相当于释放锁,让其他人去竞争 + zkClient.close(); + System.out.println(Thread.currentThread().getName()+"释放锁完成"); + } +} +``` \ No newline at end of file diff --git "a/\350\275\257\344\273\266\345\267\245\347\250\213/\346\236\266\346\236\204/\347\263\273\347\273\237\350\256\276\350\256\241/\347\263\273\347\273\237\350\256\276\350\256\241.md" "b/\350\275\257\344\273\266\345\267\245\347\250\213/\346\236\266\346\236\204/\347\263\273\347\273\237\350\256\276\350\256\241/\347\263\273\347\273\237\350\256\276\350\256\241.md" new file mode 100644 index 0000000000..d6595ba5aa --- /dev/null +++ "b/\350\275\257\344\273\266\345\267\245\347\250\213/\346\236\266\346\236\204/\347\263\273\347\273\237\350\256\276\350\256\241/\347\263\273\347\273\237\350\256\276\350\256\241.md" @@ -0,0 +1,53 @@ +# 系统设计 + +## 性能 + +### 性能指标 + +- 响应时间 + - 某个请求从发出到接收到响应消耗的时间 +- 吞吐量 + - 系统在单位时间内可以处理的请求数量,通常使用每秒的请求数来衡量 +- 并发用户数 + - 系统能同时处理的并发用户请求数量 + +### 性能优化 + +- 集群 + - 将多台服务器组成集群,使用负载均衡将请求转发到集群中 +- 缓存 + - 缓存对于性能的提升体现在响应时间上 +- 异步 + - 将消息发送到消息队列之后立即返回,之后这个操作会被异步处理 + +## 伸缩性 + +不断向集群中添加服务器来缓解不断上升的用户并发访问压力和不断增长的数据存储需求 + +如果系统存在性能问题,那么单个用户的请求总是很慢的。 +如果系统存在伸缩性问题,那么单个用户的请求可能会很快,但是在并发数很高的情况下系统会很慢 + +只要集群中的服务器是无状态的,那么往集群中添加服务器后进行负载均衡是很容易的 + +## 扩展性 + +添加新功能时对现有系统的其它应用无影响 + +- 使用消息队列对上下游应用解耦 +- 使用分布式服务将业务与服务分离,服务都是一些可复用的服务,添加新功能时,只要调用已有的服务即可 + +## 可用性 + +### 冗余 + +保证高可用的主要手段是使用冗余 + +对于应用服务器来说,保证是无状态的,就可以实现冗余 +而对于存储服务器,需要通过主从复制来实现冗余 + +### 监控 + +### 服务降级 + +## 安全性 +