开始
Spring Boot 最新版本已经到了3.1.x版本,线上目前用的2.1版本官方已经停止支持,目前打算先做一定的技术预研,在不升级JDK的前提下,削减升级坡度,预先升级到2.7.10版本GA版本。
SpringBoot官方版本支持说明:(写这边文章时从2.7.9变成了2.7.10)
官方文档:https://spring.io/projects/spring-boot#support
官方Github Release: https://github.com/spring-projects/spring-boot/releases/tag/v2.7.10
spring cloud 版本
里面升级jar包,修复logger包的漏洞,fastjson漏洞也会随着这次升级一道修复
废话不多说,直接开始:
依赖处理与功能升级
SpringBoot主包升级
我们将springboot主包从2.1.9.RELEASE 修改为2.7.10.
org.springframework.boot
spring-boot-starter-parent
2.7.10
SpringCloud组件升级
目前Spring Cloud Alibaba 与cloud 基于spring boot 2.7.10的兼容版本
org.springframework.cloud
spring-cloud-dependencies
2021.0.5
com.alibaba.cloud
spring-cloud-alibaba-dependencies
2021.0.5.0
这时候发现SpringCloud被逼在2020版本移除了对Netflix OSS大部分组件的支持
Spring Cloud官方尤其着重指出ribbon、hystrix 和 zuul 从Spring Cloud 2020.0正式版发布后将不再被Spring Cloud支持。在目前最新的Spring Cloud 2020.0中仅仅剩下了Eureka。但是留给Eureka的时间也不多了。
其中ribbon 替换为SpringCloud LoadBalance 组件,收录在SpringCloud Commons 里面
文档如下:
参考博客:https://docs.spring.io/spring-cloud-commons/docs/current/refe...
使用上和ribbon没有什么不同,使用 @LoadBalanced 手动声明 RestTemplate Bean
@ConditionalOnMissingBean(RestTemplate.class)
@LoadBalanced
@Bean
public RestTemplate restTemplate(@Qualifier("myMappingJackson2HttpMessageConverter") MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter) {
RestTemplate restTemplate = new RestTemplate();
restTemplate.getInterceptors().add(new CoreHttpRequestInterceptor());
//RestTemplate解决Date数据类型反序列化的问题,使用自定义的MappingJackson2HttpMessageConverter覆盖
restTemplate.getMessageConverters().add(5, mappingJackson2HttpMessageConverter);
return restTemplate;
}
hystrix可以考虑使用Spring Cloud Alibaba的Sentinel做熔断和流控
下面开始做hystirx到Sentinel迁移:
首先是pom替换
com.alibaba.cloud
spring-cloud-starter-alibaba-sentinel
项目里面继续使用openfeign做rpc调用,将application.properties里面feign的熔断实现配置修改为sentinel实现。
# 去掉
# feign.hystrix.enabled: true
# 改为如下即可
feign.sentinel.enabled: true
这里故意将order服务配置错,查看rpc调用信息,可以看到使用了loadbalance 和sentinel
FeignClient基于sentinel对fallbackFactory统一降级的优化处理
由于熔断需要,业务降级时,需要手写fallback业务,但是并不是所有的RPC都需要写降级代码,所以才有了定义统一业务Reuslt返回fallback降级信息,代替框架的没有配置就throw Exception的逻辑。
之前Netflix时,是feign结合hystrix做,现在升级后,需要使用sentinel逻辑再改一遍。
参考博客:https://blog.csdn.net/qq_40592377/article/details/105142856
cloud的 openfeign和alibaba 的sentinel包里面移除了如下包依赖,彻底和hystrix告别了
io.github.openfeign
feign-hystrix
10.4.0
compile
这里是重新修改后的代码
修改处1 使用反射构造SentinelInvocationHandler是因为他不提供public构造方法
修改处2 使用了我自己定义的统一Result业务错误Result的FeignFallback。
Feign对于上游参数的透传 TODO
之前是自定义HystrixConcurrencyStrategy实现,在微服务之间RPC调用时,实现请求的业务header值,跨线程池透递
目前改用sentinel之后,还没有研究透彻,有待后续优化。
Bean循环引用的问题
重启系统,发现报错如下,因为SpringBoot 2.6开始默认禁止循环引用,这时候改业务就有麻烦,先修改为强制同意。
>
Description:
The dependencies of some of the beans in the application context form a cycle:
略
↓
sqlSessionFactory defined in class path resource [com/suike/config/database/MyBatisConfig.class]
┌─────┐
| dataSource defined in class path resource [com/suike/config/database/MyBatisConfig.class]
↑ ↓
| dataSourceDev defined in class path resource [com/suike/config/database/dataSource/DruidDBConfigDev.class]
↑ ↓
| dataSourceInitializer
└─────┘
在项目Starter文件中修改 setAllowCircularReferences(Boolean.TRUE);
public static void main(String[] args) {
log.info(">>>>>>>> steamcdk-activitys 启动开始 >>>>>>>>>");
SpringApplication application = new SpringApplication(ActivityStarter.class);
//暂时先允许循环引用,后面再清理业务。做规范
application.setAllowCircularReferences(Boolean.TRUE);
application.run(args);
log.info(">>>>>>>> steamcdk-activitys 启动完成 >>>>>>>>>");
}
参考:https://blog.csdn.net/Dug_Zhang/article/details/122225331
依赖组件Nacos Server版本升级
重启项目,再次报错:
ErrCode:-401, ErrMsg:Client not connected,current status:STARTING
询问度娘得知,Alibaba2.2.7中nacos client 依赖的server 必须也是2.x 以上,而我这边项目之前用的是nacos-servcer-1.4.1
没辙,去nacos官方查1.x升级2.x升级文档:
nacos git地址: https://github.com/alibaba/nacos/releases
nacos2.0升级文档: https://nacos.io/zh-cn/docs/2.0.0-upgrading.html
覆盖文件,然后修改下配置就好了,双写先开着,老系统还在用。
ErrCode:-400, ErrMsg:Could not initialize class com.alibaba.nacos.common.remote.client.grpc.GrpcSdkClient
nacos 升级成2.2.0 ,以下是alibaba 官方版本匹配
Springfox 升级为Springdoc
网上说如果要继续用Springfox,只需要加一段配置
spring.mvc.pathmatch.matching-strategy=ant_path_matcher
但是后面肯定还会有兼容性问题,再次求助得知:Spring基于Swagger3自己做了一套基于openapi3规范的文档项目,叫springDoc.
参考:https://zhuanlan.zhihu.com/p/439255980
忙活了半天,还是决定替换成SpringDoc,首先是springfox 已经很久没有更新了
其实,改版后发现Springdoc 确实做的比springfox更适合spring体系。
文档地址:https://springdoc.org/#demos
替换注解,重写OpenAPI的配置文件,参考文档,成功平滑替换
Redis线程池改动
特别注意,spring date redis 依赖的commons-pool2 2.9.0会报错,需要另外声明为最新
org.apache.commons
commons-pool2
2.11.1
在Springboot 2x以后,底层访问redis已经不再是jedis了,而是lettuce
这边配置修改为使用lettuce链接池
MYSQL连接器 版本升级
MySQL的链接驱动, 从 8.0.31 开始,从原来的 mysql:mysql-connector-java 改为 com.mysql:mysql-connector-j
网关中,关于exclude Url匹配规则升级
> org.springframework.web.util.pattern.PatternParseException: No more pattern data allowed after {*...} or ** pattern element
错误直观展示是路径统配问题,可是之前没有问题啊,后来经过一通查找发现是spring升级到5.3之后路径统配发生了变化,官方给出的解释是“In Spring MVC, the path was previously analyzed by AntPathMatcher, but it was changed to use PathPatternParser introduced in WebFlux from Spring 5.3.0.”。
2、具体解决是把/**/*.html 改为 /*/*.html
,项目中可能涉及多个文件,都要改:
OK,修改完重启。不出所料再次遇到问题
网关使用Loadbalancer代替Ribbon实现负载均衡
访问服务网关进行路由时,找不到服务
gateway配置一切正常,鉴权也没有问题,nacos也正常注册,但是路由的时候就是找不到服务
解决方法:在pom.xml文件中添加如下依赖:
org.springframework.cloud
spring-cloud-starter-loadbalancer
原因:由于springcloud2020弃用了Ribbon,因此Alibaba在2021版本nacos中删除了Ribbon的jar包,因此无法通过lb路由到指定微服务,出现了503情况。
所以只需要引入springcloud loadbalancer包即可
fastJson严重漏洞,升级为1.2.83版本
项目启动时,加入如下代码
/*
* Fastjson存在远程代码执行漏洞 升级到最新版本1.2.83 打开autotype功能
* @see https://github.com/alibaba/fastjson/wiki/enable_autotype
*/
ParserConfig.getGlobalInstance().addDeny("com.rush.gameup");
非必须升级
Mybatis-plus从3.2升级到3.5
mybatis-plus可以说是用lambda语法写sql,体感非常丝滑。
在3.5中,主要改动是代码生成器的api升级,变得更强大了。
这里我通过mybatis-generator生成时指定我抽象出的一套扩展父类,可以加快不少开发速度
更进阶的话,手挫 100% 契合自己业务的vm、ftl模板,想象空间很大。
也可以体验下@EnumValue,@TableLogic的“花活”。
文档地址 https://baomidou.com/pages/24112f/
Gateway使用knife4j聚合swagger文档并优化ui
升级后的spring doc的UI美观了一些
但是现在有一个国人开源的更强大的UI插件:knife4j
界面效果如下图,下拉框里会列出nacos里面注册的所有服务,knife4j会自动装配进来,选中即可查看文档
com.github.xiaoymin
knife4j-gateway-spring-boot-starter
4.1.0
最新4.1版本Gateway只需要如下的简单配置,就可以自动注册和聚合所有微服务的swagger文档,比我之前手动写个聚合页使用体验要强上许多。
knife4j:
gateway:
# 指定服务发现的模式聚合微服务文档,并且是默认`default`分组
strategy: discover
discover:
# 指定版本号(Swagger2|OpenAPI3)
version: openapi3
enabled: true
enabled: true
参考文档:https://doc.xiaominfo.com/docs/changelog/x/4.1