springcloud解决什么问题?
springcloud是一套微服务解决框架。
用来解决服务发现、服务注册、断路器、负载均衡、路由策略的等问题。
springcloud常用的组件?
服务注册和发现:eureka
客户端负载均衡:ribbon和feign
断路器:hystrix
服务网关:zuul、gateway
分布式配置:springcloud config
服务注册与发现?
- 服务注册就是微服务将自己的ip端口等信息注册到注册中心服务列表里面.
- 心跳机制:服务列表减少时候,则是在应用启动后,节点们将会向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)。
- 服务发现就是微服务可以拉取注册中心的服务列表.
微服务之间是如何独立通讯的?
通过RPC调用方式.
RPC:是调用方式,通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的。
RMI远程方法调用、webservice、restfull都是RPC。
rpc框架:springcloud(基于http传输协议实现)、dubbo(基于tcp协议实现)。
RPC协议和HTTP协议的区别
既然有 HTTP 协议,为什么还要有 RPC? (qq.com)
服务发现不同:http通过dns解析到ip和端口号,rpc协议通过consul等中间件获取ip和端口号
openFeign的源码?
花一个周末,掌握 SpringCloud OpenFeign 核心原理 - 知乎 (zhihu.com)
【SpringCloud原理】OpenFeign之FeignClient动态代理生成原理 (qq.com)
-
通过@EnableFeignClients(basePackages = {"com.chao.springcloud"})注解启动 Feign Starter 组件
-
Feign Starter 在项目启动过程中,1)注册配置,2)然后扫描包下所有的 @FeignClient 接口类,每一个@FeignClient生成一个子容器,并进行设置父亲的IOC 容器,父子容器为了实现每个FeignClient之间配置隔离。
-
@FeignClient 接口类被注入时,通过
FactoryBean#getObject返回动态代理类 -
接口被调用时被动态代理类逻辑拦截,将 @FeignClient 请求信息通过编码器生成 Request
-
交由 Ribbon 进行负载均衡,挑选出一个健康的 Server 实例
-
继而通过 Client 携带 Request 调用远端服务返回请求响应,通过解码器生成 Response 返回客户端,将信息流解析成为接口返回数据
Ribbon和Feign的区别?
两者都是用来做服务调用负载均衡的,但是最主要区别在于调用方式不同,Ribbon需要自己构建http请求,模拟http请求然后使用RestTemplate发送给其他服务,步骤相当繁琐。Feign需要将调用的方法定义成抽象方法即可。
Feign的负载均衡策略?
随机:几个提供者间随机访问 ,默认选项
轮询:轮流访问
重试:在一段时间内通过RoundRobinRule选择服务实例,一段时间内没有选择出服务则线程终止
响应时间权重:根据平均响应时间来计算权重
什么是服务雪崩?服务熔断和服务降级?
https://blog.csdn.net/Mrs_chens/article/details/91831286
服务雪崩:服务端 一个服务的失败,导致整条产业链的服务都失败的状况,我们称之为服务雪崩。
服务降级:当整个微服务架构整体的负载超出了预设的上限阈值或即将到来的流量预计将会超过预设的阈值时,为了保证重要或基本的服务能正常运行,可以将一些 不重要 或 不紧急 的服务或任务进行服务的 延迟使用 或 暂停使用。
服务熔断:当扇出链路的某个微服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。检测到该节点微服务调用响应正常后恢复调用链路。断路器 open-》half-open-〉closed
服务限流:限制并发的请求访问量,超过阈值则拒绝;
狂神说SpringCloud学习笔记-KuangStudy-文章
如何设计限流模块?
可以使用Guava的RateLimiter或者spirngcloud gateway
限流的算法(四种都要了解)?
固定窗口
滑动窗口
漏桶
令牌桶
- 有一个令牌管理员,根据限流大小,定速往令牌桶里放令牌。
- 如果令牌数量满了,超过令牌桶容量的限制,那就丢弃。
- 系统在接受到一个用户请求时,都会先去令牌桶要一个令牌。如果拿到令牌,那么就处理这个请求的业务逻辑;
- 如果拿不到令牌,就直接拒绝这个请求。
其中基于令牌桶 的实现 有guava的RateLimiter和 spirngcloud gateway 的在过滤器工厂中是通过Redis和lua脚本结合的方式进行流量控制。
eureka和zookeeper都可以提供服务注册和发现的功能,两者的区别?
分布式领域中,有cap原则,C(Consistency)数据一致性,A(Availability)可用性,P(Partition tolerance)分区容错性,三者只能同时满足两个,由于网络延迟一定会导致丢包等问题,仍需要集群正常提供服务,所以分区容错性是必须满足的,也就只能划分CP或者AP。 其中,zookeeper保证cp。
zookeeper选择优先保证一致性。zookeeper保证访问请求都能保持一致的结果,同时具有容错性,但是不保证每次访问请求都是可用的。为什么不保证对请求可用呢?当zookeeper的master节点如果因为网络故障导致与其它slave节点失去联系时,剩余的节点会进行选举产生新的master节点,但是在这过程需要一定的时间,并且在选举这段时间内,整个zookeeper集群是不可用的。并且由于网络问题,这种情况发生的概率是比较大的。
Eureka保证AP
Eureka的节点之间是平等的。如果某个节点服务器宕机了,Eureka不会像zookeeper那样进行停止服务进行选举,而是让请求自动切换到另外的可用Eureka节点上,等到宕机的节点恢复后,再将其纳入集群中,只是不保证查询到的信息可能不是最新的。
eureka注册机制?
Eureka Server设计(转载 石杉的架构笔记) - 伪全栈的java工程师 - 博客园 (cnblogs.com)
场景:
客户端服务原本部署在1台机器上,现在扩容了,部署到了3台机器,并且均注册到了Eureka Server上。
客户端服务通过Eureka Client会每隔30秒去找Eureka Server拉取最近注册表的变化,看看其他服务的地址有没有变化。
除此之外,Eureka还有一个心跳机制,各个Eureka Client每隔30秒会发送一次心跳到Eureka Server,通知人家说,哥们,我这个服务实例还活着!
原理:
-
-
在拉取注册表的时候:
-
- 首先从ReadOnlyCacheMap里查缓存的注册表。
- 若没有,就找ReadWriteCacheMap里缓存的注册表。
- 如果还没有,就从内存(registry)中获取实际的注册表数据。
-
在注册表发生变更的时候:
-
- 会在内存中更新变更的注册表数据,同时过期掉ReadWriteCacheMap。
- 此过程不会影响ReadOnlyCacheMap提供人家查询注册表。一段时间内(默认30秒),各服务拉取注册表会直接读ReadOnlyCacheMap
- 30秒过后,Eureka Server的后台线程发现ReadWriteCacheMap已经清空了,也会清空ReadOnlyCacheMap中的缓存
-
下次有服务拉取注册表,又会从内存(registry)中获取最新的数据了,同时填充各个缓存。
多级缓存机制的优点是什么?
- 尽可能保证了内存注册表数据不会出现频繁的读写冲突问题。
- 并且进一步保证对Eureka Server的大量请求,都是快速从纯内存走,性能极高。