分布式理论学习
1.2 Socket编程回顾
TCP/IP, 传输层协议。HTTP应用端
同步并阻塞(BIO, 多个人看多个水壶),适用于对资源要求搞的
同步非阻塞(NIO, 一个人看多个水壶,人不能干别的),适用于弹幕,通信,聊天,现在NIO用的多
异步非阻塞(AIO,事件通知水已烧开,人能干别的),相册服务器,编程复杂
1.3 NIO模式详解。
1.44 RPC框架
RPC是调用过程,不是技术
- 客户端以本地方式(接口方式)调用服务
- client stub 接到调用后,组装方法、参数封装成消息体 (序列化)
- 客户端通过socket将消息发送到服务端
- server stub 解码
- server stub 根据解码结果调用本地服务
- 服务处理
- 本地服务执行并将结果返回 server stub
- server stub 将返回结果打包成消息 序列化
- server 发送消息到客户端
- client stub 解码返回结果
- 客户端 得到结果
RPC 目标是封装 2 3 4 5 7 8 9 10 这几步 只剩 1 6 11, 所以感觉是一次本地调用
1.45 可以用RMI 来实现
package com.wn.rest.rmi.client; import com.wn.rest.rmi.pojo.User; import com.wn.rest.rmi.service.IUserService; import java.rmi.NotBoundException; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; public class RMIClient { public static void main(String[] args) throws Exception { Registry registry = LocateRegistry.getRegistry("127.0.0.1", 9998); IUserService userService = (IUserService) registry.lookup("userService"); User user = userService.getByUserId(1); System.out.println(user.getId() + " " + user.getName()); } }
package com.wn.rest.rmi.server; import com.wn.rest.rmi.service.IUserService; import com.wn.rest.rmi.service.UserServiceImpl; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; public class RMIServer { //注册实例 public static void main(String[] args) { try { Registry registry = LocateRegistry.createRegistry(9998); //创建远程对象 IUserService userService = new UserServiceImpl(); //将远程对象注册到服务表 registry.rebind("userService", userService); System.out.println("IMR 服务端启动成功"); } catch (Exception e) { } } }
package com.wn.rest.rmi.service; import com.wn.rest.rmi.pojo.User; import java.rmi.Remote; public interface IUserService extends Remote { User getByUserId(int id) throws Exception; }
package com.wn.rest.rmi.service; import com.wn.rest.rmi.pojo.User; import java.rmi.server.UnicastRemoteObject; import java.util.HashMap; import java.util.Map; public class UserServiceImpl extends UnicastRemoteObject implements IUserService { HashMap<Integer, User> userMap = new HashMap<>(); User u1; User u2; public UserServiceImpl() throws Exception { super(); u1 = new User(); u2 = new User(); u1.setId(1); u1.setName("a"); u2.setId(2); u2.setName("b"); userMap.put(u1.getId(), u1); userMap.put(u2.getId(), u2); } @Override public User getByUserId(int id) throws Exception { return userMap.get(id); } }
1.50 基于Netty 实现RPC框架
provider 相关方法可以注册成springbean。
client 通过一个 String requestMessage, 里面有 id, method, 等参数调provider里面的方法,
1.52
2.1 分布式架构设计理论
多个服务器做不同的事情。特性
- 分布
- 对等性
- 并发性
- 缺乏全局时钟
- 故障总会发生
- 单点故障 (只有一台计算机支撑某个服务)
三态:成功、失败、超时
幂等 idempotent:一次和多次请求一个资源,对资源产生的影响是
2.3 数据一致性
数据一致、副本数据一致性
数据一致性级别:
1)强一致性,对性能影响很大
2)弱一致性,对于数据一致有一定时间延迟
3)最终一致性,在一定时间后,数据一致
2.4 CAP
一致性 Consistency
可用性 Availability
分区容错性 Partition tolerance
不可能同时满足
2.6 分布式一致性协议-2PC
解决分布式事务的问题。
阶段一:协调者询问各个事务参与的service 是否执行成功。各个分布式service 执行事务不commit。分布式service 返回状态结果,rollback or commit
阶段二:如果协调者发现所有的返回状态都是 commit,则协调者发送 commit 通知给所有的 node。node返回结果给 协调者
prepare -> commit
2.7 分布式一致性协议-3pc
引入超时机制,把prepare 一分为2,CanCommit, PreCommit, DoCommit,
2.8 分布式一致性协议 NWR 协议
用来控制一致性的级别。
N: node 有多少本分数据
W: 一次成功的更新要求有多少数据写入成功
R: 代表数据操作多少份代表成功
W + R > N 成功
2.9 Gossip 协议
利用随机的方式把数据传播到网络中。类似于bd 传播。1)反熵传播(新节点传播),2)谣言传播(增量同步)。
2.10 Paxos协议
高效的分布式一致性协议。简单的Paxos,引入多个协调者(Proposer),然后引入一个主协调者(Proposer)。具体落地的有zk,Raft等
2.20 分布式系统设计策略-心跳检测机制
查看节点是否存活。
- 周期检测机制。(设置超时时间,如果 > 一定时间没响应,则判断宕机)
- 累计失效检测机制 (设置ping此时,如果超过这个次数没有 ping 通,则判断宕机)
2.21 高可用
high availability.
1) 主-备模式
主机挂机了,使用备机模式。Master / Slave
2) 互备模式 Multi-Master
互相同步数据,保持一致
3) 集群模式
有多个节点在运行,通过主控节点分担服务请求
脑裂问题:如果心跳中断,则两个服务争抢共享资源,则会引起一些问题,比如都去读写,相应操作等。
脑裂问题:
- 心跳线束故障
- 网卡
- 开启了防火墙
- 信息配置不正确
脑裂预防:
- 增加extra 心跳线
- 隔离机制 (一个节点一个服务)
2.22 容错性,负载均衡
负载均衡器
1)static
- Round Robin (轮询, by order, potentially overloaded)
- Stick Round Robin (same user to same user, latency, )
- Weighted Round Robin (asign weight to servers, weights mannully, )
- ip /url hash (choose a proper hash function could be chanlleging)
2) dynamic
- least_connection (sometimes, loads are uneven)
- least time (least latency)
2.26 服务削峰
1)使用消息队列
2)使用削峰漏斗
分层过滤:过滤大量无效请求。
例如:
读请求过滤过期的
对写请求进行限流保护
2.27 服务降级
对于不重要的资源可以进行降级。
延迟使用或者暂停使用
2.28 服务限流
- 计数器 (窗口)
- 令牌
2.29 服务熔断 cuicuit breaker
雪崩,(服务一致网上积压)
如果接口调用出现错误比例,则服务接口调用,不再通过网络而是调用本地 服务。