一、 什么是微服务架构
1. 什么是微服务架构?微服务架构的特点是什么?
微服务架构就是将单体的应用程序分成多个应用程序,这多个应用程序就成为微服务,每个微服务运行在自己的进程中,并使用轻量级的机制通信。这些服务围绕业务能力来划分,并通过自动化部署机制来独立部署。这些服务可以使用不同的编程语言,不同数据库,以保证最低限度的集中式管理。
特点:
- 单一职责:微服务中每一个服务都对应唯一的业务能力,做到单一职责。
- 技术独立:因为是面向服务,提供Rest接口,使用什么技术没有人干涉
- 前后端分离
- 数据库分离
- 部署独立
2. Spring Cloud 是什么
Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、智能路由、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。 Spring Cloud并没有重复制造轮子,它只是将各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
3. SpringCloud的优缺点
优点:
耦合度比较低。不会影响其他模块的开发。
减轻团队的成本,可以并行开发,不用关注其他人怎么开发,先关注自己的开发。
配置比较简单,基本用注解就能实现,不用使用过多的配置文件。
微服务跨平台的,可以用任何一种语言开发。
每个微服务可以有自己的独立的数据库也有用公共的数据库。
直接写后端的代码,不用关注前端怎么开发,直接写自己的后端代码即可,然后暴露接口,通过组件进行服务通信。
缺点:
部署比较麻烦
针对数据的管理比麻烦,因为微服务可以每个微服务使用一个数据库。
系统集成测试比较麻烦
性能的监控比较麻烦。【最好开发一个大屏监控系统】
总的来说优点大过于缺点,目前看来Spring Cloud是一套非常完善的分布式框架,目前很多企业开始用微服务、Spring Cloud的优势是显而易见的。因此对于想研究微服务架构的同学来说,学习Spring Cloud是一个不错的选择。
4. SpringBoot和SpringCloud的区别?
SpringBoot专注于快速方便的开发单个个体微服务。 SpringCloud是关注全局的微服务协调整理治理框架,它将SpringBoot开发的一个个单体微服务整合并管理起来, 为各个微服务之间提供,配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等集成服务 SpringBoot可以离开SpringCloud独立使用开发项目, 但是SpringCloud离不开SpringBoot ,属于依赖的关系 SpringBoot专注于快速、方便的开发单个微服务个体,SpringCloud关注全局的服务治理框架。
5. SpringCloud由什么组成
SpringCloud目前只要有两套:SpringCloud Netflix和SpringCloud Alibaba
- SpringCloud Netflix
- Spring Cloud Eureka:服务注册与发现
- Spring Cloud Zuul:服务网关
- Spring Cloud Ribbon:客户端负载均衡
- Spring Cloud Feign:声明性的Web服务客户端
- Spring Cloud Hystrix:断路器
- Spring Cloud Confifig:分布式统一配置管理
- zipkin:分布式链路追踪
- SpringCloud Alibaba
- nacos:注册中心、配置中心
- gateway:服务网关
- Spring Cloud Ribbon:客户端负载均衡
- Spring Cloud Feign:声明性的Web服务客户端
- Sentinel:服务容错(限流、降级、熔断)
- Sleuth:调用链监控
- Seata:分布式事务
6. Spring Cloud 和dubbo区别?
服务调用方式:
dubbo是RPC
springcloud是Rest Api
注册中心:
dubbo 是zookeeper
springcloud是eureka,也可以是zookeeper
最大区别:SpringCloud抛弃了Dubbo的RPC通信,采用的是基于HTTP的REST方式。
总体来说,两者各有优势。虽说后者服务调用的功能,但也避免了上面提到的原生RPC带来的问题。而且REST相比RPC更为灵活,服务提供方和调用方的依赖只依靠一纸契约,不存在代码级别的依赖,这在强调快速演化的微服务环境下,显得更加合适。
SpringCloud比dubbo的功能更强大,覆盖面更广,而且能够与SpringFramework、SpringBoot、SpringData、SpringBatch等其他Spring项目完美融合,这些对于微服务至关重要。
使用Dubbo构建的微服务架构各环节我们选择自由度高,而SpringCloud在Spring Source的整合下,做了大量的兼容性测试,保证了机器拥有更高的稳定性。
二、Eureka
1. 什么是Eureka
Eureka是SpringCloud的主要组件,是服务注册发现的组件。Spring Cloud Eureka分为Server端和Client端,Server端作为应用的注册中心,Client端会向Server端注册服务消费服务。Eureka Server和Eureka Client都是采用Java编写的,所以,Eureka主要适用于通过Java实现的分布式系统,但是Eureka Server的服务治理机制提供了完备的RESTful API,所以它也支持将非Java语言构建的微服务应用纳入Eureka的服务治理体系中来。
2. Eureka有哪些功能?
服务注册
Eureka Client会启动时通过发送REST请求的方式向Eureka Server注册自己的服务,提供自身的元数据,比如ip地址、端口、运行状况指标的url、主页地址等信息。Eureka Server接收到注册请求后就会把这些元数据信息存储在一个双层的ConcurrentHashMap中。
服务上线:http://192.168.1.1:8810/eureka/apps/USER-SERVICE/192.168.1.9:user-service:8086/status?value=UP
服务续约
服务注册后,Eureka Client会维护一个心跳来持续通知Eureka Server,告知注册中心服务一直处于可用状态,防止被剔除。Eureka Client在默认的情况下会每隔30秒发送一次心跳来进行服务续约。Eureka Server会有一个定时器定时轮训是否续约,连续90s没收到心跳就会触发服务剔除。 服务续约任务的调用间隔时间,默认为30秒 eureka.instance.lease-renewal-interval-in-seconds=30 服务失效的时间,默认为90秒。 eureka.instance.lease-expiration-duration-in-seconds=90
服务剔除
有时候,服务实例可能会因为网络故障等原因导致不能提供服务,而此时该实例也没有发送请求给Eureka Server来进行服务下线,所以,还需要有服务剔除的机制。Eureka Server在启动的时候会创建一个定时任务,每隔一段时间(默认60秒),从当前服务清单中把超时没有续约(默认90秒)的服务剔除。
服务下线
当Eureka Client需要关闭或重启时,就不希望在这个时间段内再有请求进来,所以,就需要提前先发送REST请求给Eureka Server,告诉Eureka Server自己要下线了,Eureka Server在收到请求后,就会把该服务状态置为下线(DOWN),并把该下线事件传播出去。
服务同步
Eureka Server之间会互相进行注册,构建Eureka Server集群,不同Eureka Server之间会进行服务同步,用来保证服务信息的一致性
获取服务
Eureka Client会定时向服务器拉取注册服务列表,分为全量拉取和增量拉取。拉取使用到了缓存ResponseCache实现,有两层缓存实现。服务消费者(Eureka Client)在启动的时候,会发送一个REST请求给Eureka Server,获取上面注册的服务清单,并且缓存在Eureka Client本地,默认缓存30秒,。同时,为了性能考虑,Eureka Server也会维护一份只读的服务清单缓存,该缓存每隔30秒更新一次。 RegistryFetchIntervalSeconds
服务调用
服务消费者在获取到服务清单后,就可以根据清单中的服务列表信息,查找到其他服务的地址,从而进行远程调用。Eureka有Region和Zone的概念,一个Region可以包含多个Zone,在进行服务调用时,优先访问处于同一个Zone中的服务提供者。
自我保护
既然Eureka Server会定时剔除超时没有续约的服务,那就有可能出现一种场景,网络一段时间内发生了异常,所有的服务都没能够进行续约,Eureka Server就把所有的服务都剔除了,这样显然不太合理。所以,就有了自我保护机制,当短时间内,统计续约失败的比例,如果达到一定阈值,则会触发自我保护的机制,在该机制下,Eureka Server不会剔除任何的微服务,等到正常后,再退出自我保护机制。
远程调用
当 Eureka Client 从注册中心获取到服务提供者信息后,就可以通过 Http 请求调用对应的服务;服务提供者有多个时,Eureka Client 客户端会通过 Ribbon 自动进行负载均衡。
3. Eureka怎么实现高可用
可以搭建Eureka Server集群,多个Eureka Server之间也会互相注册为服务,当服务提供者注册到Eureka Server集群中的某个节点时,该节点会把服务的信息同步给集群中的每个节点,从而实现数据同步。因此,无论客户端访问到Eureka Server集群中的任意一个节点,都可以获取到完整的服务列表信息。
4. 什么是Eureka的自我保护模式,
Eureka Server会定时剔除超时没有续约的服务,那就有可能出现一种场景,网络一段时间内发生了异常,所有的服务都没能够进行续约,Eureka Server就把所有的服务都剔除了,这样显然不太合理。所以,就有了自我保护机制,当短时间内,统计续约失败的比例,如果达到一定阈值,则会触发自我保护的机制,在该机制下,Eureka Server不会剔除任何的微服务,等到正常后,再退出自我保护机制。
5. DiscoveryClient的作用
可以从注册中心中根据服务别名获取注册的服务器信息。
6. Eureka和ZooKeeper都可以提供服务注册与发现的功能,请说说两个的区别
Zookeeper保证了CP(C:一致性,P:分区容错性),Eureka保证了AP(A:高可用)
当向注册中心查询服务列表时,我们可以容忍注册中心返回的是几分钟以前的信息,但不能容忍直接down掉不可用。也就是说,服务注册功能对高可用性要求比较高,但zk会出现这样一种情况,当master节点因为网络故障与其他节点失去联系时,剩余节点会重新选leader。问题在于,选取leader时间过长,30 ~ 120s,且选取期间zk集群都不可用,这样就会导致选取期间注册服务瘫痪。在云部署的环境下,因网络问题使得zk集群失去master节点是较大概率会发生的事,虽然服务能够恢复,但是漫长的选取时间导致的注册长期不可用是不能容忍的。
Eureka保证了可用性,Eureka各个节点是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点仍然可以提供注册和查询服务。而Eureka的客户端向某个Eureka注册或发现是发生连接失败,则会自动切换到其他节点,只要有一台Eureka还在,就能保证注册服务可用,只是查到的信息可能不是最新的。除此之外,Eureka还有自我保护机制,如果在15分钟内超过85%的节点没有正常的心跳,那么Eureka就认为客户端与注册中心发生了网络故障,此时会出现以下几种情况:
①、Eureka不在从注册列表中移除因为长时间没有收到心跳而应该过期的服务。
②、Eureka仍然能够接受新服务的注册和查询请求,但是不会被同步到其他节点上(即保证当前节点仍然可用)
③、当网络稳定时,当前实例新的注册信息会被同步到其他节点。
因此,Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像Zookeeper那样使整个微服务瘫痪
三、Zuul
1. 网关的作用是什么
统一管理微服务请求,权限控制、负载均衡、路由转发、监控、安全控制黑名单和白名单等
2. 网关与过滤器有什么区别
网关是对所有服务的请求进行分析过滤,过滤器是对单个服务而言。
3. 常用网关框架有那些?
Nginx、Zuul、Gateway
4. Zuul与Nginx有什么区别?
![]()
- 首先 , Nginx是C语言开发,而 Zuul 是Java语言开发
- Nginx负载均衡实现,采用服务器实现负载均衡,而Zuul负载均衡的实现是采用 Ribbon + Eureka 来实现本地负载均衡。
- Nginx适合于服务器端负载均衡,Zuul适合微服务中实现网关
- Nginx相比Zuul功能会更加强大,因为Nginx可以整合一些脚本语言( Nginx + lua )
- Nginx 是一个高性能的HTTP 和反向代理服务器,也可以作为静态服务器。Zuul是 Spring Cloud Netflix 中的开源的一个API Gateway 服务器,本质上是一个web servlet 应用,提供动态路由,监控,弹性,安全等边缘服务的框架。Zuul 相当于是设备和Netflix 流应用的Web 网站后端所有请求的前门
5. 既然Nginx可以实现网关?为什么还需要使用Zuul框架
Zuul是SpringCloud集成的网关,使用Java语言编写,可以对SpringCloud架构提供更灵活的服务。比如统一管理微服务请求,权限控制、负载均衡、路由转发、监控、安全控制黑名单和白名单等
6. 如何设计一套API接口
考虑到API接口的分类可以将API接口分为开发API接口和内网API接口,内网API接口用于局域网,为内部服务器提供服务。开放API接口用于对外部合作单位提供接口调用,需要遵循Oauth2.0权限认证协议。同时还需要考虑安全性、幂等性等问题。
7. 如何实现动态Zuul网关路由转发
通过path配置拦截请求,通过ServiceId到配置中心获取转发的服务列表,Zuul内部使用Ribbon实现本地负载均衡和转发。
8. Zuul网关如何搭建集群
使用Nginx的upstream设置Zuul服务集群,通过location拦截请求并转发到upstream,默认使用轮询机制对Zuul集群发送请求。
四、Ribbon
1. Ribbon是什么?
Ribbon是Netfix发布的开源项目,主要功能是提供客户端的软件负载均衡算法
Ribbon客户端组件提供一系列完善的配置项,如连接超时,重试等。简单的说,就是在配置文件中列出后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随即连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。(有点类似Nginx)
2.Nginx与Ribbon的区别
Nginx是反向代理同时可以实现负载均衡,nginx拦截客户端请求采用负载均衡策略根据upstream配置进行转发,相当于请求通过nginx服务器进行转发。Ribbon是客户端负载均衡, 从注册中心读取目标服务器信息,然后客户端采用轮询策略对服务直接访问,全程在客户端操作。
3. Ribbon底层实现原理
Ribbon使用discoveryClient从注册中心读取目标服务信息,对同一接口请求进行计数,使用%取余算法获取目标服务集群索引,返回获取到的目标服务信息。
五、Hystrix
1. 什么是Hystrix?
Hystrix是Netflix开源的一款容错框架,包含常用的容错方法:线程隔离、信号量隔离、降级策略、熔断技术。
2. 什么情况下会触发Hystrix降级?
- 线程池已满
- 请求超时
- 服务异常
2. 什么是服务熔断?什么是服务降级?
熔断机制是应对雪崩效应的一种微服务链路保护机制。当扇出链路的某个微服务不可用或者响应时间太长时,会进行服务降级,进而熔断该节点微服务的调用,快速返回“错误”的响应信息。当检测到该节点微服务调用响应正常后恢复调用链路。在SpringCloud框架里熔断机制通过Hystrix实现,Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,默认5秒内 20次失败 且失败比例大于50%,如果失败,就会启动熔断机制。熔断机制的注解是@HystrixCommand
服务降级,一般是从整体负荷考虑。就是当某个服务熔断之后,服务器将不再被调用,此时客户端可以自己准备一个本地的fallback回调,返回一个默认值。这样做,虽然水平下降,但好歹可用,比直接挂掉强。
服务降级分为提供方降级和消费方降级:当访问的目标服务发生异常时,服务提供方进行降级;当访问的目标服务不可达时,可以执行消费方降级。
服务熔断通常适与服务降级配合使用。在服务发生熔断后,一般会让请求走事先配置的处理方法,这个处理方法就是一个降级逻辑。
3. Hystrix有哪三种状态?
**关闭状态:**熔断器默认关闭状态, 所有请求都正常可以访问;
打开状态: 当失败次数达到一定的阈值时,熔断器自动打开;(默认5秒内 20次失败 且失败比例大于50%) 此时,所有请求都进行服务降级;
**半开状态:**熔断5s后,进入半开状态 , 半开 会允许一小部分请求去访问服务,判断结果是否成功:
如果还是失败:进入打开状态,继续熔断5s, .....
如果小部分请求成功了,就会继续放更多的请求过去,直至正常后,熔断器进入关闭状态;
关闭 --打开 --半开 --(成功了)关闭...
关闭 --打开 --半开 --(还是失败)打开...
4. Hystrix限流的两种策略?
- 线程池隔离模式:使用一个线程池来存储当前请求,线程池对请求作处理,设置任务返回处理超时时间,堆积的请求先入线程池队列。这种方式要为每个依赖服务申请线程池,有一定的资源消耗,好处是可以应对突发流量(流量洪峰来临时,处理不完可将数据存储到线程池队里慢慢处理)。
- 信号量隔离模式:使用一个原子计数器(或信号量)记录当前有多少个线程在运行,请求来先判断计数器的数值,若超过设置的最大线程个数则丢弃该类型的新请求,若不超过则执行计数操作请求来计数器+1,请求返回计数器-1。这种方式是严格的控制线程且立即返回模式,无法应对突发流量(流量洪峰来临时,处理的线程超过数量,其他的请求会直接返回,不继续去请求依赖的服务)
六、Feign
1. 微服务之间如何进行通信
- **同步通信:**dubbo的rpc远程调用;springcloud的rest调用
- 异步通信:消息队列,如:RabbitMq、ActiveM、Kafka等消息队列。
2. 什么是Feign?
Feign是一个http客户端,可以帮助我们更便捷的调用HTTP API。
- feign采用的是基于接口的注解
- feign整合了ribbon,具有负载均衡的能力
- 整合了Hystrix,具有熔断的能力
3. SpringCloud有几种调用接口方式
- RestTemplate
- FeignClient
4. feign和dubbo的区别?
协议:
**Dubbo:**支持多传输协议(Dubbo、Rmi、http等等),默认的Dubbo协议:利用
Netty,TCP传输**Feign:**基于
Http传输协议
负载均衡:
Dubbo:
- 支持4种算法(随机、轮询、活跃度、Hash一致性),而且算法里面引入权重的概念。
- 配置的形式不仅支持代码配置,还支持Dubbo控制台灵活动态配置。
- 负载均衡的算法可以精准到某个服务接口的某个方法。
Feign:
支持7种策略:轮询、权重、随机、最小连接数等
负载均衡算法是Client级别的。
容错机制方面:
- Feign:默认使用Hystix作为服务熔断的组件。Hystix提供了服务降级,服务熔断,依赖隔离,监控(Hystrix Dashboard)等功能。Feign是利用熔断机制来实现容错的,与Dubbo处理的方式不一样。
- Dubbo:支持多种容错策略,FailOver、FailFast、Failsafe、FailBack、Aviailable、Broadcast、Forking策略等,以及Mock。也引入了retry次数,timeout等配置参数。Dubbo自带了失败重试的功能。
七、Bus
1. 熟悉 Spring Cloud Bus 吗?
spring cloud bus 将分布式的节点用轻量的消息代理连接起来,它可以用于广播配置文件的更改或者服务直接的通讯,也可用于监控。如果修改了配置文件,发送一次请求,所有的客户端便会重新读取配置文件。
八、Spring Cloud Config
1. 了解Spring Cloud Config 吗?
在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件。在Spring Cloud中,有分布式配置中心组件Spring Cloud Config,它支持配置服务放在配置服务的内存中(即本地),也支持放在远程Git仓库中。