汇总
分布式系统
1、层次结构
2、通信协议
默认dobbo
还有rmi hessian http webservice
3、序列化协议
默认hessian
java二进制序列化、json、soap
4、hessian数据结构
8种原始、3种递归、一种特殊类型
5、pb为什么最高性能
1编译器 2数据压缩
6、负载均衡策略
随机–根据权重,大则流量高
自动感知
一致性hash
7、集群容错
Failover
Failfast
Failsafe
Failback
Forking
Broadcast
8、动态代理
动态字节码生成
9、spi思想及扩展dubbo组件
10、服务治理
1接口的调用次数和耗时 TP50/90/99、调用成功率、失败的监控
2全链路的次数和耗时
3timeout和retry
4 Mock中实现降级逻辑
5 分布式服务接口的幂等:redis+插入unique key
6 接口调用的顺序性:会提升系统复杂度,降低效率-热点压力。dubbo进行hash负载均衡,然后打到一台机器,将order_id相同的请求放到该机器的一个线程内存队列中。更好的策略是合并请求。
11、rpc框架设计
- zookeeper注册中心,本地动态代理发出请求,hessian序列化、长连接协议,负载均衡,服务端动态代理监听并代理实现
- 再加上 监控、配置化
12、zookeeper使用场景
分布式协调、分布式锁、注册中心(元数据管理)、HA高可用
- zk
- 分布式协调
- A系统在zk建立一个监听,当系统B从MQ消费完订单消息,将zk状态改掉,zk则通知监听的系统A
- 分布式锁
- a获取锁(尝试创建临时节点),b没得到就注册监听器(zk会将变化情况反向推送b),释放则获取到
- 临时节点保证,a宕机能够把临时节点自动删除,避免死锁
- 配置中心/元数据
- dubbo的服务端地址都放到zk,消费从zk获取最新的地址,服务地址改动,zk及时地变化
- 高可用
- a宕机了,删除zk的临时节点,监听的b及时发现则插入新的临时节点,a恢复发现有了b临时节点则注册监听
- 分布式协调
13、分布式锁及其效率
三点: 互斥、无死锁(业务意外情况下仍然可以获取锁)、高可用(锁的机子宕了,能够继续获取锁)
zk
- while + countdownlatch–await卡着 + 临时节点
- 临时顺序节点更好
- 创建临时的znode,别的客户端注册监听器,释放锁就是删除znode,释放了就会通知客户端
redis
1如何保证原子性:lua
2业务时间>定期删除时间:守护线程延长定期时间并设置超时放弃
3锁的误删除:uuid+threadid
4防止死锁:key加上过期时间 setnx expireset orderic:lock 随机值 nx 3000 (nx代表无锁才能set返回ok),其他nil的节点每隔1s看是否还能set成功
释放:lua获取value对比是否是自己的,如果是则删除,否则不处理
redis主从架构时,由于异步更新到从,可能导致set的分布式锁失效
5redis集群(三种:主从、哨兵、cluster)无法满足高可用:主从是为了读写分离,锁还是在master上面。哨兵机制的集群,当master上的锁没有同步到slave时,此时有加锁请求则仍能够获得锁,不满足互斥性。三主三从的cluster模式(hash槽分配),超过了10w+的并发,则一个主的槽不可用,则该redis集群全不可用。
6时间漂移:硬件解决
7 redlock:多个实例,但是不是集群关系。锁的有效时间= ttl-时间漂移(所有实例加锁花费的时间)。
获取锁只需要超过一半的实例获取成功。避免死锁:重试机制-加锁不成功则撤回请求(避免死锁),并且在重试时加上随机时间,避免同时加锁的请求都重试结果都无法获得。避免不互斥:延迟重启-如果master挂了,延迟ttl时间对slave重启替换为master。
TTL> 业务执行时间+redis加锁时间+时钟漂移
删除锁则所有实例都执行删除。
- redlock 不健壮、无效请求
- 至少一半以上节点set成功且在超时时间内,才算创建成功。否则说明失败,通过lua删除已经set的节点。
- 没成功就每隔1s去看是否被释放
14、分布式接口幂等性
- 数据库unique key
- redis :set orderid payed
15、分布式接口顺序性
- 接入服务进行分发到(hash分发)不同机子,然后机子分发到一个线程的内存队列
或者接入服务分发到MQ,然后其他机子从MQ拉消费 - 但如果接入服收到的顺序不是你要的,那还是无法完全保证顺序
- 完全保证顺序
- 分布式锁
- 不仅以orderid标识,还需要有标识请求序号的seq。
请求先获取zookeeper锁,查库,如果seq不对则释放锁。
- 不仅以orderid标识,还需要有标识请求序号的seq。
- 分布式锁
16、分布式会话
- spring session + Redis,解耦web容器
17、分布式事务
事务ACID
- 全部结束或者回滚、和5000转账不影响和、并发事务相互不影响(脏读(看到另一个事务的中间状态)、commit读、重复读、串行化)、宕机之后恢复数据和事务成功结束后一致
CAP
- 获得准确数据、及时响应返回、单节点挂了不影响其他
- 一般选择AP – 柔性事务 base理论,达到最终一致。CA是一个必须有分布式锁,一个可以没有
2pc
- 依赖数据库、不适合高并发
- 第一阶段,每个节点记录log,并且返回给总协调是否成功,第二阶段,有一个不成功则协调让所有的人回滚。
- SEATA
- 第一阶段各个节点就提交然后释放锁,第二阶段如果成功则删除log,否则按照log回滚。(全局事务id和分支事务id,定位到log)
tcc
- 转账的例子
- 严格、业务代码繁琐
- try 系统a预留系统bc资源,锁
- confirm rpc调用系统b扣减,调用系统c转账,本地记下log
- cancel 回滚
可靠消息最终一致性
- 本地消息表
- todo
- rocketmq事务消息
- 本地消息表
本文链接: https://satyrswang.github.io/2021/04/05/分布式mindroad/
版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!