常用的实现微服务两种方式
1.Spring boot+Spring Cloud 组件多,功能完备 基于http实现
2.Spring Boot +Dubbbo+zookeeer 组件少,功能非完备 Alibaba Dubbo-> apache Bubbo 孵化Dubbo Rpc通信框架
分布式系统的优点:
高可用 ->一直可以用, 高并发-> , 高性能
分布式系统需要解决的四个问题:
1.客户端怎么访问多个服务?
API网关
2.服务于服务之间如何通信?
同步通信:
HTTP(apache http Client)
Rpc(Dubbo 只支持JAVA ,apache thrift ,gprc)
异步通信:
消息队列 : kafka rabbitMq rocketMq
3.如何管理多个服务?
服务治理 zookper
服务注册于发现
基于客户端的服务注册于发现:Apache zookper
基于服务端的服务注册于发现:netflix Eureka
4.服务挂了,怎么办?
重试机制
服务熔断
服务降级
服务限流
如何管理多个服务之Zookper 分布式协调服务
解决了服务治理的问题
什么是分布式协调服?
它主要是用来解决分布式环境中多个进程之间的同步控制,让他们有序的访问临界资源防 止产生脏数据的后果,而这个协调技术的核心就是分布式锁,所以zookper就是实现分布式锁的一种方式。
什么是分布式锁?
为了防止分布式系统中多个进程相互干扰,我们需要一种分布式协调技术来对进程进行调度,而这个协调技术的核心就是分布式锁。
对比单机多线程环境下多个线程的同步控制,通过阻塞同步synchonized或者非阻塞同步cas 算法让他们有序的访问临界资源,防止脏数据的产生。
分布式锁应具备哪些条件?:
1.在分布式环境下:一个方法在同一时间只能被同一机器的一个线程执行
2.高可用的获取锁和释放锁(始终能获取和释放锁)
3.高性能的获取锁和释放锁(要快)
4.具备可重入特性(可重新进入,由多个任务并发使用,而不用担心数据错误)
4.具备锁失效机制,防止死锁
5.具备非阻塞特性,即没有获取到锁将直接返回获取失败
分布式锁常见的实现方式:
Memcached::
利用Memcached 的add命令 ,次命令是原子操作,只有在key不存在的情况下才能 成功,也就意味着线程得到了锁。
redis :
和memcache的方式类似,利用redis的setnx命令,次命令同样是原子操作,只有在key不存在的情况下,才能set成功。
zookper
利用zookeeper的顺序临时节点,来实现分布式锁和等待队列,zookper 设计的初衷,就是为了分布式服务
Redis 实现分布式锁的过程:
加锁:
利用setnx 命令添加成功返回1 已存在元素添加失败返回0,且该过程是原子操作的特性
来设置锁的标志位实现加锁过程;
解锁:
利用del命令将添加的锁的键删除,达到锁释放的命令
锁超时:
expire 命令为锁设置生存时间 超时自动删除达到锁超时自动释放的目的;
redis实现分布式锁存在的问题:
1.加锁和锁超时是两个操作不是一组原子操作可能发生死锁(比如宕机)
1.解决 redis2.6 以后提供 set(key val EX time NX) 设置元素并设置过期时间的原子操作
2.误删锁
JVM1 set 锁id val EX 30 NX
30 秒到(JVM还未完成)
JVM2 set 锁id val EX 30 NX
JVM 操作完成 del 锁id 误删了JVM2的锁
解决方案 :进程执行释放锁前看锁是不是自己的,
将锁的val设定为进程的id ,进程释放锁前先判断当前锁的val是不是自己进程id,再决定删不删除
3.基于第二个问题之上锁的提前释放
JVM1要判断自己是否处理完成,处理完成后再释放锁,不允许未处理完成前锁超时自动释放
解决:每个进程增加守护线程 在锁超时之前若拥有锁的进程未处理完成责更新锁1的过期时间 为进程‘续命’
zookper实现分布式锁:
1.zookper的数据结构模型
zookper的数据结构很像数据结构中的树结构,也很像文件系统的目录:
树的由节点组成,zookper的数据结构同样是基于节点,节点的名字叫znode,但不同于树的节点,znode的引用方式的路径引用,类似于文件路径;
znode包含哪些东西?
1.data:znode储存的数据信息;
2.ACI:记录znode的访问权限;
3.stat:包含zookper的各种元数据,比如事务ID,版本号,时间戳,大小等;
4.child:当前节点的子节点的引用;
那为什么zookper不用做数据存储呢?
zookper是为读多写少的场景设计的,并且zookper每个节点的最大数据容量仅为1M并不适合用来储存大量业务数据,而适合储存少量状态和配置信息;
zookper常用的客户端命令
exists,getdata,getchildren属于读操作,zookper在请求读操作时可以选择是否设置watch
zookper 的事件通知机制::
zookper实现了观察者模式,watcher可以被看作是注册在特定znode上的触发器,当这个znode发生改变时,将会触发znode上注册的对应的事件,请求watch的客户端会接收到异步通知。
zookper实现自身的高可用
问题1 :zookper如何保证zookper集群的数据同步
一主多从结构,读写分离;
zookper是一主多从读写分离的结构,
更新数据时,首先更新到主节点,(这里指的是服务不是znode),再同步到子节点。
在读取数据时,直接读取任意从节点;
既然zookper是分布式系统的协调服务,并且是一主多从的结构,那如果那主机异常挂掉了怎么办?
什么是ZAB协议zookper atomic broadeast**
它有效解决了集群崩溃恢复,以及主从同步数据的问题;
ZAB协定的三种节点状态?
locking:选举状态
following:Follower节点(从节点)所处的状态;
leading:leader(主)节点所处的状态;
最大ZXID
最大zxid是节点本地最新的事务编号,包含epoch和计数两部分,epoch相当于raft选举时候的term
ZAB的崩溃修复过程
1.Leader election
选举阶段,此时集群中的节点处于Locking状态,他们各自向其他节点投票,投票当中包含自己的进程id和最新事务id(zxid)
2.接下来每个节点会将自己的zxid和收到的其他节点的zxid做对比,若比该节点小,则投票给该节点,反之不投票;
3.每次投票后,服务器都会统计票数,判断是否有节点获得了半数以上节点的票,若有则该节点将成为准节leader(主)点,该节点状态也将变为Leading,其他节点状态变为following。
4.Discovery
发现阶段,用于在从节点中发现最新的zxid和事务日志,解决因为网络或者其他原因出现多主的情况。
zookper是如何保证数据的一致性的?
为了保证主从节点数据的一致性,zookper采用了ZAB协议,这种协议特别类似于一致性算法paxos,raft.
zookper主从节点数据同步过程:
1.客户端请求写数据给任意Follower,
2.收到请求的Follower将写数据请求转发给leader
3.Leader采用二段是提交方式,先发送propose广播给leader(开启事务)
4.Followe接收到leader的propose消息后,写入日志成功,并返回ACK给Leader。
5.Leader接收到半数以上的ACK消息后返回成功给客户端并广播commit给Follower(提交并结束事务)
Zookper怎么实现分布式锁的?
简单说就是使用临时节点有序节点实现等待锁队列+watcher实现锁的自动释放而实现了高可用,高性能的分布式锁
Zookper的数据储存结构就像一颗树一样,这颗树由节点组成,这种节点叫做Zonde。
znode有四种状态:
持久化节点
持久化节点有序节点
临时节点
临时节点有序节点
持久节点:
持久节点顺序节点就是,在节点创建时候,zookper会根据创建时间的先后为节点进行编号:
临时节点:
和持久节点相反,当创建节点的客户端与zookper断开连接时,临时节点会被删除
Zookper与redis分布式锁的比较
数据一致性:
强一致性
弱一致性
顺序一致性: zookper
zookper的应用场景:
分布式锁
服务注册和发现 up:
共享配置和状态信息
zookper的部署
zookper的部署方式:
单机部署,集群部署,伪集群部署,
zookper的配置文件:
zookper的三种端口:
2181:客户端连接至zookper集群使用的监听端口;
3888:选举leader是一样;
2888:集群内机器通讯使用(leader与follower之间数据同步使用的端口号,Leader监听此端口)
Dubbo
什么是dubbo?
简单说:dubbo是面向接口的远程方法调用。
dubbo的特性:
dubbod的组件: