赞
踩
CAP理论
BASE理论 我觉得说了和没说一样,其实就是CA每一个都做了点妥协
限流
降级
降级是指自己的待遇下降了,从RPC调用环节来讲,就是去访问一个本地的伪装者而不是真实的服务。 当双11活动时,把无关交易的服务统统降级,如查看蚂蚁深林,查看历史订单,商品历史评论,只显示最后100条等等。
什么是服务降级?当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心交易正常运作或高效运作。
熔断
熔断机制是应对雪崩效应的一种微服务链路保护机制。在微服务架构中,熔断机制也是起着类似的作用。当扇出链路的某个微服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。当检测到该节点微服务调用响应正常后,恢复调用链路。
在Spring Cloud框架里,熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内20次调用失败,就会启动熔断机制。
微服务的雪崩–通过熔断框架来解决
A调用B,B调用C,C调用D,但D发生故障的时候,C会进行重试,但是A还是会继续发请求给B,导致B占用内存CPU标高,最后大家一起坏掉。
SpringCloud的限流zuul
令牌桶:
想象有一个木桶,系统按照固定速率,例如10ms每次,往桶里加入Token,如果桶已经满了就不再添加。新请求来临时,会各自拿走一个Token,如果没有Token 就拒绝服务。这里如果一段时间没有请求时,桶内就会积累一些token,下次一旦有突发流量,只要token足够,也能一次处理。
总结下令牌桶算法的特点,令牌桶即可以控制进入系统的请求请求量,同时允许突发流
漏桶
限定流出的速度,请求放到桶里面去,如果满了,就终止服务。
使用guava的RateLimiter类—只能单机使用,因为这个类只存在这个服务器上。redis集群部署(也是一主多从)会保证全局一致性。
RateLimiter.tryAcquire(时间),等待获取令牌如果超过一定时间就结束请求。
RateLimiter.acquire(),获取令牌。
**漏桶和令牌桶的区别:**从上面的例子估计大家也能看出来了,漏桶只能以固定的速率去处理请求,而令牌桶可以以桶子最大的令牌数去处理请求
redis实现:
hmset rateLimit last_ms 20 -- 最后时间毫秒 now_permits 20 -- 当前可用的令牌 max_permits 40 -- 令牌桶最大数量 rate 10 --1ms生成多少个令牌 lua的逻辑是: if(last_ms == null){ // 如果没有记录上一次操作的时间 那么就是第一次请求 now_permits = max_permits - 1; // 初始化40个数量 last_ms = CURRENT_TIME; } else { // 获取一个token now_permits = (CURRENT_TIME - last_ms) * 1000 * rate + now_permits; now_permits = Math.min(now_permits,max_permits); if(now_permits <=0 ) { return false; } now_permits--; return true ; }
redis的缓存击穿
key过期了,然后大量的请求进来。
分布式和集群:
集群就是一台机干不了,我就搞两台机。–nginx进行负载均衡
分布式是微服务,一个业务拆分成多个业务,分布在不同的服务器上。
异地多活
就是机房在不同地方,如果一个地方的机房断电了,其他机房是否能够一起承担去往坏机房的请求,其实本质是要解决数据库的问题,程序什么的都是一样的,关键是不同机房的数据是否一致,最基本的解决办法就是分布式经常用到的多个备份,这个库的备份是存在其他机房的。
分层架构
就是指ui、业务实现层、持久层。
分布式事务:
分布式锁:保证多个线程或者多个程序操作一个变量的时候,保证这个变量只有一个线程或者程序在使用,保证变量的安全性。
分布式事务:保证不同数据库的一致性
分布式事务的解决方案
XA协议的两段提交–强一致
由事务管理器来让某一个服务开始事务,这个服务执行完后把结果返回给事务管理器,当所有的服务事务都成功的时候,事务管理器才会让各个服务提交,否则就回滚。
这种形式需要你在每个服务写上开启事务,回滚事务的代码,事务管理器也要自己实现,一般有实力的公司才会这么做。
缺点:同步阻塞:当管理好几个服务的事务的时候,其中一个要执行很久,那么其他的服务已经执行完了也还是在等待那个执行久的,是阻塞的。
缺点如果事务管理器故障了,那么大家都阻塞了,尤其是在第二阶段,事务也没提交,也没回滚,大问题。
三阶段提交3PC
can commit状态,询问所有参与者是否可以执行事务。参与者返回确认信息。
pre commit状态:向各个参与者发送pre commit请求。事务执行了,但是不提交,返回执行结果
do commit状态:向各个参与者发送提交通知。
主要是解决XA协议的单点阻塞问题,如果有一个服务有问题,那么就会默认执行commit。缺点就是这个某个服务commit执行了,其他没有执行不就有问题了么。。
TCC协议其实也就是三段提交只不过有些微不同:
try还是先查询是否可以执行
但所有的服务try都返回ok的时候,事务协调器发送confirm请求,大家开始执行事务,在各自的confirm中提交事务。
如果有一个服务失败了。事务协调器调用每个服务器的cancle,来恢复原来的状态。
其实就是把回滚操作抽出来了一个cancle接口,是要程序员手写sql的,try也要写代码sql实现。。
缺点就是要写很多业务代码,try,cancle都要写。
MQ来实现事务
rocketMQ支持事务消息,kafka和activeMQ不支持但是可以通过他们的ack来实现,这个后面讲:
分布式锁-学习redis实现和zookeeper实现
分布式锁具有的条件:非阻塞的,单个服务可重入的,可以实现公平与非公平锁。
redis实现分布式锁:
关键方法:(记住有个超时的设置)
setnx(); setnx(key,value) 如果key不存在,那么设置当前key的值为value,返回1,如果存在就返回0.
expire(),设置key的有效时限senx 不能直接设置有效时间,只能通过exprie(). 是为了防止,如果程序崩溃了,这个锁一直存在 (释放锁是通过删除key就行了)。所以设置一个过期时间,自动释放。这个是redis自己控制的过期时间。
getset(key,value) 往里面设置值的时候,如果成功就返回旧值,如果第一次的话是返回null。这个用于程序自己控制过期时间, 防止我的业务还没执行完,你的所要失效了,通过getset方法来演唱失效时间。
1 vaule应该是这个客户端的uuid
2 释放的时候应该先判断当前是否当前持有锁的线程再进行释放.
3 另外就是必须有过期时间.
Long startTime = currentTime(); while(true){ if(currentTime > startTime +Time_Out){ return false; } if(tryLock(key)){ return true; }else[ Thread.sleep(1ms); ] } public boolean tryLock(key){ boolean result = setNx(key,guoqishijian); // 设置key的过期时间 if(result){ // 如果设置成功,那么就是代表获得锁了 return true; } if(checkLock(key)){ getSet(key,time)// 设置当前这个服务应该超时的时间。 } } public boolean checkLock(){ Loang time = get(key); // 获取key的超时时间 if(time > currenttime){ return true; } }
redis锁的缺点:这对于单点的redis能很好地实现分布式锁,如果redis集群,会出现master宕机的情况。如果master宕机,此时锁key还没有同步到slave节点上,会出现机器B从新的master上获取到了一个重复的锁。
zookeeper实现分布式锁原理:
首先知道一下zookeeper的一些东西。他一般有多个节点构成,采用zab协议实现高一致性。它本身有一个持久节点,然后有一些临时节点,这些临时节点是这么来的:一个客户端连接上了zk,就会创建一个临时节点,客户端断开连接这个节点就会取消掉。
临时节点按照时间顺序创建node1,node2…
通过watcher机制和临时节点机制,来实现分布式锁。临时节点占用普通节点(持久节点),也可以说是在持久节点下创建临时节点,然后看看自己是不是locker下面最小的节点,如果是说明占有了锁,如果不是就对其调用exits方法watch监听最小的节点,但最小的节点消失后,再看看自己是不是最小的节点。
优点:如果客户端宕机了,他会自动断开,锁也就释放了,不需要做什么超时处理。
缺点:也是如果客户端宕机了,他自动断开,但他如果很快的脸上来了,却还是要排队到后面去。同时性能不高,他是对leader进行操作的,我们知道zookeeper会把leader的所有信息同步到所有follwer上。 另外创建节点和销毁节点费时,消耗zk资源。
zookeeper 注册中心
dubbo 服务发现和调用
docker
docker images
docker pull 下载容器
docker run -di --name=xxx -p xxx 制作容器
docker start 哈希码
docker ps -a 查看启动的容器
springCloud
注解:
@restController
@CrossOrigin 给不同微服务之间调用的
@RequestMapping
@RestControllerAdvice AOP增强 搭配下面的方法:@ExceptionHandller
JPA的东西:
@Entity @table(name = ‘’)指向一个数据库的表PO类
dao层Extends JPArepository
zuul hystix fegin eruka
一致性算法:
为了解决数据一致性,尤其是分布式下分区,脑类情况下(不同机房)某一个区崩溃了,也还是能够保证数据一致性。
Paxos、raft、zab
paxos
提议者proposer:提出提案
决策者acceptor:参与决策,接受提议者的提案,如果这个提案获得大多数决策者同意,那么就称该提案被批准。
最终决策学习者leaner
一致性hash算法:
原来我们要保存一张图片,会把这个图片进行hash然后,对服务器的数量进行取模,确定落到哪台机上。但是如果我们增加了一台服务器,取模的数字变了,原来落在服务器A的照片就跑到B去了,如果是缓存,查找的时候就去B上去找了,而B是没有的,就需要去后台找,导致缓存雪崩。
哈希一直算法就是有一个哈希换长度是232,首先制定好各个服务器所在的位置,然后我们计算完要查询或者保存的文件的hash,之后对232取模,确定他在什么位置,顺时针到下一个服务器,这个服务器就是他要去找的服务器。
这种样式可以减少很大一部分增加了服务器(增加了一台服务器,就指定在环上的一个地方),图片保存的服务器位置变了的情况。
D是新增加的节点,也就是Cd之间的文件会重新落到不同服务器,但是其他的并不会。
其实你也看出来,他的最大问题就是如果节点数量不够,分布不均会导致hash倾斜,这样要重新确定服务器的数量还是很多。办法就是,创建更多的节点,当你的服务器数量并不是很多的时候,你可以创建虚拟映射节点。
raft算法
raft中的主副节点的同步和kafka是一样的,两阶段状态(这个两阶段要和分布式事务的区别开来,分布式事务是TCC三阶段,和MQprepared+comfirm(这个有点像)+两阶段提交(事务控制器))+ack机制。
一开始:每个节点都在等待超时,第一个变成超时的节点就是candidate,然后发起投票,一般就是他变成leader了(每个节点的超时时间是不一样的,但接收到其他节点发过来的ping的时候,这个超时倒计时会重新开始计时)
对于主从文件的复制,和kafka有点区别就是kafka等其他replica返回同步的信息后就直接commit了,而raft算法还需要主动发给消息给从节点让他们也commit。
太厉害了!!
zab选主是怎么样的?
给自己投票,广播,比较服务器id,数据id,逻辑时钟,比较透给谁
比较数据,逻辑时钟。。
原则是投票超过半数的就获胜。最可靠最完全。
kafka选主是怎么样的?
kafka有一个controller负责选组(这个controller是zookeeper实现的,watch监控器,应该就是每一个broker去注册controller,策成功了就是controller,失败了就一直监听controller是否挂了,如果挂了就变成controller。这个又有点像zookeeper实现分布式事务锁了),同时在zookeeper中维护了ISR列表,controller去ISR列表中选择第一个,叫做偏爱分区法
重新选举,去ISR列表中找一个和leadre一样的节点。
redis的哨兵模式
其实也是选主,他首选要选一个哨兵leader,是发现故障的那个哨兵发起的投票,看看自己是否能够成为选举性leader的主导致。然后选举leader的原则是:slave of 优先级设置高的,数据偏移量最大的,runid(估计是服务器id_最小的)。
就变成controller。这个又有点像zookeeper实现分布式事务锁了),同时在zookeeper中维护了ISR列表,controller去ISR列表中选择第一个,叫做偏爱分区法
重新选举,去ISR列表中找一个和leadre一样的节点。
redis的哨兵模式
其实也是选主,他首选要选一个哨兵leader,是发现故障的那个哨兵发起的投票,看看自己是否能够成为选举性leader的主导致。然后选举leader的原则是:slave of 优先级设置高的,数据偏移量最大的,runid(估计是服务器id_最小的)。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。