~1、mq消息持久化
Broker(中间人/代理人)主要由Exchange和Queue组成:Exchange负责接收消息、转发消息到绑定的队列;Queue存储消息,提供持久化、队列等功能
转载链接:https://blog.csdn.net/qbian/article/details/70198066?utm_source=itdadao&utm_medium=referral
如果消息想要从Rabbitmq崩溃中恢复,那么消息必须满足以下条件:
HBase是建立在Hadoop文件系统之上的分布式面向列的数据库
HDFS(Hadoop Distributed File System)是Hadoop项目的核心子项目,是分布式文件系统,有着高容错性,并且设计用来部署在
低廉的硬件上。而且它提供高吞吐量
1、mycat:开源的分布式数据库系统,作用就是分库分表 一开始基于mysql后来各种数据库都支持
转载链接:https://blog.csdn.net/wt077521/article/details/80469015
MyCat技术原理中最重要的一个动词是“拦截”,它拦截了用户发送过来的SQL语句,首先对SQL语句做了一些特定的分析:
如分片分析、路由分析、读写分离分析、缓存分析等,然后将此SQL发往后端的真实数据库,并将返回的结果做适当的处理,
最终再返回给用户。
2、MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法。应用程序通过读写出入队列的消息(针对应用程序
的数据)来通信,而无需专用连接来链接它们。消息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来
通信,直接调用通常是用于诸如远程过程调用的技术,遵循AMQP协议
3、Kafka是一个分布式、支持分区的(partition)、多副本的(replica)基于zookeeper协调的分布式消息系统,它的最大的特性就是
可以实时的处理大量数据以满足各种需求场景。消息队列 Kafka 是一个分布式的、高吞吐量、高可扩展性消息队列服务。是一个消息队列
4、NoSQL数据库Cassandra、Mongodb、CouchDB、Redis、 Riak、Membase、Neo4j 和 HBase
5、关系型数据库遵循ACID规则(原子性(Atomicity)、一致性(Consistency)、
(基本可用(Basically Availble)、软/柔性事务(Soft-state )、最终一致性(Eventual Consistency))
~5、分布式事务:2pc&3pc
协调者,参与者
2pc也就是XA协议:prepare,commit 如果协调者跟参与者同时挂了就可能会出现数据不一致的问题,因为两方都不知道挂的参与者
究竟什么状态
3pc:CanCommit、PreCommit、DoCommit 可以根据其他参与者状态来判断挂掉的参与者是commit还是rollback,也可能存在abort
没有及时被参与者收到在等待超时之后参与者自动执行了commit,也会存在数据不一致
转载链接:https://blog.csdn.net/yyd19921214/article/details/68953629
~6、dubbo
服务发现服务治理,分布式服务框架,服务提供者,消费者,注册中心,监控者,
容器启动服务提供者,服务提供者向注册中心注册自己提供的服务,服务消费者在启动时向注册中心订阅自己所需的服务。注册中心如果地址
有变更则将基于长连接推送变更数据给消费者,服务消费者。监控者会检测各服务的心跳以及统计各个请求的时间以及频率。
~142、Zookeeper工作原理
Zookeeper 的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式,
它们分别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,
且大多数Server完成了和 leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态。
为了保证事务的顺序一致性,zookeeper采用了递增的事务id号(zxid)来标识事务。所有的提议(proposal)都在被提出的时候加上了zxid。
实现中zxid是一个64位的数字,它高32位是epoch用来标识leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch,
标识当前属于那个leader的统治时期。低32位用于递增计数。
分布式‘锁’ - prv:包含3个方面-临时节点、有序节点、节点监听。查看locks下有没有节点,没有就建一个临时节点,节点序号按照从小到大递增
如果要找寻节点不是当前locks下最小节点,那么就监听比当前监听序号小1的对应的上一个节点,当上一节点释放的时候就能获得锁了,
如果不是监听上一个节点,而监听全部节点,这样每一个节点变化都会通知到所有监听服务,那就会变成羊群效应了。节点的变化有几种,
节点建立、删除、节点内容变更、子节点变更。
prv:通过监听各自对应的不同节点来实现分布式锁,跟线程类似,都需要判断计数是否为0,不为0就继续等待I(对应最小节点)
设置的监听是一次性的,节点变动就会通知监听者。
转载链接:https://blog.csdn.net/liu857279611/article/details/70495413
~7、限流、熔断
转载链接:https://www.cnblogs.com/DengGao/p/rateLimit.html
降级:业务降级,是指牺牲非核心的业务功能,保证核心功能的稳定运行
SLA:(正常运行时间保障协议)Service-Level Agreement的缩写,意思是服务等级协议。是关于网络服务供应商和客户间的一份合同,其中定义了服务类型、服务质量和客户付款等术语。
限流
根据排队理论,具有延迟的服务随着请求量的不断提升,其平均响应时间也会迅速提升,为了保证服务的SLA,有必要控制单位时间的请求量。
这就是限流为什么愈发重要的原因。
qps限流
限制每秒处理请求数不超过阈值。
并发限流
限制同时处理的请求数目。Java 中的 Semaphore 是做并发限制的好工具,特别适用于资源有效的场景。
单机限流
Guava 中的 RateLimiter。
集群限流
TC 提供的 common-blocking 组件提供此功能。
算法
漏桶算法
漏桶算法思路很简单,水(请求)先进入到漏桶里,漏桶以一定的速度出水,当水流入速度过大会直接溢出,可以看出漏桶算法能强行限
制数据的传输速率。
~8、Zookeeper、dubbo
dubbo(服务治理框架): Dubbo是阿里巴巴SOA服务化治理方案的核心框架,服务治理框架。Dubbo只是实现了服务治理,而Spring Cloud子项目
分别覆盖了微服务架构下的众多部件,而服务治理只是其中的一个方面
其核心部分包含:
远程通讯: 提供对多种基于长连接的NIO框架抽象封装,包括多种线程模型,序列化,以及“请求-响应”模式的信息交换方式。
集群容错: 提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。
自动发现: 基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。
zookeeper(协调服务框架):ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,
是Hadoop和Hbase的重要组件
dubbo:远程通讯、集群容错、自动发现
Zookeeper:原子性广播、事物顺序一致性(1.命名服务2.配置管理3.集群管理4.分布式锁5.队列管理)
分布式锁:临时节点,有序节点,节点监听
Zookeeper 的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式,
它们分别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,
且大多数Server完成了和 leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态。
为了保证事务的顺序一致性,zookeeper采用了递增的事务id号(zxid)来标识事务。所有的提议(proposal)都在被提出的时候加上了zxid。
实现中zxid是一个64位的数字,它高32位是epoch用来标识leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch,
标识当前属于那个leader的统治时期。低32位用于递增计数。
prv:
工作原理:
协调式服务框架,协调当然是最主要的,通知跟控制通知-原子性广播与事务顺序一致性
原子性广播:恢复模式和广播模式-选主跟通知同步
事务顺序一致性:32位时代标志+32位递增计数
优化:
jvm,log4j,快照跟日志文件分开存储,ACL(Access Control List)减少权限验证,写请求数据到磁盘,文件自动清理
1:jvm配置
2:log4j配置
3:zoo.cfg文件中,dataDir存放快照数据,dataLogDir存放日志。这两个目录不要配置成一个路径,要配置到不同的磁盘上。如果磁盘是使用了raid,系统就一块磁盘,那配置到一块磁盘上也可以。写前日志的部分对写请求的性能影响很大,保证dataLogDir所在磁盘性能良好。
4:zoo.cfg文件中skipACL=yes,忽略ACL验证,可以减少权限验证的相关操作,提升一点性能。
5:zoo.cfg文件中forceSync=no,这个对写请求的性能提升很有帮助,是指每次写请求的数据都要从pagecache中固化到磁盘上,才算是写成功返回。当写请求数量到达一定程度的时候,后续写请求会等待前面写请求的forceSync操作,造成一定延时。如果追求低延时的写请求,配置forceSync=no,数据写到pagecache后就返回。但是机器断电的时候,pagecache中的数据有可能丢失。
6:zk的dataDir和dataLogDir路径下,如果没有配置zk自动清理,会不断的新增数据文件。可配置成zk系统自动清理数据文件,但是最求系统最高性能的话,建议人工手动清理文件:zkCleanup.sh -n 3 这样保留三份文件。
7:查看zk节点状态。重新启动zk节点前后,一定要查看状态
8:配置fsync.warningthresholdms=20,单位是毫秒,在forceSync=yes的时候,如果数据固化到磁盘的操作fsync超过20ms的时候,将会在zookeeper.out中输出一条warn日志。这个目前zk的3.4.5和3.5版本有bug,在zoo.cfg中配置不生效。我的做法是在conf/java.env中添加java系统属性:、
zookeeper用来注册服务和进行负载均衡
转载链接:https://www.cnblogs.com/xiaofei1208/p/7077733.html
zookeeper通过心跳机制可以检测挂掉的机器并将挂掉机器的ip和服务对应关系从列表中删除。至于支持高并发,简单来说就是横向扩展,
在不更改代码 的情况通过添加机器来提高运算能力。通过添加新的机器向zookeeper注册服务,服务的提供者多了能服务的客户就多了。
3. zookeeper和dubbo的关系:
Dubbo的将注册中心进行抽象,是得它可以外接不同的存储媒介给注册中心提供服务,有ZooKeeper,Memcached,Redis等。
引入了ZooKeeper作为存储媒介,也就把ZooKeeper的特性引进来。首先是负载均衡,单注册中心的承载能力是有限的,在流量达到一定程度
的时候就需要分流,负载均衡就是为了分流而存在的,一个ZooKeeper群配合相应的Web应用就可以很容易达到负载均衡;资源同步,单单有
负载均衡还不够,节点之间的数据和资源需要同步,ZooKeeper集群就天然具备有这样的功能;命名服务,将树状结构用于维护全局的服务
地址列表,服务提供者在启动 的时候,向ZK上的指定节点/dubbo/${serviceName}/providers目录下写入自己的URL地址,这个操作就完
成了服务的发布。其他特性还有Mast选举,分布式锁等。
基于Zookeeper的分布式锁
转载链接:https://blog.csdn.net/qiangcuo6087/article/details/79067136
Zookeeper(业界简称zk)是一种提供配置管理、分布式协同以及命名的中心化服务,这些提供的功能都是分布式系统中非常底层且必不可少的
基本功能,但是如果自己实现这些功能而且要达到高吞吐、低延迟同时还要保持一致性和可用性,实际上非常困难。因此zookeeper提供了这些
功能,开发者在zookeeper之上构建自己的各种分布式系统。
所以调整后的分布式锁算法流程如下:
客户端连接zookeeper,并在/lock下创建临时的且有序的子节点,第一个客户端对应的子节点为/lock/lock-0000000000,第二个为/lock/lock-0000000001,以此类推;
客户端获取/lock下的子节点列表,判断自己创建的子节点是否为当前子节点列表中序号最小的子节点,如果是则认为获得锁,否则监听刚好在自己之前一位的子节点删除消息,获得子节点变更通知后重复此步骤直至获得锁;
执行业务代码;
完成业务流程后,删除对应的子节点释放锁。
远程方法调用(Remote Method Invocation,RMI)是用Java在JDK1.1中实现的,它大大增强了Java开发分布式应用的能力。从最基本的角度
看,RMI是Java的远程过程调用(RPC)机制。
RMI(Remote Method Invocation)远程方法调用是一种计算机之间利用远程对象互相调用实现双方通讯的一种通讯机制。使用这种机制,某一
台计算机上的对象可以调用另外一台计算机上的对象来获取远程数据
RMI是Enterprise JavaBeans的支柱,是建立分布式Java应用程序的方便途径。在过去,TCP/IP套接字通讯是远程通讯的主要手段,但此开
发方式没有使用面向对象的方式实现开发,在开发一个如此的通讯机制时往往令程序员感觉到乏味,对此RPC(Remote Procedure Call)应运
而生,它使程序员更容易地调用远程程序,但在面对复杂的信息传讯时,RPC依然未能很好的支持,而且RPC未能做到面向对象调用的开发
模式。针对RPC服务遗留的问题,RMI出现在世人面前,它被设计成一种面向对象的通讯方式,允许程序员使用远程对象来实现通信,并且支
持多线程的服务,这是一次远程通讯的革命,为远程通信开辟新的里程碑。
转载链接:https://www.cnblogs.com/leslies2/archive/2011/05/20/2051844.html
RMI的开发步骤
先创建远程接口及声明远程方法,注意这是实现双方通讯的接口,需要继承Remote
开发一个类来实现远程接口及远程方法,值得注意的是实现类需要继承UnicastRemoteObject
通过javac命令编译文件,通过java -server 命令注册服务,启动远程对象
最后客户端查找远程对象,并调用远程方法
转载链接:https://www.jianshu.com/p/ad5bc07b1b3e
首先,什么是dubbo?
Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。
其核心部分包含:
远程通讯: 提供对多种基于长连接的NIO框架抽象封装,包括多种线程模型,序列化,以及“请求-响应”模式的信息交换方式。
集群容错: 提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。
自动发现: 基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。
那么,Dubbo能做什么?
透明化的远程方法调用,就像调用本地方法一样调用远程方法,只需简单配置,没有任何API侵入。
软负载均衡及容错机制,可在内网替代F5等硬件负载均衡器,降低成本,减少单点。
服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址,并且能够平滑添加或删除服务提供者。
SOA 面向服务的体系结构(service-oriented architecture,SOA)
~9、RPC跟RMI区别
1:方法调用方式不同
RMI中是通过在客户端的Stub对象作为远程接口进行远程方法的调用。每个远程方法都具有方法签名。如果一个方法在服务器上执行,但是没
有相匹配的签名被添加到这个远程接口(stub)上,那么这个新方法就不能被RMI客户方所调用。
RPC中是通过网络服务协议向远程主机发送请求,请求包含了一个参数集和一个文本值,通常形成“classname.methodname(参数集)”的形式。
RPC远程主机就去搜索与之相匹配的类和方法,找到后就执行方法并把结果编码,通过网络协议发回。
2:适用语言范围不同
RMI只用于Java;
RPC是网络服务协议,与操作系统和语言无关。
**~10、概念:zookeeper分布式锁,CAS,fail-fast,**synchronize&retreenlock,dubbo,zookeeper,concurrenthashmap&hashtable
zookeeper分布式锁:
分布式锁 - prv:
分布式锁跟线程锁同理,分布式锁获取的是最小节点
包含3个方面-临时节点、有序节点、节点监听。查看locks下有没有节点,没有就建一个临时节点,节点序号按照从小到大递增
如果要找寻节点不是当前locks下最小节点,那么就监听比当前监听序号小1的对应的上一个节点,当上一节点释放的时候就能获得锁了,
如果不是监听上一个节点,而监听全部节点,这样每一个节点变化都会通知到所有监听服务,那就会变成羊群效应了。节点的变化有几种,
节点建立、删除、节点内容变更、子节点变更。
CAS(Lock-free):compareAndSwap:比较交换,用于乐观锁,内存值V跟预期值A以及要修改的新值B,当v=A的时候,更新B到内存,否则不更新
fail-fast:跟iterator相关,如果一个线程正在iterator遍历的值被另一个线程修改了,就会报异常ConcurrentModificationException
分离锁:concurrentHaspMap有分离锁,区别于hashtable锁整个表,chm只锁对应的通segment[ˈsegmənt](单个或多个链表结构),可支持多个线程访问
指令重排序:volatile:为了减少由于内存操作速度比cpu运行速度慢导致cpu空置的影响,虚拟机会按照自己的一些规则将程序顺序打乱,即后面的代码有可能会先执行。(前提是不影响程序逻辑结果)
synchronize&ReenTranLock:
1、syn引入偏向锁、轻量级锁(自旋锁),性能比re好
2、ReenTranLock特有:可指定是否公平锁,按条件分组唤醒(syn是唤醒一个或全部),中断锁
dubbo:远程通讯、集群容错、自动发现(软负载均衡,失败容错,地址路由,动态配置等集群支持) prv:rpc+- (+自动发现-集群容错)
Zookeeper:原子性广播、事务顺序一致性(1.命名服务2.配置管理3.集群管理4.分布式锁5.队列管理)
协调式服务框架,协调当然是最主要的,通知跟控制通知-原子性广播与事务顺序一致性
原子性广播:恢复模式和广播模式-选主跟通知同步
事务顺序一致性:32位时代标志+32位递增计数
什么是原子性,就是不可分,从头执行到尾,不能被其他线程同时执行。可通过CAS来实现原子操作
自旋锁:(线程上下文切换代价高于等待资源代价-原地“忙”等)处理器阻塞一个线程引起的线程上下文的切换的代价高于等待资源的代价的时候(锁的已保持者保持锁时间比较短),那么线程B可以不放弃CPU时间片,而是在“原地”忙等。可能问题-占用过多cpu、死锁
可重入锁:获得锁的线程(计数0,记录线程信息)再次进入获得锁,则计数自增1,释放就减计数直到0才给其他线程进入
偏向锁:给优先进入的线程,记录线程信息,如果使用完则膨胀为轻量级锁,无需每次加锁解锁都去CAS更新对象头。在实际应用运行过程中发现,“锁总是同一个线程持有,很少发生竞争”,也就是说锁总是被第一个占用他的线程拥有,这个线程就是锁的偏向线程。那么只需要在锁第一次被拥有的时候,记录下偏向线程ID。这样偏向线程就一直持有着锁,直到竞争发生才释放锁。以后每次同步,检查锁的偏向线程ID与当前线程ID是否一致,如果一致直接进入同步,退出同步也,无需每次加锁解锁都去CAS更新对象头,如果不一致意味着发生了竞争,锁已经不是总是偏向于同一个线程了,这时候需要锁膨胀为轻量级锁,才能保证线程间公平竞争锁。
2.可中断锁,synchronized就不是可中断锁,而Lock是可中断锁。
3.公平锁,公平锁即尽量以请求锁的顺序来获取锁
4.读写锁,读写分两个锁
concurrenthashmap&hashtable:concurrenthashmap桶力度锁区别于hashtable锁整个表,它只锁单个桶
~11、限流算法之漏桶算法、令牌桶算法
转载链接:https://blog.csdn.net/tianyaleixiaowu/article/details/74942405
prv:漏桶算法类似油海(缺点是开口不可调),令牌桶算法类似小孩抓糖果,给了多少抓多少。没了肯定就阻塞了。信号量是让指定线程获取
运行权限/一对一交接拿到信号才能获得锁(通常用于限制并发量)。
semaphore信号量通常用于限制并发量
限流的三种算法
限流主要有三种算法:信号量、漏桶算法和令牌桶算法。
信号量限制的是并发、资源。令牌桶限制的是QPS。
Semaphore是一个计数信号量。常用于限制获取某资源的线程数量,可基于java的concurrent并发包实现。
通过acquire()方法获取许可,该方法会阻塞,直到获取许可为止。
通过release()方法释放许可。
RateLimiter是Guava的concurrent包下的一个用于限制访问频率的类.
1.限流
每个API接口都是有访问上限的,当访问频率或者并发量超过其承受范围时候,我们就必须考虑限流来保证接口的可用性或者降级可用性.
即接口也需要安装上保险丝,以防止非预期的请求对系统压力过大而引起的系统瘫痪.(跟微信公众号接口访问频率同理)
通常的策略就是拒绝多余的访问,或者让多余的访问排队等待服务,或者引流.
如果要准确的控制QPS,简单的做法是维护一个单位时间内的Counter,如判断单位时间已经过去,则将Counter重置零.此做法被认为没有很好的处理单位时间的边界,比如在前一秒的最后一毫秒里和下一秒的第一毫秒都触发了最大的请求数,将目光移动一下,就看到在两毫秒内发生了两倍的QPS.
2.限流算法
常用的更平滑的限流算法有两种:漏桶算法和令牌桶算法.
2.1 漏桶算法
漏桶(Leaky Bucket)算法思路很简单,水(请求)先进入到漏桶里,漏桶以一定的速度出水(接口有响应速率),当水流入速度过大会直接溢出(访问频率超过接口响应速率),然后就拒绝请求,可以看出漏桶算法能强行限制数据的传输速率.示意图如下:
可见这里有两个变量,一个是桶的大小,支持流量突发增多时可以存多少的水(burst),另一个是水桶漏洞的大小(rate),伪代码如下:
因为漏桶的漏出速率是固定的参数,所以,即使网络中不存在资源冲突(没有发生拥塞),漏桶算法也不能使流突发(burst)到端口速率.因此,漏桶算法对于存在突发特性的流量来说缺乏效率.
2.2 令牌桶算法
令牌桶算法(Token Bucket)和 Leaky Bucket 效果一样但方向相反的算法,更加容易理解.随着时间流逝,系统会按恒定1/QPS时间间隔(如果QPS=100,则间隔是10ms)往桶里加入Token(想象和漏洞漏水相反,有个水龙头在不断的加水),如果桶已经满了就不再加了.新请求来临时,会各自拿走一个Token,如果没有Token可拿了就阻塞或者拒绝服务.
令牌桶的另外一个好处是可以方便的改变速度. 一旦需要提高速率,则按需提高放入桶中的令牌的速率. 一般会定时(比如100毫秒)往桶中增加一定数量的令牌, 有些变种算法则实时的计算应该增加的令牌的数量.
3.RateLimiter简介
Google开源工具包Guava提供了限流工具类RateLimiter,该类基于令牌桶算法(Token Bucket)来完成限流,非常易于使用.RateLimiter经常用于限制对一些物理资源或者逻辑资源的访问速率.它支持两种获取permits接口,一种是如果拿不到立刻返回false,一种会阻塞等待一段时间看能不能拿到.
RateLimiter和Java中的信号量(java.util.concurrent.Semaphore)类似,Semaphore通常用于限制并发量.