w
springcloud的组件有哪些
注册中心:euraka、nacos、zookeeper
注册中心及配置中心:nacos
远程调用:feign、dubbo
负载均衡:ribbon
服务熔断:hystrix、sentinel
网关:zuul、gateway
eureka注册中心的作用
△面试题:服务注册和发现是什么意思?springcloud是如何实现服务注册和发现的?
我们当时项目采用的eureka作为注册中心,这个也是spring cloud体系中的一个核心组件。
服务注册:服务提供者需要把自己的信息注册到eureka,由eureka来保存这些信息,比如服务名称、ip、端口等等。
服务发现:消费者向eureka拉取服务列表信息,如果服务提供者有集群,则消费者会利用负载均衡算法,选择一个发起调用。
服务监控:服务提供者会每隔30秒向eureka发送心跳,报告健康状态,如果eureka服务90秒没接收到心跳,从eureka中剔除
△面试题:nacos和eureka的区别
nacos和eureka的共同点
- 都支持服务注册和服务拉取
- 都是注册中心
- 都支持服务提供者心跳方式做健康方式
如果是临时实例,那么nacos和eureka的工作流程基本一致
nacos和eureka的不同点
- nacos支持服务端主动检测提供者状态,临时实例采用心跳模式,非临时实例采用主动检测模式
- 临时实例心跳不正常会被剔除,非临时实例心跳不正常不会被剔除
- nacos支持服务列表变更的消息推送模式,服务列表能够及时更新
- nacos集群默认采用AP模式,当集群中存在非临时实例时,才采用CP模式;eureka采用AP模式
- nacos还支持配置中心;eureka仅仅是注册中心
nacos默认是临时实例,ephemeral配置默认为true
CAP理论
CAP即
- Consistency(一致性):用户访问分布式系统任意节点得到的数据必须是一致的
- Availability(可用性):用户访问集群中的任意健康节点,必须能得到响应,而不是超时或拒绝
- Partition tolerance(分区容忍性):因为网络故障或其它原因导致分布式系统中的部分节点与其它节点失去连接,形成独立分区。
结论:
- 分布式系统节点之间肯定是需要网络连接的,分区§是必然存在的
- 如果保证访问的高可用性(A),可以持续对外提供服务,但不能保证数据的强一致性
- AP- 如果保证访问的数据强一致性©,就要放弃高可用性–>CP
BASE理论
base理论是对CAP的一种解决思路,其中包括:
- Basically Available(基本可用)︰分布式系统在出现故障时,允许损失部分可用性,即保证核心可用
- Soft State (软状态)︰在一定时间内,允许出现中间状态,比如临时的不一致状态。
- Eventually Consistent(最终一致性)︰虽然无法保证强一致性,但是在软状态结束后,最终达到数据一致。
解决分布式事务的思想和模型:
- 最终一致思想:各分支事务分别执行并提交,如果有不一致的情况,再想办法恢复数据(AP)
- 强一致思想:各分支事务执行完业务不要提交,等待彼此结果。而后统一提交或回滚(CP)
ribbon负载均衡是如何实现的?
微服务的负载均衡主要使用了一个组件Ribbon,比如,我们在使用feign远程调用的过程中,底层的负载均衡就是使用了ribbon。
ribbon执行流程
ribbon负载均衡策略有哪些?
- RoundRobinRule:简单轮询服务列表来选择服务器
- WeightedResponseTimeRule:按照权重来选择服务器,响应时间越长,权重越小
- RandomRule:随机选择一个可用的服务器
- BestAvailableRule:忽略那些短路的服务器,并选择并发数较低的服务器
- RetryRule:重试机制的选择逻辑
- AvailabilityFilteringRule:可用性敏感策略,先过滤非健康的,再选择连接数较小的实例
- ZoneAvoidanceRule: ribbon默认策略,以区域可用的服务器为基础进行服务器的选择。使用Zone对服务器进行分类,这个Zone可以理解为一个机房、一个机架等。再对Zone内的多个服务做轮询
如何指定负载均衡策略?
通过实现IRule接口,然后再通过配置类或配置文件配置即可,有两种方式
什么是服务雪崩?怎么解决这个问题?
服务雪崩是指一个服务失败导致整条链路的服务都出现问题的情形。
服务降级
服务降级是服务自我保护或者保护下游服务的一种方式。用于确保服务不会受请求突增从而影响导致不可用。一般在实际开发中调用feign组件整合,实现服务降级逻辑。
feign示例
Hystrix熔断机制
Hystrix熔断机制,用于监控微服务调用情况,默认是关闭的。
开启需要在引导类上添加注解:@EnableCircuitBreaker,若默认检测到10秒内请求的失败率超过50%,就触发熔断机制。之后每隔5秒重新尝试请求微服务,如果微服务不能响应,继续走熔断机制。如果微服务可达,则关闭熔断机制,恢复正常请求。
你们项目中有用过限流吗?怎么做的?
为什么要限流?
1、突发流量太大
2、防止用户恶意刷接口
限流的实现方式
- tomcat:设置最大连接
- Nginx
控制速率(面对突发流量场景)——漏桶算法
nginx.conf 配置
http{
limit_req_zone $binary_remote_addr zone=service1RateLimit:10m rate=10r/s;
server {
listen 80;
server_name localhost;
location /{
limit_req_zone = service1RateLimit burst=20 nodelay;
proxy_pass http://targetserver;
}
}
}
说明:
语法:limit_req_zone key zone rate
- key:定义限流方式,$binary_remote_addr就是一种key,它表示基于客户端IP方式限流
- zone:定义共享存储区来存储访问信息(自定义标识,在server里使用),10m可以存储16万的ip地址访问信息
- rate:最大访问速率,rate=10r/s 表示每秒最多10个请求来请求服务端
- burst=20,表示这个桶最多可以存储20个请求
- nodelay,表示快速处理
控制并发连接数
http{
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;
server {
listen 80;
server_name localhost;
location /{
# 对应的key为$binary_remote_addr,表示限制单个IP同时最多持有20个连接
limit_conn_zone perip 20;
# 对应的key为$server_name,表示虚拟机(server)同时能处理并发连接的总数
limit_conn_zone perserver 100;
proxy_pass http://targetserver;
}
}
}
- 网关
令牌桶算法:令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。
yml配置文件中配置,微服务路由添加局部过滤器RequestRateLimiter
说明:
key-resolver :定义限流对象( ip、路径、参数),需代码实现,使用spel表达式获取replenishRate :令牌桶每秒填充平均速率。
urstCapacity :令牌桶总容量。
- 自定义拦截器—AOP
…
△面试回答:
先来介绍业务,什么情况下去做限流,需要说明QPS具体多少
我们当时有一个活动,到了假期就会抢购优惠券,QPS最高可以达到2000,平时10-50之间,为了应对突发流量,需要做限流
常规限流,为了防止恶意攻击,保护系统正常运行,我们当时系统能够承受最大的QPS是多少(压测结果)nginx限流
控制速率(突发流量),使用的漏桶算法来实现过滤,让请求以固定的速率处理请求,可以应对突发流量控制并发数,限制单个ip的链接数和并发链接的总数
网关限流
在spring cloud gateway中支持局部过滤器RequestRateLimiter来做限流,使用的是令牌桶算法可以根据ip或路径进行限流,可以设置每秒填充平均速率,和令牌桶总容量