IT博文
MySQL 事务隔离级别详解
使用 docker compose 安装 tidb
架构师日记-如何写的一手好代码
生产事故-记一次特殊的OOM排查
Docker安装RabbitMQ——基于docker-compose工具
使用 docker-compose 部署单机 RabbitMQ
只需3步,即刻体验Oracle Database 23c
长达 1.7 万字的 explain 关键字指南!
Redis为什么能抗住10万并发?揭秘性能优越的背后原因
深度剖析Redis九种数据结构实现原理
【绩效季】遇到一个好领导有多重要,从被打差绩效到收获成长
为什么Redis不直接使用C语言的字符串?
Java阻塞队列中的异类,SynchronousQueue底层实现原理剖析
如何调整和优化 Go 程序的内存管理方式?
应用部署引起上游服务抖动问题分析及优化实践方案
Java 并发工具合集 JUC 大爆发!!!
卷起来!!这才是 MySQL 事务 & MVCC 的真相。
JDK8 到 JDK17 有哪些吸引人的新特性?
告别StringUtil:使用Java 11的全新String API优化你的代码
从JDK8飞升到JDK17,再到未来的JDK21
Java JMH Benchmark Tutorial
linux和macOS下top命令区别
Windows10关闭Hyper-V的三种方法
为什么应该选择 POSTGRES?
阿里云对象存储 OSS 限流超过阈值自动关闭【防破产,保平安】
Java高并发革命!JDK19新特性——虚拟线程(Virtual Threads)
“请不要在虚拟机中运行此程序”的解决方案
Spring中的循环依赖及解决
浅谈复杂业务系统的架构设计 | 京东云技术团队
面试题:聊聊TCP的粘包、拆包以及解决方案
操作日志记录实现方式
字节跳动技术团队-慢 SQL 分析与优化
Spring Boot 使用 AOP 防止重复提交
Controller层代码就该这么写,简洁又优雅!
SpringBoot 项目 + JWT 完成用户登录、注册、鉴权
重复提交不再是问题!SpringBoot自定义注解+AOP巧妙解决
SpringBoot 整合 ES 实现 CRUD 操作
SpringBoot 整合 ES 进行各种高级查询搜索
SpringBoot操作ES进行各种高级查询
SpringBoot整合ES查询
如何做架构设计? | 京东云技术团队
最值得推荐的五个VPN软件(便宜+好用+稳定),靠谱的V2ray梯子工具
我说MySQL每张表最好不超过2000万数据,面试官让我回去等通知?
vivo 自研鲁班分布式 ID 服务实践
使用自带zookeeper超简单安装kafka
推荐 6 个很牛的 IDEA 插件
喜马拉雅 Redis 与 Pika 缓存使用军规
「程序员转型技术管理」必修的 10 个能力提升方向
jdk17 下 netty 导致堆内存疯涨原因排查 | 京东云技术团队
如何优雅做好项目管理?
MySQL 到 TiDB:Hive Metastore 横向扩展之路
聊聊即将到来的 MySQL5.7 停服事件
Linux终端环境配置
微软 Edge 浏览器隐藏功能一览:多线程下载、IE 模式、阻止视频自动播放等
Hutool 中那些常用的工具类和实用方法
clash 内核删库?汇总目前常用的内核仓库和客户端
JDK11 升级 JDK17 最全实践干货来了 | 京东云技术团队
我是如何写一篇技术文的?
虚拟线程原理及性能分析
Java线程池实现原理及其在美团业务中的实践
Editplus和EmEditor配置一键编译java运行环境
用Spring Boot 3.2虚拟线程搭建静态文件服务器有多快?
SpringBoot中使用LocalDateTime踩坑记录 - 程序员偏安 - 博客园
程序员必备!10款实用便捷的Git可视化管理工具 - 追逐时光者 - 博客园
基于Netty开发轻量级RPC框架
开发Java应用时如何用好Log
复杂SQL治理实践 | 京东物流技术团队
火山引擎ByteHouse:分析型数据库如何设计并发控制?
多次崩了之后,阿里云终于改了
推荐程序员必知的四大神级学习网站
初探分布式链路追踪
新项目为什么决定用 JDK 17了
Java上进了,JDK21 要来了,并发编程再也不是噩梦了
mapstruct这么用,同事也开始模仿
再见RestTemplate,Spring 6.1新特性:RestClient 了解一下!
【MySQL】MySQL表设计的经验(建议收藏)
如何正确地理解应用架构并开发
解读工行专利CN112905176B
工商银行取得「基于 Spring Boot 的 web 系统后端实现方法及装置」专利
IDEA 2024.1:Spring支持增强、GitHub Action支持增强、更新HTTP Client等
TIOBE 2 月:Go 首次进入前十、“上古语言” COBOL 和 Fortran 排名飙升
Java 21 虚拟线程如何限流控制吞吐量
🎉 通用、灵活、高性能分布式 ID 生成器 | CosId 2.6.6 发布
20年编程,AI编程6个月,关于Copliot辅助编码工具,你想知道的都在这里
Java 8 内存管理原理解析及内存故障排查实践
消息队列选型之 Kafka vs RabbitMQ
从 MongoDB 到 PostgreSQL 的大迁移
腾讯云4月8日故障复盘及情况说明
PHP 在 2024 年还值得学习吗?
AMD集显安装显卡驱动之后出现黑屏,建议这样解决
使用 Docker 部署 moments 微信朋友圈 - 谱次· - 博客园
Java 17 是最常用的 Java LTS 版本
盘点Lombok的几个骚操作
Llama 3 + Ollama + Open WebUI打造本机强大GPT
如何优雅地编写缓存代码
Gmeek快速上手
笔记软件思源远程和本地接入大语言模型服务Ollama实现AI辅助写作(Windows篇)
Git Subtree:简单粗暴的多项目管理神器
这款轻量级规则引擎,真香!!
Ollama教程:本地LLM管理、WebUI对话、Python/Java客户端API应用
GLM-4-9B支持 Ollama 部署
智谱AI开源代码生成大模型第四代版本:CodeGeeX4-ALL-9B
美团二面:如何保证Redis与Mysql双写一致性?连续两个面试问到了!
免费开源好用,Obsidian和Omnivore真正实现一键联动剪藏文章,手把手教程!
得物 Redis 设计与实践
架构图怎么画?手把手教您,以生鲜电商为例剖析业务/应用/数据/技术架构图
使用Hutool要注意了!升级到6.0后你调用的所有方法都将报错 - 掘金
别再用雪花算法生成ID了!试试这个吧
无敌的Arthas!
Navicat Premium v16、v17 破解激活
🎉 分布式接口文档聚合,Solon 是怎么做的?
深入体验全新 Cursor AI IDE 后,说杀疯了真不为过!
Nacos 3.0 架构全景解读,AI 时代服务注册中心的演进
本文档使用 MrDoc 发布
-
+
JDK11 升级 JDK17 最全实践干货来了 | 京东云技术团队
# **1、前言** 上篇文章给大家带来了 [JDK8 升级 JDK11 的最全实践,](https://my.oschina.net/u/4090830/blog/10111749)相信大家阅读后已经对 JDK11 有了比较深入的了解。2021 年 9 月 14 日,Oracle 发布了可以长期支持的 JDK17 版本,那么从 JDK11 到 JDK17,到底带来了哪些特性呢?亚毫秒级的 ZGC 效果到底怎么样呢?值得我们升级吗?而且升级过程会遇到哪些问题呢?带着这些问题,本篇文章将带来完整的 JDK11 升级 JDK17 最全实践。 # **2、为什么升级 JDK17** **1)长期支持版本** JDK17 是 Oracle 官方在 2021 年 9 月 14 日发布的一个长期支持(LTS)版本,意味着它将获得长期的更新和支持,有助于保持程序的稳定性和可靠性。 **2)性能提升** 更好的垃圾回收器。综合评估,从 Java 8 升级到 Java 11,\*\*G1GC 平均速度提升 16.1%,ParallelGC 为 4.5%\*\*\*\*,\*\* 从 Java 11 升级到 Java 17,**G1GC 平均速度提升 8.66%,ParallelGC 为 6.54%**([基于 OptaPlanner 的用例基准测试表明)](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fwww.optaplanner.org%2Fblog%2F2021%2F09%2F15%2FHowMuchFasterIsJava17.html) 最大的亮点是带来了**稳定版的 ZGC 垃圾回收器,达到亚毫秒级停顿。** **3)新语法和特性** Switch 表达式简化、Text Blocks 文本块、instanceof 的模式匹配升级和 NullPointerException 提示信息改进等 4)**支持最新的技术和框架** Spring framework6 和 Spring Boot3 都默认使用 Java 17 作为最低版本 # **3、升级后压测效果** > **先给出结论:** > > 1、JDK17 相对于 JDK8 和 JDK11,**所有垃圾回收器的性能都有很明显的提升,特别是稳定版的 ZGC 垃圾回收器** > > 2、**不论任何机器配置下,都推荐使用 ZGC**,ZGC 的停顿时间达到亚毫秒级,吞吐量也比较高 **我在 JDOS 平台上选择了不同配置的机器(2C4G、4C8G、8C16G),并分别使用 JDK8、JDK11 和 JDK17 进行部署和压测。** 整个压测过程限时 60 分钟,用 180 个虚拟用户并发请求一个接口,每次接口请求都创建 512Kb 的数据。最终产出不同 GC 回收器的各项指标数据,来分析 GC 的性能提升效果。 **以下是压测的性能情况:**  # **4、OracleJDK 和 OpenJDK 的选择** 2021 年 9 月,Oracle 宣布 JDK17 可以免费商用,直到下一个 LTS 版本之后继续提供整整一年,同时 Oracle 将继续按照自 Java 9 以来的相同版本和时间表提供 GPL 下的 Oracle OpenJDK 版本。 2023 年 9 月,OracleJDK 发布了新的 LTS 版本 JDK21,这就意味着从 **2024 年 9 月开始,在生产环境使用 OracleJDK17 将需要付费。**  参考: [https://www.oracle.com/hk/java/technologies/downloads/#java17](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fwww.oracle.com%2Fhk%2Fjava%2Ftechnologies%2Fdownloads%2F%23java17) OracleJDK 和 OpenJDK 这两个之间没有真正的技术差别,因为针对 Oracle JDK 构建过程是基于 OpenJDK 的。自从 JDK11 开始,OracleJDK 和 OpenJDK 在功能上基本相同,所以推荐使用 [OpenJDK17](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fjdk.java.net%2Farchive%2F) 或其他开源的 JDK 版本,这些开源版本都是基于 OpenJDK 构建并提供长期支持的,比如:[AdoptOpenJDK](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fadoptopenjdk.net%2F)、[RedHatOpenJDK。](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fdevelopers.redhat.com%2Fproducts%2Fopenjdk%2Foverview)  官方参考: [https://blogs.oracle.com/java/post/oracle-jdk-releases-for-java-11-and-later](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fblogs.oracle.com%2Fjava%2Fpost%2Foracle-jdk-releases-for-java-11-and-later) # **5、JDK11 到 JDK17 带来了哪些新特性** ### **5.1、JVM 改进** 1、ZGC 垃圾回收器从实验性功能更改为**正式产品功能**,从 JDK11 引入以来,经过持续的迭代升级,目前已经足够稳定。**需要手动开启,开启方式:-XX:+UseZGC** 2、G1 垃圾回收器仍然作为默认垃圾回收器,进行改进升级,主要包括可中止的混合收集集合、NUMA 可识别内存分配等 3、JDK14 开始删除 CMS 垃圾回收器 4、JDK14 开始弃用 ParallelScavenge 和 SerialOld GC 的组合使用 5、JDK15 禁用偏向锁,默认禁用:-XX:+UseBiasedLocking 6、NullPointerException 提示信息改进 JDK14 以前的出现 NullPointerException 时,只能定位到所在异常行,无法定位具体是哪个变量。改进后的 NullPointerException,可以清晰描述具体变量,提升了空指针异常的可读性。  ### **5.2、新语法特性** #### **5.2.1、Switch 表达式简化** switch 表达式带来了简化式的编码方式,提供了新的分支切换方式,即 -> 符号,右则表达式方法体在执行完分支方法之后,自动结束 switch 分支,同时 -> 右则方法块中可以是表达式、代码块或者是手动抛出的异常 参考: [https://openjdk.org/jeps/361](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fopenjdk.org%2Fjeps%2F361) **传统写法**  **新写法**  #### **5.2.2、Text Blocks 文本块** 参考: [https://openjdk.org/jeps/378](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fopenjdk.org%2Fjeps%2F378) 通过编写 """,来减少转义字符和换行符,达到简化代码和提高代码可读性的目的  #### **5.2.3、Record 类型** 参考: [https://openjdk.org/jeps/395](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fopenjdk.org%2Fjeps%2F395) record 是 JDK 14 引入的关键字,用于声明不可变的数据类。它适用于存储纯粹的值类型数据,如接口传输数据、坐标点和只读的日志记录。与 lombok 相比,record 简化了定义纯粹数据类型的过程。由于 record 类是不可变的,成员变量只能设置一次且无法更改,无需提供显式的 setter () 方法。 **1、定义 Point 类,使用关键字 record,未定义 get/set**  **2、查看编译后的字节码文件**   **3、使用 Point 类**  #### **5.2.4、instanceof 的模式匹配升级** - instanceof 类型判断再也不需要强制转换 参考: [https://openjdk.org/jeps/394](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fopenjdk.org%2Fjeps%2F394)  #### **5.2.5、密封的类和接口** 参考: [https://openjdk.org/jeps/409](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fopenjdk.org%2Fjeps%2F409) JDK15 开始,引入了 sealed 普通类或接口类,这些类只允许被指定的类或者 interface 进行扩展和实现。 使用修饰符 sealed,您可以将一个类声明为密封类。密封的类使用关键字 permits 列出可以直接扩展它的类。子类可以是最终的,非密封的或密封的 比较实用的一个特性,可以用来限制类的层次结构  #### **5.2.6、其他优化和升级** 感兴趣的同学,推荐阅读 OpenJDK 官方文档说明,从 JDK11 到 JDK17 的改动: [https://openjdk.org/projects/jdk/17/jeps-since-jdk-11](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fopenjdk.org%2Fprojects%2Fjdk%2F17%2Fjeps-since-jdk-11) # **6、升级步骤** ### **6.1、JDK 选择** OpenJDK17 下载:[https://jdk.java.net/archive/](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fjdk.java.net%2Farchive%2F) 行云镜像:jdt-base-tomcat/java-jdt-centos7.4-openjdk-17.0.2-tomcat8.0.53 ### **6.2、pom 编译配置升级** maven 编译所需 JDK 升级至 17 ``` <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> </properties> ``` ### **6.3、SpringBoot 升级** SpringBoot 版本升级到 **2.7.15**,Spring 版本升级为 **5.3.29** **为什么不升级到 SpringBoot3?** Spring Boot 3.0 最低要求 Java 17,SpringBoot3.0 带来了很多变化,和 SpringBoot2 差异较大。 考虑到公司很多中间件都是基于 SpringBoot2 构建的,所以此处推荐升级到 SpringBoot2 的最高版本 2.7.15。 **POM 升级** ``` <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.15</version> </parent> ``` 也可以通过设置 dependencyManagement 的方式: ``` <properties> <!-- 框架版本配置--> <springboot-version>2.7.15</springboot-version> <springframework.version>5.3.29</springframework.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>${springboot-version}</version> <scope>import</scope> <type>pom</type> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-framework-bom</artifactId> <version>${springframework.version}</version> <scope>import</scope> <type>pom</type> </dependency> </dependencies> </dependencyManagement> ``` 参考: spring 升级指南: [https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fgithub.com%2Fspring-projects%2Fspring-framework%2Fwiki%2FSpring-Framework-Versions) springboot 版本官网: [https://spring.io/projects/spring-boot#learn](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fspring.io%2Fprojects%2Fspring-boot%23learn) **循环依赖问题** SpringBoot 升级到 2.7.15 后,如果应用中存在循环依赖的问题,启动时会报如下错误:  **原因**:官方文档不鼓励循环依赖引用,默认情况下是禁止的 **解决方案:** 第一种:推荐更新应用中 bean 的依赖关系来解决 第二种:配置文件中加入以下配置,**为了和旧版本保持一致,此配置推荐添加** ``` #放开循环依赖 spring.main.allow-circular-references=true ``` ### **6.4、常用中间件升级** #### **6.4.1、Lombok 版本升级到 1.18.20 以上** ``` <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> </dependency> ``` 如果不升级,编译时会报错如下:  #### **6.4.2、swgger 问题,springfox3.0.0 和 springboot2.7 版本不兼容** **异常:** ``` Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException: Cannot invoke "org.springframework.web.servlet.mvc.condition.PatternsRequestCondition.getPatterns()" because "this.condition" is null ``` **解决方案:** ``` /** * 增加如下配置可解决Spring Boot 2.7.15 与Swagger 3.0.0 不兼容问题 **/ @Bean public BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() { return new BeanPostProcessor() { @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) { customizeSpringfoxHandlerMappings(getHandlerMappings(bean)); } return bean; } private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) { List<T> copy = mappings.stream().filter(mapping -> mapping.getPatternParser() == null).collect(Collectors.toList()); mappings.clear(); mappings.addAll(copy); } @SuppressWarnings("unchecked") private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) { try { Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings"); field.setAccessible(true); return (List<RequestMappingInfoHandlerMapping>) field.get(bean); } catch (IllegalArgumentException | IllegalAccessException e) { throw new IllegalStateException(e); } } }; } ``` 参考:[https://developer.aliyun.com/article/950787](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fdeveloper.aliyun.com%2Farticle%2F950787) #### **6.4.3、AKS 升级(针对直接从 JDK8 升级的情况)** **异常**:Causedby: java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException **原因**:Java11 删除了 Java EE modules,其中就包括 java.xml.bind (JAXB)。 **解决方案:** 手动引入如下包即可 ``` <!-- API, java.xml.bind module --> <dependency> <groupId>jakarta.xml.bind</groupId> <artifactId>jakarta.xml.bind-api</artifactId> <version>2.3.2</version> </dependency> <!-- Runtime, com.sun.xml.bind module --> <dependency> <groupId>org.glassfish.jaxb</groupId> <artifactId>jaxb-runtime</artifactId> <version>2.3.2</version> </dependency> ``` #### **6.4.4、Concrete 配置中心阻塞升级** 使用 Concrete 时,启动时异常: ``` Unable to make field private static final java.lang.reflect.Method jdk.proxy2.$Proxy97.m0 accessible: module jdk.proxy2 does not "opens jdk.proxy2" to unnamed module @61d47554 ``` **原因:** 分析下 Concrete 报错的原因,如下图,包内 com.wangyin.concrete.spring.ConcreteConfigProcessor#postProcessAfterInitialization(212 行)的实现逻辑   **解决方案:** 1、在 JVM 启动参数中设置 --add-opens jdk.proxy2 来开启私有字段的访问,但因为动态代理生成的包名是随机不明确的,**所以这种方案不可行**。JDK 官方文档也明确表示不支持访问动态代理内部的随机字段。官方说明:[https://cr.openjdk.org/~mr/jigsaw/spec/api/java/lang/reflect/Proxy.html](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fcr.openjdk.org%2F%7Emr%2Fjigsaw%2Fspec%2Fapi%2Fjava%2Flang%2Freflect%2FProxy.html) 2、代码修改,只需把 f.setAccessible (true) 移到 Modifier.isStatic (f.getModifiers ()) 的判断下方即可。原因是方法 Modifier.isStatic (f.getModifiers ()) 本来就要跳过静态字段,这样修改直接避免了访问。**推动 concrete 团队修复问题或更换使用 Ducc 配置中心** ### **6.5、JVM 启动参数配置** #### **6.5.1、开启 ZGC** **启动参数中配置:**\-XX:+UseZGC 移除 - XX:ConcGCThreads,行云部署下 JVM 参数配置需要清除  #### **6.5.2、不同中间件所需启动参数** 升级 JDK17 后,项目启动时可能会遇到如下两种类型的异常: 1、cannot access class sun.util.calendar.ZoneInfo (in module java.base) because **module java.base** does not **export sun.util.calendar** to unnamed module @0x2611f533 2、Unable to make field final int java.math.BigInteger.signum accessible: **module java.base** does not "**opens java.math**" to unnamed module @525f1e4e **异常原因:** 自从 JDK9 中引入了模块化功能后,再到 JDK17,对于包扫描和反射的权限控制更加的严格。常见的库比如(Spring)大量用到包扫描和反射,所以常出现此错误。 **解决方案:** 一个粗暴的解决办法是将没开放的 module 强制对外开放,即保持和 Java9 之前的版本一致。 - \--add-exports 导出包,意味着其中的所有公共类型和成员都可以在编译和运行时访问。 - \--add-opens 打开包,意味着其中的所有类型和成员(不仅是公共类型)都可以在运行时访问。 主要区别在于 `--add-opens` 允许 “深度反射”,即非公共成员的访问,才可以调用 `setAccessible(true)` 参考: [https://stackoverflow.com/questions/44056405/whats-the-difference-between-add-exports-and-add-opens-in-java-9](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fstackoverflow.com%2Fquestions%2F44056405%2Fwhats-the-difference-between-add-exports-and-add-opens-in-java-9) **SGM 需要加入:** ``` --add-opens java.management/java.lang.management=ALL-UNNAMED --add-opens jdk.management/com.sun.management.internal=ALL-UNNAMED --add-opens java.management/sun.management=ALL-UNNAMED ``` **R2M 需要加入:** ``` --add-opens java.base/java.time=ALL-UNNAMED ``` **Ducc 需要加入:** ``` --add-opens java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.concurrent.locks=ALL-UNNAMED --add-opens java.base/java.security=ALL-UNNAMED --add-opens java.base/jdk.internal.loader=ALL-UNNAMED --add-opens java.management/com.sun.jmx.mbeanserver=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED ``` **AKS 需要加入:** ``` --add-exports java.base/sun.security.action=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.math=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/sun.util.calendar=ALL-UNNAMED ``` ### **6.6、启动后的验证** 1\. 推荐先升级 JDK11,再到 JDK17,一边升级一边进行验证观察 2\. 观察日志是否有异常,特别是上面说到的启动时异常 3\. 观察监控类软件,比如 SGM、UMP 等监控是否正常 4\. 推荐逐步有序切量,并做好常态化压测,防止影响核心业务 5\. 升级完成后,**最好能做个全流程的功能测试,防止功能异常** # **7、总结** > 1、升级后,除了可以使用新的语法特性,最大的亮点是可以使用亚毫秒级停顿的 GC 性能(至少百倍的 GC 性能提升),所以 **强烈建议升级到 JDK17** > > 2、整个升级过程并不复杂,主要涉及到中间件版本的升级和启动参数的配置 如果还停留在 JDK8,推荐先升级 JDK11,再到 JDK17,具体升级步骤先参考我的上篇文章 “[JDK8 升级 JDK11 最全实践干货来了](https://my.oschina.net/u/4090830/blog/10111749)”,再参考本章中的升级步骤。 希望以上分享可以给大家带来实际的帮助,升级过程中如果遇到问题,欢迎大家在评论区回复。 > 作者:京东科技 曲振富 > > 来源:京东云开发者社区 转载请注明来源
admin
2023年11月14日 21:00
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
PDF文档(打印)
分享
链接
类型
密码
更新密码