SpringCloud 服务的平滑上下线

吐槽
以前都是手撸 RPC,最近接触 SpringCloud,深感痛心。主要有以下几点:
1)代码量巨大,找 BUG 时间长,超级复杂的设计
2)版本管理混乱,经常出现莫名其妙的配置错误(所以 2.0 是打死不敢上生产啊)
3)Netflix 公司的有些代码,实在是让人费解,根本就不考虑扩展性
4)生态链庞大,学习成本大

建议准备上微服务的同学,固定下一个版本,不要随意更新或降级。拿 tomcat 的 basedir来说, 1.5.8到 1.5.13到 1.5.16版本是换来换去,不小心点会出事故的。

server:
 port: 21004
 context-path: /
 tomcat:
   basedir: file:.

如上, basedir先是从 .换到 file:.,又从 file:.换成 .,连兼容代码都木有。有木有想打死工程师?

前言
今天主要谈的话题,是 平滑的上下线功能。所谓平滑,指的是发版无感知,不至于等到夜深人静的时候偷偷去搞。某些请求时间可以长点,但不能失败,尤其是对支付来说,想花钱花不出去是很让人苦恼的;花了钱买不到东西是很让人恼火的。整体来说,SpringCloud 功能齐全,经过一段时间的踩坑后使用起来还是非常舒服的。

我们的微服务,大体集成了以下内容。

SpringCloud 服务的平滑上下线

嗯,一个庞大的生态

问题
那么问题来了,SpringCloud 到注册中心的注册是通过 Rest接口调用的。它不能像 ZooKeeper那样,有问题节点反馈及时生效。也不能像 Redis那么快的去轮训,太娇贵怕轮坏了。如下图:

SpringCloud 服务的平滑上下线

有三个要求:

1)ServiceA 下线一台实例后,Zuul 网关的调用不能失败
2)ServiceB 下线一台实例后,ServiceA 的 Feign 调用不能失败
3)服务上线下线,Eureka 服务能够快速感知

说白了就一件事,怎样尽量缩短服务下线后 Zuul 和其他被依赖服务的发现时间,并在这段时间内保证请求不失败。

解决时间问题
影响因子
1) Eureka 的两层缓存问题 (这是什么鬼
EurekaServer 默认有两个缓存,一个是 ReadWriteMap,另一个是 ReadOnlyMap。有服务提供者注册服务或者维持心跳时时,会修改 ReadWriteMap。当有服务调用者查询服务实例列表时,默认会从 ReadOnlyMap 读取(这个在原生 Eureka 可以配置,SpringCloud Eureka 中不能配置,一定会启用 ReadOnlyMap 读取),这样可以减少 ReadWriteMap 读写锁的争用,增大吞吐量。EurekaServer 定时把数据从 ReadWriteMap 更新到 ReadOnlyMap 中
2) 心跳时间
服务提供者注册服务后,会定时心跳。这个根据服务提供者的 Eureka 配置中的服务刷新时间决定。还有个配置是服务过期时间,这个配置在服务提供者配置但是在 EurekaServer 使用了,但是默认配置 EurekaServer 不会启用这个字段。需要配置好 EurekaServer 的扫描失效时间,才会启用 EurekaServer 的主动失效机制。在这个机制启用下:每个服务提供者会发送自己服务过期时间上去,EurekaServer 会定时检查每个服务过期时间和上次心跳时间,如果在过期时间内没有收到过任何一次心跳,同时没有处于保护模式下,则会将这个实例从 ReadWriteMap 中去掉
3)调用者服务从 Eureka 拉列表的轮训间隔
4) Ribbon 缓存
解决方式
1) 禁用 Eureka 的 ReadOnlyMap 缓存 (Eureka 端)


eureka.server.use-read-only-response-cache: false

2) 启用主动失效,并且每次主动失效检测间隔为 3s (Eureka 端)


eureka.server.eviction-interval-timer-in-ms: 3000

像 eureka.server.responseCacheUpdateInvervalMs和 eureka.server.responseCacheAutoExpirationInSeconds在启用了主动失效后其实没什么用了。默认的 180s 真够把人给急疯的。

3) 服务过期时间 (服务提供方)


ureka.instance.lease-expiration-duration-in-seconds: 15

超过这个时间没有接收到心跳 EurekaServer 就会将这个实例剔除。EurekaServer 一定要设置 eureka.server.eviction-interval-timer-in-ms 否则这个配置无效,这个配置一般为服务刷新时间配置的三倍。默认 90s!
4) 服务刷新时间配置,每隔这个时间会主动心跳一次 (服务提供方)


reka.instance.lease-renewal-interval-in-seconds: 5

5) 拉服务列表时间间隔 (客户端)


eureka.client.registryFetchIntervalSeconds: 5

默认 30s

6) ribbon 刷新时间 (客户端)


ribbon.ServerListRefreshInterval: 5000

ribbon 竟然也有缓存,默认 30s

这些超时时间相互影响,竟然三个地方都需要配置,一不小心就会出现服务不下线,服务不上线的囧境。不得不说 SpringCloud 的这套默认参数简直就是在搞笑。

重试
那么一台服务器下线,最长的不可用时间是多少呢?(即请求会落到下线的服务器上,请求失败)。赶的巧的话,这个基本时间就是 eureka.client.registryFetchIntervalSeconds+ribbon.ServerListRefreshInterval, 大约是 8秒的时间。如果算上服务端主动失效的时间,这个时间会增加到 11秒。

如果你只有两个实例,极端情况下服务上线的发现时间也需要 11 秒,那就是 22 秒的时间。

理想情况下,在这 11 秒之间,请求是失败的。假如你的 QPS 是 1000,部署了四个节点,那么在 11 秒中失败的请求数量会是 1000 / 4 * 11 = 2750,这是不可接受的。所以我们要引入重试机制。

SpringCloud 引入重试还是比较简单的。但不是配置一下就可以的,既然用了重试,那么就还需要控制超时。可以按照以下的步骤:
1) 引入 pom (千万别忘了哦)


<dependency>

<groupId>
org.springframework.retry
</groupId>

<artifactId>
spring-retry
</artifactId>

</dependency>

2) 加入配置

ribbon.OkToRetryOnAllOperations:true 
#(是否所有操作都重试,若false则仅get请求重试)
ribbon.MaxAutoRetriesNextServer:3 
#(重试负载均衡其他实例最大重试次数,不含首次实例)
ribbon.MaxAutoRetries:1
#(同一实例最大重试次数,不含首次调用)
ribbon.ReadTimeout:30000
ribbon.ConnectTimeout:3000
ribbon.retryableStatusCodes:404,500,503
#(那些状态进行重试)
spring.cloud.loadbalancer.retry.enable:true
# (重试开关)

发布系统
OK, 机制已经解释清楚,但是实践起来还是很繁杂的,让人焦躁。比如有一个服务有两个实例,我要一台一台的去发布,在发布第二台之前,起码要等上 11 秒。如果手速太快,那就是灾难。所以一个配套的发布系统是必要的。

首先可以通过 rest 请求去请求 Eureka,主动去隔离一台实例,多了这一步,可以减少至少 3 秒服务不可用的时间(还是比较划算的)。

然后通过打包工具打包,推包。依次上线替换。

市面上没有这样的持续集成工具,那么发布系统就需要定制,这也是一部分工作量。

到此,仅仅是解决了 SpringCloud 微服务平滑上下线的功能,至于灰度,又是另外一个话题了。有条件的公司选择自研还是很明智的,不至于将功能拉低到如此的水平。

不过大体不用担心,你的公司能不能活下去,还是一个未知数。Netflix 都忍了,在座的各位能比它强大么?

SpringCloud的存在是视觉污染,而你我的存在是星光点点。

可我的钱包,还是空空的。

要不要帮帮忙?

原文地址:https://blog.51cto.com/15072903/2619999

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Nacos 中的参数有很多,如:命名空间、分组名、服务名、保护阈值、服务路由类型、临时实例等,那这些参数都是什么意思?又该如何设置?接下来我们一起来盘它。 1.命名空间 在 Nacos 中通过命名空间(Namespace)+ 分组(Group)+服务名(Name)可以定位到一个唯一的服务实例。 命名
Nacos 支持两种 HTTP 服务请求,一个是 REST Template,另一个是 Feign Client。之前的文章咱们介绍过 Rest Template 的调用方式,主要是通过 Ribbon(负载均衡) + RestTemplate 实现 HTTP 服务调用的,请求的核心代码是这样的: @
Nacos 是 Spring Cloud Alibaba 中一个重要的组成部分,它提供了两个重要的功能:服务注册与发现和统一的配置中心功能。 服务注册与发现功能解决了微服务集群中,调用者和服务提供者连接管理和请求转发的功能,让程序的开发者无需过多的关注服务提供者的稳定性和健康程度以及调用地址,因为这
Spring Cloud Alibaba 是阿里巴巴提供的一站式微服务开发解决方案,目前已被 Spring Cloud 官方收录。而 Nacos 作为 Spring Cloud Alibaba 的核心组件之一,提供了两个非常重要的功能:服务注册中心(服务注册和发现)功能,和统一配置中心功能。 Nac
在 Nacos 的路由策略中有 3 个比较重要的内容:权重、保护阈值和就近访问。因为这 3 个内容都是彼此独立的,所以今天我们就单独拎出“保护阈值”来详细聊聊。 保护阈值 保护阈值(ProtectThreshold):为了防止因过多实例故障,导致所有流量全部流入剩余健康实例,继而造成流量压力将剩余健
前两天遇到了一个问题,Nacos 中的永久服务删除不了,折腾了一番,最后还是顺利解决了。以下是原因分析和解决方案,建议先收藏,以备不时之需。 临时实例和持久化实例是 Nacos 1.0.0 中新增了一个特性。临时实例和持久化实例最大的区别是健康检查的方式:临时实例使用客户端主动上报的健康检查模式,而
Spring Cloud Alibaba 技术体系中的 Nacos,提供了两个重要的功能:注册中心(服务注册与发现)功能和配置中心功能。 其中注册中心解决了微服务调用中,服务提供者和服务调用者的解耦,让程序开发者可以无需过多的关注服务提供者和调用者的运行细节,只需要通过 Nacos 的注册中心就可以
负载均衡通器常有两种实现手段,一种是服务端负载均衡器,另一种是客户端负载均衡器,而我们今天的主角 Ribbon 就属于后者——客户端负载均衡器。 服务端负载均衡器的问题是,它提供了更强的流量控制权,但无法满足不同的消费者希望使用不同负载均衡策略的需求,而使用不同负载均衡策略的场景确实是存在的,所以客
本篇文章为大家展示了如何解决Spring Cloud 服务冲突问题,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。一、背景...
本篇内容主要讲解“spring cloud服务的注册与发现怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“spri...
本篇内容介绍了“Dubbo怎么实现Spring Cloud服务治理 ”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处...
本篇内容主要讲解“SpringCloud相关面试题有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“SpringCloud相...
如何分析Spring Cloud Ribbon、Spring Cloud Feign以及断路器,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希
这篇文章主要讲解了“springcloud微服务的组成部分有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“s...
这篇文章主要讲解了“SpringCloud的OpenFeign项目怎么创建”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习...
本篇内容主要讲解“spring cloud oauth3整合JWT后获取用户信息不全怎么办”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带...
怎样解析微服务架构SpringCloud,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。...
这篇文章主要介绍spring cloud中API网关的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、服务网关简介1、外观模式客户端...
本篇内容介绍了“Spring Cloud微服务的相关问题有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处...
本文小编为大家详细介绍“spring cloud config整合gitlab如何搭建分布式的配置中心”,内容详细,步骤清晰,细节处理妥当,希望这篇“spring cloud config整合gi...