热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

基础概念及问答(二)

1:请简要介绍一下你了解Mysql的

1: 请简要介绍一下你了解Mysql的哪些锁
不同的存储引擎,默认哪种锁
MyISAM和MEMORY采用表级锁(table-level locking)
BDB采用页面锁(page-level locking)或表级锁,默认为页面锁
InnoDB支持行级锁(row-level locking)和表级锁,默认为行级锁
大致分类:
按照按锁粒度分类-行级锁&表级锁&表级锁&页级锁
1 行级锁
(1) 描述
行级锁是mysql中锁定粒度最细的一种锁。表示只针对当前操作的行进行加锁。行级锁能大大减少数据库操作的冲突,其加锁粒度最小,但加锁的开销也最大。行级锁分为共享锁和排他锁
(2)特点
开销大,加锁慢,会出现死锁。发生锁冲突的概率最低,并发度也最高。
2 表级锁
(1) 描述
表级锁是mysql中锁定粒度最大的一种锁,表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大部分mysql引擎支持。最常使用的MyISAM与InnoDB都支持表级锁定。表级锁定分为表共享读锁(共享锁)与表独占写锁(排他锁)
(2)特点
开销小,加锁快,不会出现死锁。发生锁冲突的概率最高,并发度也最低。
3 页级锁
(1) 描述
页级锁是 MySQL 中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但冲突多,行级冲突少,但速度慢。因此,采取了折衷的页级锁,一次锁定相邻的一组记录。BDB 支持页级锁。
(2)特点
开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。
 锁级别分类 - 共享锁 & 排他锁 & 意向锁
1 共享锁(Share Lock)
共享锁又称读锁,是读取操作创建的锁。其他用户可以并发读取数据,但任何事务都不能对数据进行修改(获取数据上的排他锁),直到已释放所有共享锁。
如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁。获准共享锁的事务只能读数据,不能修改数据。
用法
SELECT … LOCK IN SHARE MODE;
在查询语句后面增加LOCK IN SHARE MODE,MySQL 就会对查询结果中的每行都加共享锁,当没有其他线程对查询结果集中的任何一行使用排他锁时,可以成功申请共享锁,否则会被阻塞。其他线程也可以读取使用了共享锁的表,而且这些线程读取的是同一个版本的数据。
2 排他锁(Exclusive Lock)
排他锁又称写锁、独占锁,如果事务T对数据A加上排他锁后,则其他事务不能再对A加任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据。
用法
SELECT … FOR UPDATE;
在查询语句后面增加FOR UPDATE,MySQL 就会对查询结果中的每行都加排他锁,当没有其他线程对查询结果集中的任何一行使用排他锁时,可以成功申请排他锁,否则会被阻塞。
3 意向锁(Intention Lock)
意向锁是表级锁,其设计目的主要是为了在一个事务中揭示下一行将要被请求锁的类型。InnoDB 中的两个表锁:
意向共享锁(IS):表示事务准备给数据行加入共享锁,也就是说一个数据行加共享锁前必须先取得该表的IS锁;
意向排他锁(IX):类似上面,表示事务准备给数据行加入排他锁,说明事务在一个数据行加排他锁前必须先取得该表的IX锁。
意向锁是 InnoDB 自动加的,不需要用户干预。
对于INSERT、UPDATE和DELETE,InnoDB 会自动给涉及的数据加排他锁;对于一般的SELECT语句,InnoDB 不会加任何锁,事务可以通过以下语句显式加共享锁或排他锁。
共享锁:SELECT … LOCK IN SHARE MODE;
排他锁:SELECT … FOR UPDATE;
1、表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最 
高,并发度最低。
2、行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最 
低,并发度也最高。
3、页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表 
锁和行锁之间,并发度一般。

2: Spring 、Spring Boot 和 Spring Cloud 的关系?
Spring 最初最核心的两大核心功能 Spring Ioc 和 Spring Aop 成就了 Spring,Spring 在这两大核心的功能上不断的发展,才有了 Spring 事务、Spring Mvc 等一系列伟大的产品,最终成就了 Spring 帝国,到了后期 Spring 几乎可以解决企业开发中的所有问题。microservice架构风格是一种将单个应用程序开发为一组小服务的方法,每个服务都在自己的进程中运行,并与轻量级机制(通常是HTTP资源API)进行通信。这些服务是围绕业务能力构建的,可以通过全自动部署机制独立部署。对这些服务的集中管理非常有限,这些服务可以用不同的编程语言编写,并使用不同的数据存储技术。
Spring Boot 是在强大的 Spring 帝国生态基础上面发展而来,发明 Spring Boot 不是为了取代 Spring ,是为了让人们更容易的使用 Spring 。
Spring Cloud 是一系列框架的有序集合。它利用 Spring Boot 的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用 Spring Boot 的开发风格做到一键启动和部署。
Spring Cloud 是为了解决微服务架构中服务治理而提供的一系列功能的开发框架,并且 Spring Cloud 是完全基于 Spring Boot 而开发,Spring Cloud 利用 Spring Boot 特性整合了开源行业中优秀的组件,整体对外提供了一套在微服务架构中服务治理的解决方案

3: 消息队列有什么优缺点;RabbitMQ有什么优缺点
优点:解耦、异步、削峰。
缺点
系统可用性降低
本来系统运行好好的,现在你非要加入个消息队列进去,那消息队列挂了,你的 系统不是呵呵了。因此,系统可用性会降低;
系统复杂度提高
加入了消息队列,要多考虑很多方面的问题,比如:一致性问题、如何保证消息 不被重复消费、如何保证消息可靠性传输等。因此,需要考虑的东西更多,复杂 性增大。
一致性问题
A 系统处理完了直接返回成功了,人都以为你这个请求就成功了;但是问题是, 要是 BCD 三个系统那里,BD 两个系统写库成功了,结果 C 系统写库失败了, 咋整?你这数据就不一致了。
所以消息队列实际是一种非常复杂的架构,你引入它有很多好处,但是也得针对 它带来的坏处做各种额外的技术方案和架构来规避掉,做好之后,你会发现,妈 呀,系统复杂度提升了一个数量级,也许是复杂了 10 倍。但是关键时刻,用, 还是得用的。

4: Spring容器启动过程有哪些步骤
  • 初始化一个Reader和Scanner,Reader可以用来注册单个BeanDefinition,Scanner用来扫描得到BeanDefinition,
  • 通过Reader把配置类注册为一个BeanDefinition
  • 调用refresh方法,开始启动Spring容器
  • 先获取一个Bean工厂
  • 预先往Bean工厂中添加一些Bean后置处理器,和一些单例bean,和一些其他的配置
  • 执行Bean工厂的后置处理器,这里会进行扫描,扫描bean和bean的后置处理器
  • 实例化bean的后置处理器并且排序,然后添加到Bean工厂中去
  • 初始化用来进行国际化的MessageSource
  • 初始化事件广播器
  • 注册事件监听器
  • 开始实例化非懒加载的单例bean
  • 发布ContextRefreshedEvent事件

    5: Ribbon的负载均衡原理

  • Ribbon是Spring Cloud家族的开源项目,主要功能是提供客户端的软件负载均衡算法,实现服务高可用。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法,将请求平摊的分配到多个服务上,从而达到系统的HA。
  • 需要注意的是:Ribbon并非直接通过DiscoveryClient从注册中心获取服务的可用提供者,而是通过ServerList从注册中心获取服务提供者,ServerList与DiscoveryClient不一样,ServerList不是Spring Cloud定义的接口,而是Ribbon定义的接口。
  • Ribbon自身的负载均衡算法
  • RoundRobinRule(轮询算法)
  • RandomRule(随机算法)
  • AvailabilityFilteringRule():会先过滤由于多次访问故障而处于断路器跳闸状态的服务,还有并发的连接数量超过阈值的服务,然后对剩余的服务列表按照轮询策略进行访问
  • WeightedResponseTimeRule():根据平均响应的时间计算所有服务的权重,响应时间越快服务权重越大被选中的概率越高,刚启动时如果统计信息不足,则使用RoundRobinRule策略,等统计信息足够会切换到WeightedResponseTimeRule
  • RetryRule():先按照RoundRobinRule的策略获取服务,如果获取失败则在制定时间内进行重试,获取可用的服务。
  • BestAviableRule():会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务
  • ZoneAvoidanceRule():默认规则,符合判断server所在区域的性能和server的可用性选择服务器
  • 自定义负载均衡算法需要爱继承AbstractLoadBalanceRule类进行自定义算法实现。
    6: 为什么使用MQ;MQ的优点
  • 异步处理 - 相比于传统的串行、并行方式,提高了系统吞吐量。
  • 应用解耦 - 系统间通过消息通信,不用关心其他系统的处理。
  • 流量削锋 - 可以通过消息队列长度控制请求量;可以缓解短时间内的高并发请 求。
  • 日志处理 - 解决大量日志传输。
  • 消息通讯 - 消息队列一般都内置了高效的通信机制,因此也可以用在纯的消息通 讯。比如实现点对点消息队列,或者聊天室等。
  • 详答
  • 主要是:解耦、异步、削峰。
  • 解耦:A 系统发送数据到 BCD 三个系统,通过接口调用发送。如果 E 系统也要 这个数据呢?那如果 C 系统现在不需要了呢?A 系统负责人几乎崩溃…A 系统 跟其它各种乱七八糟的系统严重耦合,A 系统产生一条比较关键的数据,很多系 统都需要 A 系统将这个数据发送过来。如果使用 MQ,A 系统产生一条数据, 发送到 MQ 里面去,哪个系统需要数据自己去 MQ 里面消费。如果新系统需要 数据,直接从 MQ 里消费即可;如果某个系统不需要这条数据了,就取消对 MQ 消息的消费即可。这样下来,A 系统压根儿不需要去考虑要给谁发送数 据,不需要维护这个代码,也不需要考虑人家是否调用成功、失败超时等情况。就是一个系统或者一个模块,调用了多个系统或者模块,互相之间的调用很复 杂,维护起来很麻烦。但是其实这个调用是不需要直接同步调用接口的,如果用 MQ 给它异步化解耦。
  • 异步:A 系统接收一个请求,需要在自己本地写库,还需要在 BCD 三个系统写 库,自己本地写库要 3ms,BCD 三个系统分别写库要 300ms、450ms、 200ms。最终请求总延时是 3 + 300 + 450 + 200 = 953ms,接近 1s,用户 感觉搞个什么东西,慢死了慢死了。用户通过浏览器发起请求。如果使用 MQ,那么 A 系统连续发送 3 条消息到 MQ 队列中,假如耗时 5ms,A 系统从 接受一个请求到返回响应给用户,总时长是 3 + 5 = 8ms。
  • 削峰:减少高峰时期对服务器压力。

    7: B树定义
    B树和平衡二叉树稍有不同的是B树属于多叉树又名平衡多路查找树(查找路径 不只两个),不属于二叉搜索树的范畴,因为它不止两路,存在多路。
    B树满足的条件:
  • 树种的每个节点多拥有m个子节点且m>=2,空树除外(注:m阶代表一个树节 点多有多少个查找路径,m阶=m路,当m=2则是2叉树,m=3则是3叉);
  • 除根节点外每个节点的关键字数量大于等于ceil(m/2)-1个小于等于m-1个,非根 节点关键字数必须>=2;(注:ceil()是个朝正无穷方向取整的函数 如ceil(1.1)结果为2)
  • 所有叶子节点均在同一层、叶子节点除了包含了关键字和关键字记录的指针外也 有指向其子节点的指针只不过其指针地址都为null对应下图后一层节点的空格子
  • 如果一个非叶节点有N个子节点,则该节点的关键字数等于N-1;
  • 所有节点关键字是按递增次序排列,并遵循左小右大原则;


  • B树的应用场景:构造一个多阶的B类树,然后在尽量多的在结点上存储相关的信息, 保证层数尽量的少,以便后面我们可以更快的找到信息,磁盘的I/O操作也少一些,而 且B类树是平衡树,每个结点到叶子结点的高度都是相同,这也保证了每个查询是稳定 的。
    8: Mybatis都有哪些Executor执行器?它们之间的区别是什么
  • Mybatis有三种基本的Executor执行器,SimpleExecutor、ReuseExecutor、 BatchExecutor。
  • ReuseExecutor:执行update或select,以sql作为key查找Statement对象,存在就使 用,不存在就创建,用完后,不关闭Statement对象,而是放置于Map内,供下一次使用。简言之,就是重复使用Statement对象。
  • BatchExecutor:执行update(没有select,JDBC批处理不支持select),将所有sql都添 加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个 Statement对象,每个Statement对象都是addBatch()完毕后,等待逐一执行 executeBatch()批处理。与JDBC批处理相同。
  • 作用范围:Executor的这些特点,都严格限制在SqlSession生命周期范围内。
    9: 什么是 java 序列化?什么情况下需要序列化
    简单说就是为了保存在内存中的各种对象的状态(也就是实例变量,不是方法),并且可以把保存的对象状态再读出来。虽然你可以用你自己的各种各样的方法来保存object states,但是Java给你提供一种应该比你自己好的保存对象状态的机制,那就是序列化。
    什么情况下需要序列化:
    a)当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;
    b)当你想用套接字在网络上传送对象的时候;
    c)当你想通过RMI传输对象的时候;
    10: Spring Boot 中如何实现定时任务
  • 定时任务也是一个常见的需求,Spring Boot 中对于定时任务的支持主要还是来自 Spring 框架。
  • 在 Spring Boot 中使用定时任务主要有两种不同的方式,一个就是使用 Spring 中的 @Scheduled 注解,另一个则是使用第三方框架 Quartz。
  • 使用 Spring 中的 @Scheduled 的方式主要通过 @Scheduled 注解来实现。
  • 使用 Quartz ,则按照 Quartz 的方式,定义 Job 和 Trigger 即可。
    11: JDK7中的ConcurrentHashMap是如何扩容的
    JDK7中的ConcurrentHashMap和JDK7的HashMap的扩容是不太一样的,首先JDK7中也是支持多线程扩容的,原因是,JDK7中的ConcurrentHashMap分段了,每一段叫做Segment对象,每个Segment对象相当于一个HashMap,分段之后,对于ConcurrentHashMap而言,能同时支持多个线程进行操作,前提是这些操作的是不同的Segment,而ConcurrentHashMap中的扩容是仅限于本Segment,也就是对应的小型HashMap进行扩容,所以是可以多线程扩容的。
    每个Segment内部的扩容逻辑和HashMap中一样。
    12: Spring Boot 有哪些优点
    Spring Boot 主要有如下优点:
  • 容易上手,提升开发效率,为 Spring 开发提供一个更快、更广泛的入门体验。
  • 开箱即用,远离繁琐的配置。
  • 提供了一系列大型项目通用的非业务性功能,例如:内嵌服务器、安全管理、运行数据监控、运行状况检查和外部化配置等。
  • 没有代码生成,也不需要XML配置。
  • 避免大量的 Maven 导入和各种版本冲突。

  • 13: MyBatis编程步骤是什么样的
  • 创建SqlSessionFactory
  • 通过SqlSessionFactory创建SqlSession
  • 通过sqlsession执行数据库操作
  • 调用session.commit()提交事务
  • 调用session.close()关闭会话

  • 14: 我们如何监视所有 Spring Boot 微服务
  • Spring Boot 提供监视器端点以监控各个微服务的度量。这些端点对于获取有关应用程序的信息(如它们是否已启动)以及它们的组件(如数据库等)是否正常运行很有帮助。但是,使用监视器的一个主要缺点或困难是,我们必须单独打开应用程序的知识点以了解其状态或健康状况。想象一下涉及 50 个应用程序的微服务,管理员将不得不击中所有 50 个应用程序的执行终端。为了帮助我们处理这种情况,我们将使用位于的开源项目。它建立在 Spring Boot Actuator 之上,它提供了一个 Web UI,使我们能够可视化多个应用程序的度量。

  • 15: 如何处理缓存数据不一致和并发竞争
  • 数据不一致
    问题描述:
  • 同一份数据,可能会同时存在 DB 和缓存之中。那就有可能发生,DB 和缓存的数据不一致。如果缓存有多个副本,多个缓存副本里的数据也可能会发生不一致现象。
    业务场景:
  • 在缓存机器的带宽被打满,或者机房网络出现波动时,缓存更新失败,新数据没有写入缓存,就会导致缓存和 DB 的数据不一致。缓存 rehash 时,某个缓存机器反复异常,多次上下线,更新请求多次 rehash。这样,一份数据存在多个节点,且每次 rehash 只更新某个节点,导致一些缓存节点产生脏数据。
    解决方案:
  • 1.cache 更新失败后,可以进行重试,如果重试失败,则将失败的 key 写入队列机服务,待缓存访问恢复后,将这些 key 从缓存删除。这些 key 在再次被查询时,重新从 DB 加载,从而保证数据的一致性。
  • 2.缓存时间适当调短,让缓存数据及早过期后,然后从 DB 重新加载,确保数据的最终一致性。
  • 3.不采用 rehash 策略,而采用缓存分层策略,尽量避免脏数据产生。

    数据并发竞争

    问题描述:
  • 数据并发竞争,是指在高并发访问场景,一旦缓存访问没有找到数据,大量请求就会并发查询 DB,导致 DB 压力大增的现象。
    业务场景:
    购票系统,如果某个火车车次缓存信息过期,但仍然有大量用户在查询该车次信息。微博系统中,如果某条微博正好被缓存淘汰,但这条微博仍然有大量的转发、评论、赞。
    解决方案:
    1.使用全局锁。当缓存请求 miss 后,先尝试加全局锁,只有加全局锁成功的线程,才可以到 DB 去加载数据。其他进程/线程在读取缓存数据 miss 时,如果发现这个 key 有全局锁,就进行等待,待之前的线程将数据从 DB 回种到缓存后,再从缓存获取。
    2.对缓存数据保持多个备份,即便其中一个备份中的数据过期或被剔除了,还可以访问其他备份,从而减少数据并发竞争的情况。

    16: 微服务优缺点
    优点:
  • 1.每个微服务都很小,这样能聚焦一个指定的业务功能或业务需求。
  • 2.微服务能够被小团队单独开发。
  • 3.微服务是松耦合的,是有功能意义的服务,无论是在开发阶段或部署阶段都是独立的。
  • 4.微服务能使用不同的语言开发。
  • 5.微服务易于被一个开发人员理解,修改和维护,这样小团队能够更关注自己的工作成果。无需通过合作才能体现价值。
  • 6.微服务只是业务逻辑的代码,不会和HTML,CSS 或其他界面组件混合。
    缺点
  • 1.运维要求较高
  • 2.分布式的复杂性
  • 3.接口调整成本高
    17: 如何处理缓存失效、缓存穿透与缓存雪崩

    缓存失效

  • 问题描述:
    业务访问时,如果大量的 key 同时过期,很多缓存数据访问都会 miss,进而穿透到 DB,DB 的压力就会明显上升,由于 DB 的性能较差,只在缓存的 1%~2% 以下,这样请求的慢查率会明显上升。
  • 业务场景:
    同一批火车票售卖时,系统会一次性加载到缓存,如果缓存写入时,过期时间按照预先设置的过期值,那过期时间到期后,系统就会因缓存失效出现变慢的问题。新业务上线时,会进行缓存预热,也会一次性加载大批热数据。
  • 解决方案:
    设计缓存的过期时间时,使用公式:过期时间=base 时间+随机时间,让数据在未来一段时间内慢慢过期,避免瞬时全部过期,对 DB 造成过大压力

    缓存穿透

  • 问题描述:
    有特殊访客在查询一个不存在的 key,导致每次查询都会穿透到 DB,如果这个特殊访客再控制一批肉机,持续访问系统里不存在的 key,就会对 DB 产生很大的压力,从而影响正常服务。
  • 业务场景:
    通过不存在的 UID 访问用户,通过不存在的车次 ID 查看购票信息 
    解决方案:
    1.查询这些不存在的数据时,第一次查 DB,虽然没查到结果返回 NULL,仍然记录这个 key 到缓存,只是这个 key 对应的 value 是一个特殊设置的值。                                                   改进:设置很短的过期时间,将这些不存在的 key 存在一个独立的公共缓存。
    2.构建一个 BloomFilter 缓存过滤器,记录全量数据,这样访问数据时,可以直接通过 BloomFilter 判断这个 key 是否存在,如果不存在直接返回即可,根本无需查缓存和 DB。

    缓存雪崩

  • 问题描述:
    缓存雪崩是指部分缓存节点不可用,导致整个缓存体系甚至甚至服务系统不可用的情况。
  • 按照缓存是否 rehash分两种情况:
    缓存不支持 rehash 导致的系统雪崩不可用
    缓存支持 rehash 导致的缓存雪崩不可用
  • 业务场景:
    微博、Twitter 在突发流量洪峰时crash。机架断电,导致业务缓存多个节点宕机,大量请求直接打到 DB,也导致 DB 过载而阻塞,整个系统异常。
  • 解决方案:
    1.对业务 DB 的访问增加读写开关,当发现 DB 请求变慢、阻塞,慢请求超过阀值时,就会关闭读开关,部分或所有读 DB 的请求进行 failfast 立即返回,待 DB 恢复后再打开读开关。(优先保证写,同时支持部分读)
    2.对缓存增加多个副本,缓存异常或请求 miss 后,再读取其他缓存副本,而且多个缓存副本尽量部署在不同机架,从而确保在任何情况下,缓存系统都会正常对外提供服务。
    3.对缓存体系进行实时监控,当请求访问的慢速比超过阀值时,及时报警,通过机器替换、服务替换进行及时恢复;也可以通过各种自动故障转移策略,自动关闭异常接口、停止边缘服务、停止部分非核心功能措施,确保在极端场景下,核心功能的正常运行。
    18: 如何使用 Spring Boot 实现分页和排序
    使用 Spring Boot 实现分页非常简单。使用 Spring Data-JPA 可以实现将可分页的传递给存储库方法。
  • 微服务中如何实现 session 共享 ?
    在微服务中,一个完整的项目被拆分成多个不相同的独立的服务,各个服务独立部署在不同的服务器上,各自的 session 被从物理空间上隔离开了,但是经常,我们需要在不同微服务之间共享 session ,常见的方案就是 SpringSession + Redis 来实现 session 共享。将所有微服务的 session 统一保存在 Redis 上,当各个微服务对 session 有相关的读写操作时,都去操作 Redis 上的 session 。这样就实现了 session 共享,Spring Session 基于 Spring 中的代理过滤器实现,使得 session 的同步操作对开发人员而言是透明的,非常简便。
    19: 二叉搜索树
  • 二叉搜索树也是一种树,适用与一般二叉树的全部操作,但二叉搜索树能够实现 数据的快速查找。
  • 二叉搜索树满足的条件:
  • 非空左子树的所有键值小于其根节点的键值
  • 非空右子树的所有键值大于其根节点的键值
  • 左右子树都是二叉搜索树
  • 二叉搜索树的应用场景:如果是没有退化称为链表的二叉树,查找效率就是 lgn,效率不错,但是一旦退换称为链表了,要么使用平衡二叉树,或者之后的 RB树,因为链表就是线性的查找效率。
    20: Hystrix断路器的实现原理
    Hystix是Spring Cloud家族产品组件之一,主要用来熔断降级以及资源隔离来保护系统免受级联故障影响。
  • Hystrix设计目标
  1. 对来自依赖的延迟和故障进行防护和控制——这些依赖通常都是通过网络访问的
  2. 阻止故障的连锁反应
  3. 快速失败并迅速恢复
  4. 回退并优雅降级
  5. 提供近实时的监控与告警
  • Hystrix遵循的设计原则
  1. 防止任何单独的依赖耗尽资源(线程)
  2. 过载立即切断并快速失败,防止排队
  3. 尽可能提供回退以保护用户免受故障
  4. 使用隔离技术(例如隔板,泳道和断路器模式)来限制任何一个依赖的影响
  5. 通过近实时的指标,监控和告警,确保故障被及时发现
  6. 通过动态修改配置属性,确保故障及时恢复
  7. 防止整个依赖客户端执行失败,而不仅仅是网络通信
  • Hystrix如何实现这些设计目标?
  1. 使用命令模式将所有对外部服务(或依赖关系)的调用包装在HystrixCommand或HystrixObservableCommand对象中,并将该对象放在单独的线程中执行;
  2. 每个依赖都维护着一个线程池(或信号量),线程池被耗尽则拒绝请求(而不是让请求排队)。
  3. 记录请求成功,失败,超时和线程拒绝。
  4. 服务错误百分比超过了阈值,熔断器开关自动打开,一段时间内停止对该服务的所有请求。
  5. 请求失败,被拒绝,超时或熔断时执行降级逻辑。
  6. 近实时地监控指标和配置的修改。
Hystrix工作流程
orHysutrdtservablecommand
constrwctaHystrtacommand
crcubreates
Legend:
retumpth
SCCOSSTD
observable:
lensemmed
compLton
YE:CLaNck
Hystrtx[obscrwablejCommandmethod
Nox+eturnresultingobservat
1、创建HystrixCommand 或者 HystrixObservableCommand 对象
2、执行命令execute()、queue()、observe()、toObservable()
3、如果请求结果缓存这个特性被启用,并且缓存命中,则缓存的回应会立即通过一个Observable对象的形式返回
4、检查熔断器状态,确定请求线路是否是开路,如果请求线路是开路,Hystrix将不会执行这个命令,而是直接执行getFallback
5、如果和当前需要执行的命令相关联的线程池和请求队列,Hystrix将不会执行这个命令,而是直接执行getFallback
6、执行HystrixCommand.run()或HystrixObservableCommand.construct(),如果这两个方法执行超时或者执行失败,则执行getFallback()
7、Hystrix 会将请求成功,失败,被拒绝或超时信息报告给熔断器,熔断器维护一些用于统计数据用的计数器。
这些计数器产生的统计数据使得熔断器在特定的时刻,能短路某个依赖服务的后续请求,直到恢复期结束,若恢复期结束根据统计数据熔断器判定线路仍然未恢复健康,熔断器会再次关闭线路。
Hystrix断路器工作原理:
断路器开启或者关闭的条件:
     1、 当满足一定的阀值时候 (默认 10 秒内 超过 20 个请求 次数 )
     2、 当失败率达到一定的时候( 默认 10 秒内超过 秒内超过 50%的请求失败 )
     3、 到达以上阀值 ,断路器将会开启
     4、 当开启的时候 ,所有请求 都不会进行转发
     5、 一段时间之后( 默认是 5秒),这个时候断路器是半开状态, 会让其中一请求进行转发。如果成功断路器会关闭,若失败继续开启。重复 4和 5。
Hystrix特性
  • 请求熔断:当Hystrix Command请求后端服务失败数量超过一定比例(默认50%), 断路器会切换到开路状态(Open). 这时所有请求会直接失败而不会发送到后端服务. 断路器保持在开路状态一段时间后(默认5秒), 自动切换到半开路状态(HALF-OPEN).这时会判断下一次请求的返回情况, 如果请求成功, 断路器切回闭路状态(CLOSED), 否则重新切换到开路状态(OPEN). Hystrix的断路器就像我们家庭电路中的保险丝, 一旦后端服务不可用, 断路器会直接切断请求链, 避免发送大量无效请求影响系统吞吐量, 并且断路器有自我检测并恢复的能力.
  • 服务降级:Fallback相当于是降级操作. 对于查询操作, 我们可以实现一个fallback方法, 当请求后端服务出现异常的时候, 可以使用fallback方法返回的值. fallback方法的返回值一般是设置的默认值或者来自缓存.告知后面的请求服务不可用了,不要再来了。
  • 依赖隔离(采用舱壁模式,Docker就是舱壁模式的一种):在Hystrix中, 主要通过线程池来实现资源隔离. 通常在使用的时候我们会根据调用的远程服务划分出多个线程池.比如说,一个服务调用两外两个服务,你如果调用两个服务都用一个线程池,那么如果一个服务卡在哪里,资源没被释放后面的请求又来了,导致后面的请求都卡在哪里等待,导致你依赖的A服务把你卡在哪里,耗尽了资源,也导致了你另外一个B服务也不可用了。这时如果依赖隔离,某一个服务调用A B两个服务,如果这时我有100个线程可用,我给A服务分配50个,给B服务分配50个,这样就算A服务挂了,我的B服务依然可以用。
  • 请求缓存:比如一个请求过来请求我userId=1的数据,你后面的请求也过来请求同样的数据,这时我不会继续走原来的那条请求链路了,而是把第一次请求缓存过了,把第一次的请求结果返回给后面的请求。
  • 请求合并:我依赖于某一个服务,我要调用N次,比如说查数据库的时候,我发了N条请求发了N条SQL然后拿到一堆结果,这时候我们可以把多个请求合并成一个请求,发送一个查询多条数据的SQL的请求,这样我们只需查询一次数据库,提升了效率。
Hystix解决了什么问题?
复杂分布式体系结构中的应用程序通常有几十个依赖项,每个依赖项都不可避免地在某个时刻失败。如果主机应用程序没有与这些外部故障隔离开来,那么出现风险就有可能让整个集群服务崩溃。
例如,对于一个依赖于30个服务的应用程序,其中每个服务的正常运行时间为99.99%,您可以期望:
99.9930=99.7%正常运行时间
10亿个请求中的0.3%=3000000个失败
即使所有依赖项都有很好的正常运行时间,每月停机2小时以上。
现实通常比这个情况更糟。
即使所有的依赖性都表现良好,如果您不设计整个系统的弹性,那么即使是0.01%的停机时间对几十个服务中的每一个服务的总影响也相当于一个月可能有几个小时的停机时间
熔断器有以下几个主要配置
 




推荐阅读
  • ZeroMQ在云计算环境下的高效消息传递库第四章学习心得
    本章节深入探讨了ZeroMQ在云计算环境中的高效消息传递机制,涵盖客户端请求-响应模式、最近最少使用(LRU)队列、心跳检测、面向服务的队列、基于磁盘的离线队列以及主从备份服务等关键技术。此外,还介绍了无中间件的请求-响应架构,强调了这些技术在提升系统性能和可靠性方面的应用价值。个人理解方面,ZeroMQ通过这些机制有效解决了分布式系统中常见的通信延迟和数据一致性问题。 ... [详细]
  • 2019年后蚂蚁集团与拼多多面试经验详述与深度剖析
    2019年后蚂蚁集团与拼多多面试经验详述与深度剖析 ... [详细]
  • Node.js 教程第五讲:深入解析 EventEmitter(事件监听与发射机制)
    本文将深入探讨 Node.js 中的 EventEmitter 模块,详细介绍其在事件监听与发射机制中的应用。内容涵盖事件驱动的基本概念、如何在 Node.js 中注册和触发自定义事件,以及 EventEmitter 的核心 API 和使用方法。通过本教程,读者将能够全面理解并熟练运用 EventEmitter 进行高效的事件处理。 ... [详细]
  • 作为140字符的开创者,Twitter看似简单却异常复杂。其简洁之处在于仅用140个字符就能实现信息的高效传播,甚至在多次全球性事件中超越传统媒体的速度。然而,为了支持2亿用户的高效使用,其背后的技术架构和系统设计则极为复杂,涉及高并发处理、数据存储和实时传输等多个技术挑战。 ... [详细]
  • Ceph API微服务实现RBD块设备的高效创建与安全删除
    本文旨在实现Ceph块存储中RBD块设备的高效创建与安全删除功能。开发环境为CentOS 7,使用 IntelliJ IDEA 进行开发。首先介绍了 librbd 的基本概念及其在 Ceph 中的作用,随后详细描述了项目 Gradle 配置的优化过程,确保了开发环境的稳定性和兼容性。通过这一系列步骤,我们成功实现了 RBD 块设备的快速创建与安全删除,提升了系统的整体性能和可靠性。 ... [详细]
  • 本文深入探讨了IO复用技术的原理与实现,重点分析了其在解决C10K问题中的关键作用。IO复用技术允许单个进程同时管理多个IO对象,如文件、套接字和管道等,通过系统调用如`select`、`poll`和`epoll`,高效地处理大量并发连接。文章详细介绍了这些技术的工作机制,并结合实际案例,展示了它们在高并发场景下的应用效果。 ... [详细]
  • 在操作系统中,阻塞状态与挂起状态有着显著的区别。阻塞状态通常是指进程因等待某一事件(如I/O操作完成)而暂时停止执行,而挂起状态则是指进程被系统暂时移出内存,以释放资源或降低系统负载。此外,本文还深入分析了`sleep()`函数的实现机制,探讨了其在不同操作系统中的具体实现方式及其对进程调度的影响。通过这些分析,读者可以更好地理解操作系统如何管理进程的不同状态以及`sleep()`函数在其中的作用。 ... [详细]
  • SQL Server开发技巧:修改表结构后的视图批量更新方法与实践 ... [详细]
  • 本文探讨了如何在C#中实现USB条形码扫描仪的数据读取,并自动过滤掉键盘输入,即使不知道设备的供应商ID(VID)和产品ID(PID)。通过详细的技术指导和代码示例,展示了如何高效地处理条形码数据,确保系统能够准确识别并忽略来自键盘的干扰信号。该方法适用于多种USB条形码扫描仪,无需额外配置设备信息。 ... [详细]
  • 在Ubuntu系统中,由于预装了MySQL,因此无需额外安装。通过命令行登录MySQL时,可使用 `mysql -u root -p` 命令,并按提示输入密码。常见问题包括:1. 错误 1045 (28000):访问被拒绝,这通常是由于用户名或密码错误导致。为确保顺利连接,建议检查MySQL服务是否已启动,并确认用户名和密码的正确性。此外,还可以通过配置文件调整权限设置,以增强安全性。 ... [详细]
  • Spring框架入门指南:专为新手打造的详细学习笔记
    Spring框架是Java Web开发中广泛应用的轻量级应用框架,以其卓越的功能和出色的性能赢得了广大开发者的青睐。本文为初学者提供了详尽的学习指南,涵盖基础概念、核心组件及实际应用案例,帮助新手快速掌握Spring框架的核心技术与实践技巧。 ... [详细]
  • 本文详细介绍了如何在Linux系统中搭建51单片机的开发与编程环境,重点讲解了使用Makefile进行项目管理的方法。首先,文章指导读者安装SDCC(Small Device C Compiler),这是一个专为小型设备设计的C语言编译器,适合用于51单片机的开发。随后,通过具体的实例演示了如何配置Makefile文件,以实现代码的自动化编译与链接过程,从而提高开发效率。此外,还提供了常见问题的解决方案及优化建议,帮助开发者快速上手并解决实际开发中可能遇到的技术难题。 ... [详细]
  • 技术日志:深入探讨Spark Streaming与Spark SQL的融合应用
    技术日志:深入探讨Spark Streaming与Spark SQL的融合应用 ... [详细]
  • 在 Linux 系统中,`/proc` 目录实现了一种特殊的文件系统,称为 proc 文件系统。与传统的文件系统不同,proc 文件系统主要用于提供内核和进程信息的动态视图,通过文件和目录的形式呈现。这些信息包括系统状态、进程细节以及各种内核参数,为系统管理员和开发者提供了强大的诊断和调试工具。此外,proc 文件系统还支持实时读取和修改某些内核参数,增强了系统的灵活性和可配置性。 ... [详细]
  • Java队列机制深度解析与应用指南
    Java队列机制在并发编程中扮演着重要角色。本文深入解析了Java队列的各种实现类及其应用场景,包括`LinkedList`、`ArrayBlockingQueue`和`PriorityQueue`等,并探讨了它们在高并发环境下的性能表现和适用场景。通过详细分析这些队列的内部机制和使用技巧,帮助开发者更好地理解和应用Java队列,提升系统的设计和架构能力。 ... [详细]
author-avatar
只爱裙装
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有