分布式

14 篇文章 0 订阅
14 篇文章 0 订阅

~1、mq消息持久化
Broker(中间人/代理人)主要由Exchange和Queue组成:Exchange负责接收消息、转发消息到绑定的队列;Queue存储消息,提供持久化、队列等功能
转载链接:https://blog.csdn.net/qbian/article/details/70198066?utm_source=itdadao&utm_medium=referral
如果消息想要从Rabbitmq崩溃中恢复,那么消息必须满足以下条件:

  1. 把它的投递默认选项设置为持久化
  2. 发送到持久化的交换机
  3. 到达持久化的队列
    prv:比如是节目现场念纸条,先要让人默认投递内容而不是直接喊,由人传递到主席台,到达主持人处
    ~2、“服务熔断”和“服务降级”。
    prv:服务熔断-责任链结构的服务下游的某个服务挂了,让中间的服务做一些预定处理,比如返回提示当前排队人数过多…。服务降低-关掉某服务
    服务降级,整体资源快不够了,忍痛将某些服务先关掉,待渡过难关,再开启回来。
    对于这两个概念,号称支持的框架可不少,Hystrix当属其中的佼佼者。
    熔断器实现的三个状态机:
    Closed:熔断器关闭状态,调用失败次数积累,到了阈值(或一定比例)则启动熔断机制;
    Open:熔断器打开状态,此时对下游的调用都内部直接返回错误,不走网络,但设计了一个时钟选项,默认的时钟达到了一定时间(这个时间一般设置成平均故障处理时间,也就是MTTR),到了这个时间,进入半熔断状态;
    Half-Open:半熔断状态,允许定量的服务请求,如果调用都成功(或一定比例)则认为恢复了,关闭熔断器,否则认为还没好,又回到熔断器打开状态;
    而两者的区别也是明显的:
    触发原因不太一样,服务熔断一般是某个服务(下游服务)故障引起,而服务降级一般是从整体负荷考虑;
    管理目标的层次不太一样,熔断其实是一个框架级的处理,每个微服务都需要(无层级之分),而降级一般需要对业务有层级之分
    (比如降级一般是从最外围服务开始)
    实现方式不太一样,这个区别后面会单独来说;
    ~3、Redis雪崩、穿透、热点key等优化
    数据类型:String、hash、list、set、sorted set
    转载链接:https://www.cnblogs.com/hjwublog/p/5639990.html
    转载链接:https://blog.csdn.net/qq_21583681/article/details/78463000
    缓存穿透
    然而缓存可能会遇到这种问题:请求cache拿不到数据,就会去存储层拿,都拿不到时,返回空值(可能会返回大量空值)。
    或者代码有问题,拿不到数据。就会一直请求数据。导致后端打崩。
    优化方法:
    1、缓存层缓存空值。
    –缓存太多空值,占用更多空间。(优化:给个空值过期时间)
    –存储层更新代码了,缓存层还是空值。(优化:后台设置时主动删除空值,并缓存把值进去)
    缓存雪崩
    redis挂了,客户端直接请求到数据库里面。数据库负载非常高。甚至数据库拖挂了。
    优化方法:
    1、保持缓存层服务器的高可用。
    –监控、集群、哨兵。当一个集群里面有一台服务器有问题,让哨兵踢出去。
    2、依赖隔离组件为后端限流并降级。
    比如推荐服务中,如果个性化推荐服务不可用,可以降级为热点数据。
    3、提前演练。
    演练 缓存层crash后,应用以及后端的负载情况以及可能出现的问题。
    对此做一些预案设定。
    prv:哨兵群有一个主哨兵(负责故障转移处理),哨兵们会隔1秒就发一次心跳检测,看其他哨兵是否正常,根据投票机制把失效的
    哨兵处理掉。
    热点key重建
    A、B、C、D同时请求一个资源,不存在时都要去请求存储层,有可能会拖挂。
    优化方法:
    1、互斥锁:
    只允许一个请求重建缓存。
    其他请求等待缓存重建执行完,重新从缓存获取数据即可。
    2、用户过期
    –“物理”不过期
    –逻辑设置过期时间(根据上一次更新时间,构建一个队列,主动去更新)
    4、zookeeper\hbase\mycat\mq\Kafka\nosql
    ZooKeeper:分布式应用程序协调服务
    zookeeper的四种类型的节点
    znode创建类型(CreateMode),有以下四种:
    1、PERSISTENT 持久化节点
    2、PERSISTENT_SEQUENTIAL 顺序自动编号持久化节点,这种节点会根据当前已存在的节点数自动加 1
    3、EPHEMERAL 临时节点, 客户端session超时这类节点就会被自动删除
    4、EPHEMERAL_SEQUENTIAL 临时自动编号节点
    转载链接:https://www.cnblogs.com/ASPNET2008/p/6421571.html
    okeeper选举机制
    zookeeper集群
    配置多个实例共同构成一个集群对外提供服务以达到水平扩展的目的,每个服务器上的数据是相同的,每一个服务器均可以对外提供读和写的
    服务,这点和redis是相同的,即对客户端来讲每个服务器都是平等的。
    这篇主要分析leader的选择机制,zookeeper提供了三种方式:
    LeaderElection
    AuthFastLeaderElection
    FastLeaderElection
    默认的算法是FastLeaderElection,所以这篇主要分析它的选举机制。
    选择机制中的概念
    服务器ID
    比如有三台服务器,编号分别是1,2,3。
    编号越大在选择算法中的权重越大。
    数据ID
    服务器中存放的最大数据ID.
    值越大说明数据越新,在选举算法中数据越新权重越大。
    逻辑时钟
    或者叫投票的次数,同一轮投票过程中的逻辑时钟值是相同的。每投完一次票这个数据就会增加,然后与接收到的其它服务器返回的投票信
    息中的数值相比,根据不同的值做出不同的判断。
    选举状态
    LOOKING,竞选状态。
    FOLLOWING,随从状态,同步leader状态,参与投票。
    OBSERVING,观察状态,同步leader状态,不参与投票。
    LEADING,领导者状态。
    选举消息内容
    在投票完成后,需要将投票信息发送给集群中的所有服务器,它包含如下内容。
    服务器ID
    数据ID
    逻辑时钟
    选举状态
    因为每个服务器都是独立的,在启动时均从初始状态开始参与选举
    默认是采用投票数大于半数则胜出的逻辑。
    选举流程简述
    目前有5台服务器,每台服务器均没有数据,它们的编号分别是1,2,3,4,5,按编号依次启动,它们的选择举过程如下:
    服务器1启动,给自己投票,然后发投票信息,由于其它机器还没有启动所以它收不到反馈信息,服务器1的状态一直属于Looking。
    服务器2启动,给自己投票,同时与之前启动的服务器1交换结果,由于服务器2的编号大所以服务器2胜出,但此时投票数没有大于半数,
    所以两个服务器的状态依然是LOOKING。
    服务器3启动,给自己投票,同时与之前启动的服务器1,2交换信息,由于服务器3的编号最大所以服务器3胜出,此时投票数正好大于半数,
    所以服务器3成为领导者,服务器1,2成为小弟。
    服务器4启动,给自己投票,同时与之前启动的服务器1,2,3交换信息,尽管服务器4的编号大,但之前服务器3已经胜出,所以服务器4只能
    成为小弟。
    服务器5启动,后面的逻辑同服务器4成为小弟。
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通常用于限制并发量.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值