SpringCloud基础重难点
spring cloud 介绍
spring cloud 是⼀系列框架的集合。它利⽤ spring boot 的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中⼼、消息总线、负载均衡、断路器、数据监控等,都可以⽤ spring boot 的开发风格做到⼀键启动和部署。spring cloud 并没有重复制造轮⼦,它只是将⽬前各家公司开发的⽐较成熟、经得起实际考验的服务框架组合起来,通过 spring boot 风格进⾏再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了⼀套简单易懂、易部署和易维护的分布式系统开发⼯具包。
spring cloud 对于中⼩型互联⽹公司来说是⼀种福⾳,因为这类公司往往没有实⼒或者没有⾜够的资⾦投⼊去开发⾃⼰的分布式系统基础设施,使⽤spring cloud ⼀站式解决⽅案能在从容应对业务发展的同时⼤⼤减少开发成本。同时,随着近⼏年微服务架构和 docker 容器概念的⽕爆,也会让spring cloud 在未来越来越“云”化的软件开发风格中⽴有⼀席之地,尤其是在⽬前五花⼋门的分布式解决⽅案中提供了标准化的、⼀站式的技术⽅案,意义可能会堪⽐当年 servlet 规范的诞⽣,有效推进服务端软件系统技术⽔平的进步。
spring cloud 技术组成
eureka:微服务治理,服务注册和发现
ribbon:负载均衡、请求重试
hystrix:断路器,服务降级、熔断
feign:ribbon + hystrix 集成,并提供⽣命式客户端
hystrix dashboard 和 turbine:hystrix 微服务监控
zuul:API ⽹关,提供微服务的统⼀⼊⼝,并提供统⼀的权限验证
config:配置中⼼
bus:配置更新消息总线
sleuth:链路追踪
2.1 eureka注册中⼼
与zookeeper 类似,维护⼀组微服务的地址信息
Zookeeper:某⼀个微服务不可⽤,会⽴即删除该服务的注册信息
eureka:某⼀个微服务不可⽤,会保护该服务的注册信息,不删除
eureka的设计值认为,服务不可⽤可能不是服务本⾝的问题,只是由于微服务和注册中⼼之间的⽹络问题,⽽与其他微服务之间可能仍然可以连接
netflix公司开发的⼀套微服务框架,并开源,spring cloud集成了netflix 的微服务框架:
eureka
ribbon
hystrix
feign
zuul
客户端每30秒向eureka服务器发送信条数据
如果⼀个客户端90秒内没有发送⼼跳数据,认为该服务不可⽤
客户端每隔30秒,从eureka拉取新的注册信息
2.2 ribbon
作⽤: 负载均衡和重试
封装 RestTemplate,⽣成动态代理,来添加负载均衡和重试的代码
单独使⽤ribbon,开启重试需要⾃⼰写代码,添加重试参数配置
后⾯ ribbon 被feign 和 zuul 封装,不做任何配置,不写任何代码,可以直接使⽤负载均衡和重试
2.3 hystrix
断路器,降级和熔断
降级:
当服务不可⽤,或者访问超时,可以执⾏降级代码,可以返回错误信息,或者返回缓存数据
熔断:
10秒内请求数量达到20个,并且,有50% 出现失败降级的情况,会打开断路器,所有的请求,都直接降级,不再向后台微服务转发
断路器打开5秒后,会处于半开状态,当请求到达时,会尝试向后台符转发,如果成功,会关闭断路器,如果仍然失败,保持打开状态
2.4 feign
声明式客户端、整合 ribbon 和 hystrix
feign整合ribbon
不需要任何配置,已经启⽤ribbon的负载均衡和重试
feign整合 hystrix
启⽤ hystrix
abled=true
添加 hystrix 依赖
暴露 hystrix.stream 监控端点
2.5 zuul
作⽤:api⽹关,路由,负载均衡等多种作⽤
简介:类似nginx,反向代理的功能,不过netflix⾃⼰增加了⼀些配合其他组件的特性。
在微服务架构中,后端服务往往不直接开放给调⽤端,⽽是通过⼀个API⽹关根据请求的url,路由到相应的服务。当添加API⽹关后,在第三⽅调⽤端和服务提供⽅之间就创建了⼀⾯墙,这⾯墙直接与调⽤⽅通信进⾏权限控制,后将请求均衡分发给后台服务端。
过滤器权限过滤:继承 ZuulFilter
降级:实现 FallbackProvider
2.5 config
springcloud难学吗作⽤:配置管理
简介:SpringCloud Config提供服务器端和客户端。服务器存储后端的默认实现使⽤git,因此它轻松⽀持标签版本的配置环境,以及可以访问⽤于管理内容的各种⼯具。
3、常见⾯试题
问题⼀:什么是Spring Cloud?
Spring cloud流应⽤程序启动器是基于Spring Boot的Spring集成应⽤程序,提供与外部系统的集成。Spring cloud Task,⼀个⽣命周期短暂的微服务框架,⽤于快速构建执⾏有限数据处理的应⽤程序。
问题⼆:使⽤Spring Cloud有什么优势?
使⽤Spring Boot开发分布式微服务时,我们⾯临以下问题
1、与分布式系统相关的复杂性-这种开销包括⽹络问题,延迟开销,带宽问题,安全问题。
2、服务发现-服务发现⼯具管理集中的流程和服务如何查和互相交谈。它涉及⼀个服务⽬录,在该⽬录中注册服务,然后能够查并连接到该⽬录中的服务。
3、冗余-分布式系统中的冗余问题。
4、负载平衡 --负载平衡改善跨多个计算资源的⼯作负荷,诸如计算机,计算机
5、集,⽹络链路,中央处理单元,或磁盘驱动器的分布。
6、性能-问题由于各种运营开销导致的性能问题。
7、部署复杂性-Devops技能的要求。
优点:
1.Spring Cloud 来源于 Spring,质量、稳定性、持续性都可以得到保证。
2.Spirng Cloud 天然⽀持 Spring Boot,更加便于业务落地。
3.Spring Cloud 发展⾮常的快,从 2016 年开始接触的时候相关组件版本为 1.x,到现在将要发布 2.x 系列。
4.Spring Cloud 是 Java 领域最适合做微服务的框架。
5.相⽐于其它框架,Spring Cloud 对微服务周边环境的⽀持⼒度最⼤。
6.对于中⼩企业来讲,使⽤门槛较低。
7.Spring Cloud 是微服务架构的最佳落地⽅案
问题三:服务注册和发现是什么意思?Spring Cloud如何实现?
当我们开始⼀个项⽬时,我们通常在属性⽂件中进⾏所有的配置。随着越来越多的服务开发和部署,添加和修改这些属性变得更加复杂。有些服务可能会下降,⽽某些位置可能会发⽣变化。⼿动更改属性可能会产⽣问题。 Eureka服务注册和发现可以在这种情况下提供帮助。由于所有服务都在Eureka 服务器上注册并通过调⽤Eureka服务器完成查,因此⽆需处理服务地点的任何更改和处理。
问题四:负载均衡的意义什么?
在计算中,负载平衡可以改善跨计算机,计算机集,⽹络链接,中央处理单元或磁盘驱动器等多种计算资源的⼯作负载分布。负载平衡旨在优化资源使⽤,最⼤化吞吐量,最⼩化响应时间并避免任何单⼀资源的过载。使⽤多个组件进⾏负载平衡⽽不是单个组件可能会通过冗余来提⾼可靠性和可⽤性。负载平衡通常涉及专⽤软件或硬件,例如多层交换机或域名系统服务器进程。
问题五:什么是Hystrix?它如何实现容错?
Hystrix是⼀个延迟和容错库,旨在隔离远程系统,服务和第三⽅库的访问点,当出现故障是不可避免的故障时,停⽌级联故障并在复杂的分布式系统中实现弹性。
通常对于使⽤微服务架构开发的系统,涉及到许多微服务。这些微服务彼此协作。
问题六:什么是Hystrix断路器?我们需要它吗?
由于某些原因,employee-consumer公开服务会引发异常。在这种情况下使⽤Hystrix我们定义了⼀个回退⽅法。如果在公开服务中发⽣异常,则回退⽅法返回⼀些默认值。如果firstPage method() 中的异常继续发⽣,则Hystrix电路将中断,并且员⼯使⽤者将⼀起跳过firtsPage⽅法,并直接调⽤回退⽅法。断路器的⽬的是给第⼀页⽅法或第⼀页⽅法可能调⽤的其他⽅法留出时间,并导致异常恢复。可能发⽣的情况是,在负载较⼩的情况下,导致异常的问题有更好的恢复机会
4、solr-lucene
4.1 solr概念
Solr是⼀个⾼性能,基于Lucene的全⽂搜索服务器。同时对其进⾏了扩展,提供了⽐Lucene更为丰富的查询语⾔,同时实现了可配置、可扩展,并对查询性能进⾏了优化,并且提供了⼀个完善的功能管理界⾯,是⼀款⾮常优秀的全⽂搜索引擎。
4.2 lucene概念
Lucene是apache jakarta项⽬的⼀个⼦项⽬,是⼀个开放源代码的全⽂检索引擎开发⼯具包,但它不是⼀个完整的全⽂检索引擎,⽽是⼀个全⽂检索引擎的架构,提供了完整的查询引擎和索引引擎,部分⽂本分析引擎。Lucene的⽬的是为软件开发⼈员提供⼀个简单易⽤的⼯具包,以⽅便的在⽬标系统中实现全⽂检索的功能,或者是以此为基础建⽴起完整的全⽂检索引擎。
4.3 倒排索引
Mysql索引是(B+tree)
我们⼀般情况下,先到⽂档,再在⽂档中出包含的词;
倒排索引则是这个过程反过来,⽤词,来出它出现的⽂档.
实际举例
⽂档编号⽂档内容
1、全⽂检索引擎⼯具包
2、全⽂检索引擎的架构
3、查询引擎和索引引擎
分词结果
⽂档编号分词结果集
1、{全⽂,检索,引擎,⼯具,包}
2、{全⽂,检索,引擎,的,架构}
3、{查询,引擎,和,索引,引擎}
5、rabbitMQ
5.1 概念
MQ全称是Message Queue,可以理解为消息队列的意思,简单来说就是消息以管道的⽅式进⾏传递。RabbitMQ是⼀个实现了AMQP(Advanced Message Queuing Protocol)⾼级消息队列协议的消息队列服务,⽤Erlang语⾔的。
RabbitMQ是⼀种消息中间件,⽤于处理来⾃客户端的异步消息。服务端将要发送的消息放⼊到队列池
中。接收端可以根据RabbitMQ配置的转发机制接收服务端发来的消息。RabbitMQ依据指定的转发规则进⾏消息的转发、缓冲和持久化操作,主要⽤在多服务器间或单服务器的⼦系统间进⾏通信,是分布式系统标准的配置。
为什么选择RabbitMQ
现在的市⾯上有很多MQ可以选择,⽐如ActiveMQ、ZeroMQ、Appche Qpid,那问题来了为什么要选择RabbitMQ?
1、除了Qpid,RabbitMQ是唯⼀⼀个实现了AMQP标准的消息服务器;
2、可靠性,RabbitMQ的持久化⽀持,保证了消息的稳定性;
3、⾼并发,RabbitMQ使⽤了Erlang开发语⾔,Erlang是为电话交换机开发的语⾔,天⽣⾃带⾼并发光环,和⾼可⽤特性;
4、集部署简单,正是应为Erlang使得RabbitMQ集部署变的超级简单;
5、社区活跃度⾼,根据⽹上资料来看,RabbitMQ也是⾸选;
5.2 ⼯作模式
5.2.1 简单模式
RabbitMQ是⼀个消息中间件,你可以想象它是⼀个邮局。当你把信件放到邮箱⾥时,能够确信邮递员会正确地递送你的信件。RabbitMq就是⼀个邮箱、⼀个邮局和⼀个邮递员。
发送消息的程序是⽣产者
队列就代表⼀个邮箱。虽然消息会流经RbbitMQ和你的应⽤程序,但消息只能被存储在队列⾥。队列存储空间只受服务器内存和磁盘限制,它本质上是⼀个⼤的消息缓冲区。多个⽣产者可以向同⼀个队列发送消息,多个消费者也可以从同⼀个队列接收消息.
消费者等待从队列接收消息
5.2.2 ⼯作模式
⼯作队列(即任务队列)背后的主要思想是避免⽴即执⾏资源密集型任务,并且必须等待它完成。相反,我们将任务安排在稍后完成。
我们将任务封装为消息并将其发送到队列。后台运⾏的⼯作进程将获取任务并最终执⾏任务。当运⾏多个消费者时,任务将在它们之间分发。
使⽤任务队列的⼀个优点是能够轻松地并⾏⼯作。如果我们正在积压⼯作任务,我们可以添加更多⼯作进程,这样就可以轻松扩展。
⼀个⽣产者,多个消费者,每个消费者获取到的消息唯⼀。
1、⾃动模式
消费者从消息队列获取消息后,服务端就认为该消息已经成功消费。
2、⼿动模式
消费者从消息队列获取消息后,服务端并没有标记为成功消费
消费者成功消费后需要将状态返回到服务端
5.2.3 发布订阅模式
⼀个⽣产者发送的消息会被多个消费者获取。
⽣产者:可以将消息发送到队列或者是交换机。
消费者:只能从队列中获取消息。
如果消息发送到没有队列绑定的交换机上,那么消息将丢失。
Exchanges 交换机(使⽤fanout交换机)
RabbitMQ消息传递模型的核⼼思想是,⽣产者永远不会将任何消息直接发送到队列。实际上,通常⽣
产者甚⾄不知道消息是否会被传递到任何队列。相反,⽣产者只能向交换机(Exchange)发送消息。交换机是⼀个⾮常简单的东西。⼀边接收来⾃⽣产者的消息,另⼀边将消息推送到队列。交换器必须确切地知道如何处理它接收到的消息。它应该被添加到⼀个特定的队列中吗?它应该添加到多个队列中吗?或者它应该被丢弃。这些规则由exchange 的类型定义。
有⼏种可⽤的交换类型:direct、topic、header和fanout。我们将关注最后⼀个——fanout。让我们创建⼀个这种类型的交换机,并称之为
logs: ch.exchangeDeclare("logs", "fanout");
fanout交换机⾮常简单。它只是将接收到的所有消息⼴播给它所知道的所有队列。这正是我们的⽇志系统所需要的。
5.2.4 路由模式
1、发送消息到交换机并且要指定路由key
2、消费者将队列绑定到交换机时需要指定路由key
使⽤直连交换机 Direct exchange
如果将⽇志消息写⼊磁盘的程序只接收关键error,⽽不是在warning或info⽇志消息上浪费磁盘空间。
前⾯我们使⽤的是fanout交换机,这并没有给我们太多的灵活性——它只能进⾏简单的⼴播。
我们将⽤直连交换机(Direct exchange)代替。它背后的路由算法很简单——消息传递到bindingKey与routingKey完全匹配的队列。
5.2.5 主题模式
在上⼀⼩节,我们改进了⽇志系统。我们没有使⽤只能进⾏⼴播的fanout交换机,⽽是使⽤Direct交换机,从⽽可以选择性接收⽇志。
虽然使⽤Direct交换机改进了我们的系统,但它仍然有局限性——它不能基于多个标准进⾏路由。
在我们的⽇志系统中,我们可能不仅希望根据级别订阅⽇志,还希望根据发出⽇志的源订阅⽇志。
这将给我们带来很⼤的灵活性——我们可能只想接收来⾃“cron”的关键错误,但也要接收来⾃“kern”的所有⽇志。
要在⽇志系统中实现这⼀点,我们需要了解更复杂的Topic交换机。
主题交换机 Topic exchange
发送到Topic交换机的消息,它的的routingKey,必须是由点分隔的多个单词。单词可以是任何东西,但通常是与消息相关的⼀些特性。⼏个有效的routingKey⽰例:“se”、“nyse.vmw”、“ange.rabbit”。routingKey可以有任意多的单词,最多255个字节。
bindingKey也必须采⽤相同的形式。Topic交换机的逻辑与直连交换机类似——使⽤特定routingKey发送的消息将被传递到所有使⽤匹配bindingKey绑定的队列。bindingKey有两个重要的特殊点:
* 可以通配单个单词。
# 可以通配零个或多个单词。
5.2.6 RPC模式
(RPC) Remote Procedure Call Protocol 远程过程调⽤协议
在⼀个⼤型的公司,系统由⼤⼤⼩⼩的服务构成,不同的团队维护不同的代码,部署在不同的机器。但是在做开发时候往往要⽤到其它团队的⽅法,因为已经有了实现。但是这些服务部署不同的机器上,想要调⽤就需要⽹络通信,这些代码繁琐且复杂,⼀不⼩⼼就会写的很低效。RPC协议定义了规划,其它的公司都给出了不同的实现。⽐如微软的wcf,以及现在⽕热的WebApi。
回调队列 Callback Queue
使⽤RabbitMQ去实现RPC很容易。⼀个客户端发送请求信息,并得到⼀个服务器端回复的响应信息。为了得到响应信息,我们需要在请求的时候发送⼀个“回调”队列地址。我们可以使⽤默认队列。
关联id (correlationId):
在上⾯的代码中,我们会为每个RPC请求创建⼀个回调队列。这是⾮常低效的,这⾥还有⼀个更好的⽅法:让我们为每个客户端创建⼀个回调队列。
这就提出了⼀个新的问题,在队列中得到⼀个响应时,我们不清楚这个响应所对应的是哪⼀条请求。这时候就需要使⽤关联id(correlationId)。我们将为每⼀条请求设置唯⼀的的id值。稍后,当我们在回调队列⾥收到⼀条消息的时候,我们将查看它的id属性,这样我们就可以匹配对应的请求和响应。如果我们发现了⼀个未知的id值,我们可以安全的丢弃这条消息,因为它不属于我们的请求。
RPC的⼯作⽅式是这样的:
对于RPC请求,客户端发送⼀条带有两个属性的消息:replyTo,设置为仅为请求创建的匿名独占队列,和correlationId,设置为每个请求的惟⼀id值。
请求被发送到rpc_queue队列。
RPC⼯作进程(即:服务器)在队列上等待请求。当⼀个请求出现时,它执⾏任务,并使⽤replyTo字段中的队列将结果发回客户机。
客户机在回应消息队列上等待数据。当消息出现时,它检查correlationId属性。如果匹配请求中的值,则向程序返回该响应数据。
5.3 其他
ConnectionFactory(连接管理器)、Channel(信道)、Exchange(交换器)、Queue(队列)、RoutingKey(路由键)、BindingKey(绑定键)。
ConnectionFactory(连接管理器):应⽤程序与Rabbit之间建⽴连接的管理器,程序代码中使⽤;
Channel(信道):消息推送使⽤的通道;
Exchange(交换器):⽤于接受、分配消息;
Queue(队列):⽤于存储⽣产者的消息;
RoutingKey(路由键):⽤于把⽣成者的数据分配到交换器上;
BindingKey(绑定键):⽤于把交换器的消息绑定到队列上;
5.3.1 消息持久化
Rabbit队列和交换器有⼀个不可告⼈的秘密,就是默认情况下重启服务器会导致消息丢失,那么怎么保证Rabbit在重启的时候不丢失呢?答案就是消息持久化。
当你把消息发送到Rabbit服务器的时候,你需要选择你是否要进⾏持久化,但这并不能保证Rabbit能从崩溃中恢复,想要Rabbit消息能恢复必须满⾜3个条件:
1、投递消息的时候durable设置为true,消息持久化,代码:channel.queueDeclare(x, true, false, false, null),参数2设置为true持久化;
2、设置投递模式deliveryMode设置为2(持久),代码:channel.basicPublish(x, x, MessageProperties.PERSISTENT_TEXT_PLAIN,x),参数3设置为存储纯⽂本到磁盘;
3、消息已经到达持久化交换器上;
4、消息已经到达持久化的队列;
持久化⼯作原理
Rabbit会将你的持久化消息写⼊磁盘上的持久化⽇志⽂件,等消息被消费之后,Rabbit会把这条消息标识为等待垃圾回收。
持久化的缺点
消息持久化的优点显⽽易见,但缺点也很明显,那就是性能,因为要写⼊硬盘要⽐写⼊内存性能较低很多,从⽽降低了服务器的吞吐量,尽管使⽤SSD硬盘可以使事情得到缓解,但他仍然吸⼲了Rabbit的性能,当消息成千上万条要写⼊磁盘的时候,性能是很低的。
所以使⽤者要根据⾃⼰的情况,选择适合⾃⼰的⽅式。
5.4 常见⾯试题
1.什么是rabbitmq
采⽤AMQP⾼级消息队列协议的⼀种消息队列技术,最⼤的特点就是消费并不需要确保提供⽅存在,实现了服务之间的⾼度解耦
2.为什么要使⽤rabbitmq
1.在分布式系统下具备异步,削峰,负载均衡等⼀系列⾼级功能;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论