1、关于分布式锁的了解?
原理:控制分布式系统有序的去对共享资源进行操作,通过互斥来保持一致性。
具备的条件:
①分布式环境下,一个方法在同一时间只能被一个机器的一个线程执行
②高可用的获取锁和释放锁
③高性能的获取锁和释放锁
④具备可重入特性
⑤具备锁失效机制,防止死锁
分布式锁的三种实现:
A. 基于数据库实现分布式锁;
B. 基于缓存(Redis等)实现分布式锁;
C. 基于Zookeeper实现分布式锁
A.基于数据库的实现:
在数据库中创建一个表,表中包含方法名等字段,并在方法名字段上创建唯一索引,想要执行某个方法,就是用这个方法名向表中插入数据,成功插入则获取锁,执行完成后删除对应的行数据释放锁
B.基于缓存(Redis等)实现分布式锁:
推荐: Redis有很高的性能;
Redis命令对此支持较好,实现起来比较方便
实现:
(1)获取锁的时候,使用setnx加锁,并使用expire 命令为锁添加一个超时时间,超过该时间则自动释放锁,锁的value值为一个随机生成的UUID,通过此在释放锁的时候进行判断。
(2)获取锁的时候设置一个获取的超时时间,若超过这个时间就放弃获取锁。
(3)释放锁的时候,通过UUID判断是不是该锁,若是该锁,就执行delete进行锁释放。
C.基于Zookeeper的实现方式
原因: Zookeeper是一个为分布式应用提供一致性服务的开源组件,它内部是一个分层的文件系统目录树结构,规定同一个目录下只能有一个唯一文件名。
实现:
- 创建一个目录mylock
- 线程A想获取锁就在mylock目录下创建临时顺序节点
- 获取mylock目录下所有的子节点,然后获取比自己小的兄弟节点,如果不存在,则说明当前线程顺序号最小,获得锁;
- 线程B获取所有节点,判断自己是不是最小的节点,设置监听比自己次小的节点
- 线程A处理完,删除自己的节点,线程B监听到便跟事件,判断自己是不是最小的节点,如果是则获得锁。
- 使用Apache的开源库Curator,它是一个Zookeeper客户端,Curator提供的InterProcessMutex是分布式锁的实现,acquire方法用于获取锁,release方法用于释放锁。
2、 分布式事务处理机制
在CAP定理中,一致性、可用性、分区容错性是不可能同时存在的。但在实际的应用场景中,数据的一致性是需要保证的。
事务是达到以上目的的最好方法:
即保证执行结果的正确性;保证数据的一致性;ACID
常见的事务处理机制:
Master-Slave 复制:
Slave一般是Master的备份。读写都在Master上,异步同步数据到Slave;Master挂了,Slave只能读。
Master-Master多主复制:
2个以上Master,都提供读写服务。一台挂了,另一台正常读写。
两阶段提交:
第一阶段:准备阶段:
协调者节点向所有参与者节点询问是否可以执行提交操作,并开始等待各参与者节点的响应。参与者节点执行询问发起为止的所有事务操作,并将Undo信息和Redo信息写入日志。各参与者节点响应协调者节点发起的询问。
第二阶段:提交阶段:
如果协调者收到了参与者的失败消息或者超市直接给每个参与者发送回滚(Rollback)消息;否则,发送提交(Commit)消息;参与者根据协调者的指令执行提交或者回滚操作,释放所有事务处理过程中使用的锁资源。
三阶段提交:
CanCommit阶段:协调者向参与者发送commit请求,参与者如果可以提交就返回Yes响应,否则返回No响应。
PreCommit阶段:协调者根据参与者的反应情况来决定是否可以记忆事务的PreCommit操作。
doCommit阶段:进行真正的事务提交。具体为执行提交、终端事务。
3、用分布式和没有用分布式的项目的差异是什么?
- 传统项目:
存在问题:
1:模块之间耦合度太高,其中一个功能升级,其他的模块都得一起升级部署。
2:开发困难,各个团队开发最后都要整合在一起.
3:系统扩展性差
4:不能灵活进行分布式部署
解决方案:
把模块才分成独立的工程,单节点运行,如果某一个节点压力大了可以单独对这个节点进行增加配置,其他节点不受影响。缺点就是系统之间交互需要额外的工作量来进行接口的开发。把系统拆分成多个工程,需要完成系统的工程需要多个工程协作完成,这种形式就叫做分布式。
- 分布式:
把系统拆分成多个子系统.
优点:
1:把模块拆分,使用接口通信,降低模块之间的耦合度.
2:把项目拆分成若干个子项目,不同的团队负责不同的子项目.
3:增加功能时只需要再增加一个子项目,调用其他系统的接口就可以。
4:可以灵活的进行分布式部署.
5:提高代码的复用性,比如service层,如果不采用分布式rest服务方式架构就会在手机wap商城,微信商城,pc,android,ios每个端都要写一个service层逻辑,开发量大,难以维护一起升级,这时候就可以采用分布式rest服务方式,公用一个service层。