本系列示例与胶水代码地址: https://github.com/HashZhang/spring-cloud-scaffold
Spring Cloud还是比较活跃的,更新一直很快。我一般考虑最新版本SR2发布之后,再考虑升级(一般SR1还有SR2会有一些新老框架的兼容性升级)。而且由于需要我们线上稳定,结合我们的发布周期来看,跳一个大版本升级是一个更好的选择(也就是一年做一次大版本升级)。例如我们之前的升级路线就是:Brixton -> Daltson -> Finchley -> 当前的Hoxton
做了这么多次升级,感觉可以出这个系列,来分享我们项目使用Spring cloud
框架实现的框架功能,在升级中遇到的坑,以及如何升级等等。每个版本都会有实例代码,并在上一版本实现的功能基础上,实现更多更实用的功能。所有示例代码都在开头提到的项目中,每个版本系列的最后,还会附上功能测试流程。
在Hoxton版本Release的同时,Spring Cloud也宣布,其中的这些项目,已经进入维护模式(不再开发新功能),用户最好做如下的替换:
- Spring Cloud Netflix Ribbon -> Spring Cloud Load Balancer
- Spring Cloud NetFlix Zuul -> Spring Cloud Gateway
- Spring Cloud Hystrix -> Spring Cloud Circuit Breaker Resilience4J
- Spring Cloud Netflix Turbine -> Micrometer Promethus
- Spring Cloud Netflix Archaius -> Spring Cloud Config Server
可以看出,Spring Cloud netflix中的zuul, ribbon, hystrix都基本上算是废了,我们也可以抛弃掉Sprnig Cloud Netflix了。还有一个体系也在官方中,就是Spring Cloud Alibaba,但是通过Spring Cloud netflix这件事,我个人感觉这种依赖性质的胶水项目,最好还是我们架构组自己维护,这块是比较容易有坑的,自己维护自己用更新起来更高效,而且不会有粘合的项目都不更新了替换起来要人命的代价。
Spring Cloud Hoxton,至少对于官方文档来说,是一个里程碑式的变化。官方文档终于将所有项目的文档分开了,并且做了比较多的整理,可以看出,这个Hoxton一定是有人下定决心要做一个变革了。并且,Spring Cloud在这个版本引入了更多的虚拟化,云原生依赖,例如Spring-Cloud-kubernetes,确实,有些服务发现,调用策略什么的,Spring Cloud和k8s体系重复了,这个依赖可以使我们灵活地切换这些功能到底交给谁来做,期待这个项目的完善成熟。
这篇文章,会主要列出升级步骤与详细说明,以及对应的源代码,和实现的功能。以及如何替换Spring Cloud Netflix体系为新的组件。
原有的功能以及之前的实现
1. 微服务
以前的体系:
- 注册中心:Eureka
- 客户端封装:OpenFeign
- 客户端负载均衡:Ribbon
- 断路器与隔离: Hystrix
实现的功能:
- 所有集群公用同一个公共Eureka集群,集群之间不互相调用,通过实例的
metamap
中的zone
配置,来区分不同集群的实例。之前通过Ribbon
的配置ServerListFilter
实现,使用com.netflix.loadbalancer.ZoneAffinityServerListFilter
作为ServerListFilter
,参考:Spring cloud实现FeignClient指定Zone调用 - 微服务之间调用,有重试,只对GET请求进行重试,连接超时,读取超时还有 4xx 和 5xx 的状态码都会重试。这个之前是通过加入
spring-retry
重试通过ribbon配置实现的。参考:Spring Cloud Finchley OpenFeign的重试配置相关的坑 - 微服务调用有线程隔离,例如微服务1调用微服务2和微服务3,调用微服务2的线程和微服务3的线程不一样。之前是通过
Hystrix
配置实现hystrix.threadpool.default.coreSize=50
- 实现了实例级别的熔断,而不是微服务级别的。当调用微服务的两个实例的时候,当一个实例一直异常,则将这个实例断路器打开一段时间,而不是整个微服务都不能工作。之前通过
Ribbon
的配置LoadBalancerRule
实现,使用com.netflix.loadbalancer.AvailabilityFilteringRule
作为LoadBalancerRule
。参考:Ribbon的AvailabilityFilteringRule的坑
2. 网关
以前的体系:
- API网关:Zuul
实现的功能:
- 重试,只对GET请求进行重试,连接超时,读取超时还有 4xx 和 5xx 的状态码都会重试。这个之前是通过加入
spring-retry
重试通过ribbon配置实现的。 - 微服务调用有线程隔离,例如微服务1调用微服务2和微服务3,调用微服务2的线程和微服务3的线程不一样。之前是通过
Hystrix
配置实现hystrix.threadpool.default.coreSize=50
- 实现了实例级别的熔断,而不是微服务级别的。当调用微服务的两个实例的时候,当一个实例一直异常,则将这个实例断路器打开一段时间,而不是整个微服务都不能工作。之前通过
Ribbon
的配置LoadBalancerRule
实现,使用com.netflix.loadbalancer.AvailabilityFilteringRule
作为LoadBalancerRule
。参考:Ribbon的AvailabilityFilteringRule的坑 - 特定接口 request body 解密与特定接口 response body 的加密。
3. Eureka-Server
实现的功能:
- 实例的快速上线下线,参考:Eureka 服务实例实现快速下线快速感知快速刷新配置解析
现在要实现的功能
1. 微服务
- 微服务之间调用依然基于利用 open-feign 的方式,有重试,仅对GET请求并且状态码为4xx和5xx进行重试(对4xx重试是因为滚动升级的时候,老的实例没有新的 api,重试可以将请求发到新的实例上)
- 某个微服务调用其他的微服务 A 和微服务 B, 调用 A 和调用 B 的线程池不一样。并且调用不同实例的线程池也不一样。也就是实例级别的线程隔离
- 实现实例级别的熔断。
- 使用 zone 隔离,不同 zone 之间不能互相调用
- 负载均衡的轮询算法,需要请求与请求之间隔离,不能共用同一个 position 导致某个请求失败之后的重试还是原来失败的实例
2. 网关
- 转发请求,有重试,仅对GET请求并且状态码为4xx和5xx进行重试
- 不同微服务的不同实例线程隔离
- 实现实例级别的熔断。
- 使用 zone 隔离,仅转发请求到同 zone 的实例
- 负载均衡的轮询算法,需要请求与请求之间隔离,不能共用同一个 position 导致某个请求失败之后的重试还是原来失败的实例
3. Eureka
- 实现服务实例快速上下线
新的pom依赖
1. 微服务
代码语言:javascript复制 org.springframework.boot
spring-boot-starter-parent
2.2.7.RELEASE
3.4.2
1.1.0
com.github.ben-manes.caffeine
caffeine
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-logging
org.springframework.boot
spring-boot-starter-log4j2
org.projectlombok
lombok
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.cloud
spring-cloud-starter-openfeign
org.springframework.cloud
spring-cloud-starter-sleuth
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-tomcat
org.springframework.boot
spring-boot-starter-undertow
org.apache.httpcomponents
httpclient
io.github.resilience4j
resilience4j-spring-cloud2
${resilience4j-spring-cloud2.version}
com.lmax
disruptor
${disruptor.version}
org.springframework.cloud
spring-cloud-dependencies
Hoxton.SR4
pom
import
org.apache.maven.plugins
maven-compiler-plugin
3.6.1
11
11
2. 网关
代码语言:javascript复制 org.springframework.boot
spring-boot-starter-parent
2.2.7.RELEASE
3.4.2
1.1.0
com.github.ben-manes.caffeine
caffeine
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-logging
org.springframework.boot
spring-boot-starter-log4j2
org.projectlombok
lombok
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.cloud
spring-cloud-starter-gateway
org.springframework.cloud
spring-cloud-starter-sleuth
org.springframework.boot
spring-boot-starter-actuator
io.github.resilience4j
resilience4j-spring-cloud2
${resilience4j-spring-cloud2.version}
org.springframework.cloud
spring-cloud-starter-circuitbreaker-reactor-resilience4j
com.lmax
disruptor
${disruptor.version}
org.apache.maven.plugins
maven-compiler-plugin
3.6.1
11
11
org.springframework.cloud
spring-cloud-dependencies
Hoxton.SR4
pom
import
3. Eureka-Server
代码语言:javascript复制 org.springframework.boot
spring-boot-starter-parent
2.2.7.RELEASE
3.4.2
com.github.ben-manes.caffeine
caffeine
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-logging
org.springframework.boot
spring-boot-starter-log4j2
org.projectlombok
lombok
org.springframework.cloud
spring-cloud-starter-netflix-eureka-server
org.springframework.cloud
spring-cloud-starter-sleuth
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-tomcat
org.springframework.boot
spring-boot-starter-undertow
com.lmax
disruptor
${disruptor.version}
org.springframework.cloud
spring-cloud-dependencies
Hoxton.SR4
pom
import
org.apache.maven.plugins
maven-compiler-plugin
3.6.1
11
11