一、相关概念
1、什么是集群
集群是指将多台服务器集中在一起,每台服务器都实现相同的业务,做相同的事,一起来工作,从而提高工作能力。可以分散服务器压力解决高并发的问题,同时也能预防单节点故障,即一台服务器故障不影响其他服务器正常运行,但没有解决单体应用代码臃肿,业务复杂,维护性差等等问题。
2、什么是负载均衡
使用了集群后,解决高并发同时有一个新的问题,就是客户端的请求如何分配到多台服务。因此需要通过负载均衡器,比如Nginx,使用负载均衡算法比如轮询、权重、随机等等将请求分发到不同的服务器。
3、什么是分布式
分布式是将应用按照业务类型拆分成多个子应用,每个子应用部署在不同的服务器上单独运行,子应用之间通过API相互调用。可以分散服务器压力解决高并发问题,同时可以解决单体应用代码臃肿、业务复杂、维护性差等等问题,但是不能防止单节点故障,比如一个子应用故障,整个应用就能不完整运行
4、集群和分布式的区别,分别解决什么问题
集群 | 分布式 | |
概念 | 将一个应用程序复制多份,部署在多台服务器上,每个服务器中的程序都是完整的,可独立运行 | 将一个应用程序拆分成多个子程序,分别部署在多台服务器上,每个服务器中的程序都是不完整的,所有服务器需要相互通信相互协调才能完成最终的业务; |
能解决高并发问题,同时能防止单节点故障,即一台服务器宕机不影响其他服务器的正常运行 | 能解决高并发问题,但不能防止单节点故障,即一台服务器宕机了,整体业务就无法完成 | |
没有解决单体应用代码臃肿,业务复杂,维护性差等等问题 | 解决单体应用代码臃肿、业务复杂、维护性差、能降低模块之间的耦合等等问题 |
实际应用中,我们可以将分布式和集群相结合,比如分布式某个子程序的负载很高,可以单独对这个子程序做集群
5、说一下你理解的微服务
微服务也是一个分布式系统,它将单体应用进行细粒度拆分,形成多个微服务,每个服务独立运行,每个服务也都可以有自己的数据库,服务之间使用HTTP通信,互相协调完成整个系统的业务。它的优点是服务之间解耦合,不同的服务可以有不同的编程语言,技术选型多元化,支持敏捷开发,他的缺点是分布式事务很复杂,部署麻烦,技术成本高,服务间通信对性能也有一定的损耗。
6、什么是CAP理论 , 哪些技术用到AP,哪些用到CP
CAP原理指的是在分布式系统中,一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance)三个要素不可能同时得到保证,只能满足其中两个。分区容错性是分布式系统的内在要求,因此我们通常会在一致性和可用性之间做取舍。
CP如果系统允许有段时间失效就可以考虑。常见的如Redis,Nacos,ZooKeeper;AP,如果系统允许出现短暂时间的不一致可以考虑。常见的如MySQL,Eureka
应用场景
1)CA场景:银行转账系统需要保证转账操作的强一致性,同时也需要保证系统的高可用性,这时可以采用CA模型。但是,当网络发生分区时,整个系统可能会失效,因此需要采取其他措施来保证系统的可用性和分区容错性。
2)CP场景:数据库系统需要保证数据的强一致性和分区容错性,但是在某些情况下,可以适当降低可用性,例如暂停写入操作或者延迟响应读取请求等。
3)AP场景:社交网络系统需要保证数据能够及时响应用户请求,并且能够容忍部分数据不一致的情况。
7、什么是强一致性和最终一致性
强一致性是只数据在多个副本中总数实时同步的,如果能容忍数据在多个副本中在一定的延迟时间内同步,则是弱一致性
最终一致性则不要求数据什么时候同步,但是最终会同步即可。通常情况下我们在分布式领域选择会牺牲了强一致性,会采用最终一致性。
8、什么是Base理论?
Base指的是基本可用、软状态、最终一致性。它是对CAP中的AP的扩展,意思是说当出现故障部分服务不可用时,要保证核心功能可用,允许在一段时间内数据不一致,但最终要保证一致性。满足Base理论的事务也叫柔性事务。
二、SpringCloud
1、讲一下你们公司微服务解决方案
我司正在使用的是第一代微服务方案,Springcloud Netflix全家桶。
它是使用Eureka做服务注册与发现,也就是解决服务之间通信问题,
使用Ribbon/OpenFeign做客户端的负载均衡,也就是解决将请求路由到微服务集群的问题,
使用Hystrix断路器的熔断、降级来解决单节点故障,
使用Zuul做服务网关,将它作为整个微服务的大门,来实现登录、权限检查等业务,
使用Config分布式配置中心,来统一管理配置所有微服务的配置文件,
使用Bus消息总线给各个微服务广播消息,可以实现各个微服务配置的自动刷新,
使用Sleuth链路追踪,来实时监控各个微服务建的调用关系,快速定位故障节点
2、说一说Spring Cloud有哪些常用组件?
Eureka:做服务注册与发现,用来解决服务之间通信问题,
Ribbon/OpenFeign:用做客户端的负载均衡,也就是解决将请求路由到微服务集群的问题,
Hystrix:断路器,它的熔断、降级策略用来解决单节点故障,
Zuul:做服务网关,它是整个微服务的大门,可以用来实现登录、权限检查等业务,
Config:分布式配置中心,用来统一管理配置所有微服务的配置文件,
Bus:消息总线,用来给各个微服务广播消息,可以实现各个微服务配置的自动刷新,
Sleuth:链路追踪,用来实时监控各个微服务建的调用关系,快速定位故障节点
3、Spring Cloud的优缺点?
微服务相对单体应用来说:
优点
-
服务之间无耦合,代码简单方便开发维护,服务之间升级维护互不影响
-
轻量级HTTP通信机制,不同的服务可以采用不同的编程语言
-
有极强的扩展能力,业务量大的服务可以再次拆分服务,或者也可以集群部署
-
支持时下流行的敏捷开发并做了优化
缺点
-
分布式事务繁琐
-
部署麻烦,开发人员的学习成本高
-
技术成本高,开发人员需要花更多的时间学习相关技术
-
微服务间的通信存在对性能的损耗问题
4、什么是服务注册?
Eureka是一个服务注册与发现的组件,翻译成人话就是管理所有微服务的通讯录的组件。它包含注册中心,客户端两部分组成。客户端在启动的时候会向注册中心发送一条自我介绍信息,比如端口,ip等等,在注册中心就会保存一张所有微服务的通讯录。这就叫服务注册。
5、什么是服务发现?
微服务会定期的从注册中心拉取一份微服务通讯录,到本地缓存起来,默认是30s一次。当一个微服务向另一个微服务发起调用,直接根据本地的通讯录找到对方的服务名,发送HTTP请求。这个就叫服务发现。
6、什么是服务续约?
微服务会定时(默认30s)发送心跳请求,告诉注册中心,自己还处于存活状态,那么服务中心就不会将其从清单中删除,否则,当微服务宕机或者网络故障等因素,没有在规定时间(默认90s)内提交心跳请求,注册中心就会将它从通讯录中删除。
7、如果服务挂了,注册中心要等到90s后剔除,那么在剔除前的这段时间内,挂掉的服务有可能还是会被调用,怎么处理?
第一,可以修改注册中心剔除服务时间,同时加快服务续约心跳请求的频率
第二,可以使用Hystrix的熔断降级机制,当某个服务不可访问,快速失败,并返回托底数据
第三。重试,提供者集群
8、你知道EurekaClient服务发现和服务续约每隔30s做一次请求是用什么技术实现的吗?
使用了ScheduledThreadPoolExecutor线程池定时任务来实现。
服务发现(服务续约)是先判断是否开启了服务发现功能(默认是开启的),获取定时任务的间隔时间(默认是30s),然后初始化服务发现(心跳请求)的定时任务,间隔时间可以在yml中修改。
9、Ribbon是什么,Ribbon的工作原理讲一下
Ribbon是一个客户端负载均衡器,它可以按照负载均衡算法,向多个服务发起调用。当一个微服务有多个集群时,就可以使用它做请求负载均衡,通常结合RestTemplate来使用。
工作原理:消费者会30s/次注册中心拉取服务注册清单缓存到本地,当消费者需要调用一组提供者集群服务时,Ribbon会根据提供者服务名,从服务注册中心获取可用的服务列表;然后按照负载均衡算法(默认是轮询),选择其中的一个目标服务实例;在客户端和目标服务之间建立连接,发起http调用服务。故障转移:如果目标服务发生故障或不可用,Ribbon会根据配置的故障转移策略选择另一个可用的服务实例。
Ribobn内部通过LoadBalancerInterceptor拦截RestTemplate发起的请求,然后交给RibbonLoadBalancerClient负载均衡客户端做负载均衡,RibbonLoadBalancerClient把选择服务的工作交给ILoadBalancer负载均衡器 ,ILoadBalancer会调用 IRule负载均衡算法类来选择服务。之后RibbonLoadBalancerClient把选择好的服务交给LoadBalancerRequest去发请求。
RestTemplate是什么?RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。
10、Ribbon有哪些负载均衡算法,怎么配置?
RoundRobinRule:简单轮询,ribbon默认规则
AvailabilityFilteringRule:忽略短路状态和并发过高的服务器
WeightedResponseTimeRule:根据服务器响应时间作为权重,响应时间越长权重越小
ZoneAvoidanceRule:根据区域选择
BestAvailableRule:忽略短路的服务器,选择并发较低的服务器
RandomRule:随机选择一个可用服务器
Retry:重试机制的选择逻辑
11、OpenFeign和Ribbon的区别?
OpenFeign整合了Ribbon和Hystrix,屏蔽了Ribbon拼接URL,参数的细节,使用声明式编程,让服务调用更加简单,OpenFiegn底层也是走的Ribbon的负载均衡策略。推荐使用OpenFeign。
12、OpengFiegn的工作流程?
首先,当程序启动时,@EnableFeignClient会扫描@FeignClient注解的接口,并交给Spring容器管理。当发起请求时,会使用jdk动态代理,并为每个方法都生成相应的RequestTemplate,同时封装http信息,包括url和请求参数等。最后把RestTemplate交给HttpClient发送请求,使用ribbon的负载均衡发起调用。
13、为什么要使用Eureka?为什么要使用Ribbon?为什么要使用config配置中心?
在微服务系统中,各个服务之间是需要进行网络通信的,那么他们相互调用就得知道对方的通信地址。eureka就是专门来做做服务注册与发现,解决服务之间通信问题的。
当一个微服务做了集群,也就是同一个服务名会对应多个地址,那么我们在调用的时候,应该调用哪一个就成了问题,Ribbon是一个负载均衡器,它可以按照负载均衡算法,向多个服务发起调用。当一个微服务有多个集群时,就可以使用它做请求的分发。
在微服务系统中,服务数量很多,而每个服务都有自己的配置文件,管理起来很麻烦。用了config配置中心就可以帮我们集中管理配置文件,它支持本地配置文件,也支持将配置文件放到远程仓库如git集中管理
14、为什么Feign的客户端接口没有写实现类也可以直接被依赖注入?
自动注入的实例其实是一个jdk动态代理对象(生成接口的代理对象,在代理对象中实现了相应的逻辑处理),Feign会为每个方法生成相应的requestTemplate,它根据服务名找到对应的服务,根据返回值类型、形参列表匹配相应的接口,然后封装url、请求参数,最后生成request请求,使用Ribbon负载均衡发起调用
15、介绍一下Hystrix?
Hystrix意为熔断器,它可以将出现故障的服务,通过熔断、降级等手段隔离开,这样不影响整个系统的主业务。它可以防止由单节点异常导致整个微服务故障,如果遇到故障时,快速失败,熔断的同时可以返回兜底数据达到服务降级的目的。
16、什么是熔断,什么是降级
熔断,是对服务链路的一种保护机制,当链路上的某个服务不可访问时,服务就会触发降级返回托底数据,同时当失败率到达一个阈值,就标记该服务为短路状态,当请求访问时直接熔断。直到检查到该服务能正常访问时,就快速恢复。
降级,是当某个服务不可访问时,我们返回一些事先准备好的数据给客户端,比如说,友情提示服务暂不可用,请稍后重试,这样用户体验就上去了。
17、什么是资源隔离?
指的是限制某一个分布式服务的资源使用,可以理解为限流,也就是限制某个服务的请求数量。它包括线程池隔离和信号量隔离。
线程池隔离,通过为每个微服务或服务操作分配独立的线程池来实现的。是指用一个线程池来存储当前请求,可以通过设置线程池最大线程数和最大排队队列数来限制请求数量。
信号量隔离:通过限制同时访问某一资源或服务的并发请求数来实现隔离。是指用一个计数器来记录当前有多少个线程在运行,请求进来计数器就增加1,超过最大信号量,就直接返回
18、资源隔离:信号量和线程池的区别?
线程池方式是异步处理,它与调用线程不是同一个线程
信号量方式是同步处理,与调用线程是同一个线程
线程池方式由于需要排队,调度,线程切换,因此开销较大,信号量方式无需切换线程,开销较小
19、对于CAP理论,Eureka选择的是CP还是AP?它保证了一致性还是可用性?
CAP理论指的是,一个分布式系统中,一致性,可用性,分区容错性,三个要素只能同时实现两点。Eureka选择的是AP,它是弱一致性的,保证了可用性和分区容错性,放弃了数据一致性。也就是说当多个Eureka之间不可通信时,需要保证服务可用,正常提供服务注册发现功能,但是网络恢复后最终还是会同步的。
20、说一下Eureka的自我保护?
为了防止服务被误删除,Eureka不会立即删除过时的服务数据。这种机制可能会导致客户端从注册中心获取到已经下线的服务并发起调用而导致错误,因此在开发阶段我们可以关闭自我保护机制。在生产环境中,我们需要打开自我保护,因为它可以防止因为网络波动,服务没有及时续约而造成的服务误删除问题。
工作原理:
1)当超过一定比例的客户端节点(默认为85%)在一定时间内没有发送心跳时,Eureka Server会认为发生了网络故障,并自动进入自我保护模式[。
2)在自我保护模式下,Eureka Server不会移除因长时间未发送心跳而应该过期的服务。
3)Eureka Server仍然能够接受新服务的注册和查询请求,但不会将这些信息同步到其他节点上,以保证当前节点的可用性。
4)当网络恢复稳定时,当前Eureka Server上的新注册信息会被同步到其他节点中。
21、你们项目是如何做服务降级的?
比如在秒杀业务中,需要实时从redis中查询库存,通过设置hystrix的最大信号量,以此来防止redis雪崩。当并发过高,请求数超过最大信号量,触发降级,直接向客户端返回兜底数据:”活动太火爆啦,请稍后重试“
25、Zuul有哪几类Filter,他们的执行顺序是怎么样的?
zuul按照执行顺序,分为pre前置过滤,route路由过滤,post后置过滤,error异常后过滤。
正常流程是请求先经过前置过滤器,到达路由过滤器进行路由,路由到各种微服务执行请求,返回结果后经过后置过滤,返回用户
异常流程,如果再整个过程中出现异常,都会进入error异常过滤器,处理完毕后经过post过滤器返回用户,如果error自己出现异常,最终也会通过post过滤器返回用户,如果post过滤器出现异常,也会跳转到error过滤器,然后直接返回用户
26、在Zuul中做登录检查如何实现?
可以通过继承ZuulFilter抽象类,自定义pre类型的过滤器,shouldFilter方法中可以定义需要放行的资源,run方法中检查请求头中的token信息,如果没有token,就响应到客户端未登录的信息,并组织filter继续往后执行
27、在Zuul中如何做限流?
方式一:可以通过继承ZuulFilter抽象类自定义pre过滤器,加上限流算法,来实现
方式二:可以通过hystrix的资源隔离模式,设置线程池最大连接数或者最大信号量来实现
方式三:常用,Ratelimit,使用令牌桶算法。。。
28、浏览器发起一个请求,在你的微服务项目中的怎么去执行的?
浏览器发起的所有请求首先通过Nginx,通过负载均衡算法,路由给zuul集群,然后通过zuul前置过滤,作登录校验后,它会从配置中心拉取的通讯地址中,根据url匹配到对应的服务,然后使用ribbon发起restful调用。微服务间也可以通过feign相互调用,最终执行完任务,返回浏览器
29、说下Ribbon和Feign的区别呢?
Ribbon和Feign都是SpringCloud Netflix中实现负载均衡的组件,不同点在于:
Ribbon是需要我们手动构建http请求,根据目标服务名通过负载均衡算法直接调用目标服务,Feign是采用接口的方式,将需要调用的目标服务方法定义成抽象方法,路径,服务名,形参列表,返回值类型需要保持一致。我们只需要调用接口中的方法就可以了。它会自动帮我们生成jdk动态代理,为每个方法生成RequestTemplate并封装url和请求参数,使用负载均衡算法发起调用
Ribbon的实现方式,一般配合RestTemplate发起http请求,我们需要在注册RestTemplate的Bean的方法上加@LoadBalanced,使它具有负载均衡的能力;Feign的实现方式,是在主启动类上加@EnableFeignClients,在客户端接口上加注解@FeignClient
30、Spring,SpringBoot和SpringCloud的关系以及区别?
Spring是一个开源的轻量级控制反转和面向切面编程的容器框架。轻量级是说它开发使用简单,功能强大。控制反转是指将对象的创建,销毁控制交给ioc容器,方便解耦合,降低维护难度,面向切面编程是指将相同的逻辑横向抽取出来,可以对一些通用业务如事务,日志进行集中管理。
Springboot是一个基于spring的框架,对spring做了大量简化,使开发流程更快,更高效。比如它大量简化maven依赖,基于注解配置(JavaConfig)无需XML,内嵌Tomcat,部署流程简单,打包和部署更加灵活,允许独立运行
SpringCloud是基于SpringBoot实现的,用于微服务架构中管理和协调服务的,它是一系列框架的有序集合,它为开发者提供了一系列工具,例如服务发现与注册,配置中心,网关,负载均衡,熔断器,链路追踪等等,让微服务架构落地变得更简单