上云无忧 > 文档中心 > 腾讯云弹性微服务 TEM 实战教程 - Java 应用调优最佳实践
弹性微服务 TEM
腾讯云弹性微服务 TEM 实战教程 - Java 应用调优最佳实践

文档简介:
优化容器镜像: 通过优化容器镜像,您可以缩短加载时间和启动时间。您可以通过以下方式优化镜像: 尽可能减小化容器镜像大小 避免使用嵌套 jar 包 使用弹性微服务 Jar / War 方式部署
*此产品及展示信息均由腾讯云官方提供。免费试用 咨询热线:400-826-7010,为您提供专业的售前咨询,让您快速了解云产品,助您轻松上云! 微信咨询
  免费试用、价格特惠

优化容器镜像

通过优化容器镜像,您可以缩短加载时间和启动时间。您可以通过以下方式优化镜像:
尽可能减小化容器镜像大小
避免使用嵌套 jar 包
使用弹性微服务 Jar / War 方式部署
弹性微服务 Jar / War 方式部署默认提供 Jar 包镜像构建的最佳实践,弹性微服务默认提供能充分利用构建缓存的构建流程,使用新一代构建利器 Buildkit 进行高速构建,构建速度优化50%以上,并且整个构建流程可追溯,构建日志可查,简单高效。

设置应用加速

使用弹性微服务 Jar / War 方式部署,并选择 KONA JDK 11/Open JDK 11 运行环境,弹性微服务将默认开启应用加速功能,并且默认支持 SpringBoot 应用零改造加速。弹性微服务增强了 Open JDK 中的 AppCDS 特性,您无需改造原有的 SpringBoot 嵌套 Jar 包结构,弹性微服务将直接提供 Java 应用加速的最佳实践,实例扩容时的启动时间将缩短至10%~40%。

JVM 参数优化

使用可以感知容器内存资源的 JDK

在虚拟机和物理机中,对于 CPU 和内存分配,JVM 会从常见位置(例如,Linux 中的/proc/cpuinfo/proc/meminfo)查找其可以使用的 CPU 和内存。但是,在容器中运行时,CPU 和内存限制条件存储在/proc/cgroups/...中。较旧版本的 JDK 会继续在/proc(而不是/proc/cgroups)中查找,这可能会导致 CPU 和内存用量超出分配的上限,并因此引发多种严重的问题:
线程过多,因为线程池大小由 Runtime.availableProcessors() 配置
JVM的对内存使用超出容器内存上限。并导致容器被 OOMKilled。
JDK 8u131 首先实现了 UseCGroupMemoryLimitForHeap 的参数。但这个参数存在缺陷,为应用添加 UnlockExperimentalVMOptionsUseCGroupMemoryLimitForHeap 参数后,JVM 确实可以感知到容器内存,并控制应用的实际堆大小。但是这并没有充分利用我们为容器分配的内存。
因此 JVM 提供 -XX:MaxRAMFraction 标志来帮助更好的计算堆大小,MaxRAMFraction 默认值是4(即除以4),但它是一个分数,而不是一个百分比,因此很难设置一个能有效利用可用内存的值。
JDK 10 附带了对容器环境的更好支持。如果在 Linux 容器中运行 Java 应用程序,JVM 将使用 UseContainerSupport 选项自动检测内存限制。然后,通过 InitialRAMPercentageMaxRAMPercentageMinRAMPercentage 来进行对内存控制。这时,我们使用的是百分比而不是分数,这将更加准确。
默认情况下,UseContainerSupport 参数是激活的,MaxRAMPercentage 是25%,MinRAMPercentage 是50%。
需要注意的是,这里 MinRAMPercentage 并不是用来设置堆大小的最小值,而是仅当物理服务器(或容器)中的总可用内存小于250MB时,JVM 将用此参数来限制堆的大小。
同理,MaxRAMPercentage 是当物理服务器(或容器)中的总可用内存大小超过250MB时,JVM 将用此参数来限制堆的大小。
这几个参数已经向下移植到 JDK 8u191。UseContainerSupport 默认情况下是激活的。我们可以设置 -XX:InitialRAMPercentage=50.0 -XX:MaxRAMPercentage=80.0 来 JVM 感知并充分利用容器的可用内存。需要注意的是,在指定 -Xms -Xmx 时,InitialRAMPercentageMaxRAMPercentage 将会失效。

关闭优化编译器

默认情况下,JVM 有多个阶段的 JIT 编译。虽然这些阶段可以逐渐提高应用的效率,但它们也会增加内存使用的开销,并增加启动时间。
对于短期运行的云原生应用,可以考虑使用以下参数来关闭优化阶段,以牺牲长期运行效率来换取更短的启动时间。
			
JAVA_TOOL_OPTIONS="-XX:+TieredCompilation -XX:TieredStopAtLevel=1"

关闭类验证

当 JVM 将类加载到内存中以供执行时,它会验证该类未被篡改并且没有恶意修改或损坏。但在云原生环境,CI/CD 流水线通常也由云原生平台提供,这表示我们的应用的编译和部署是可信的,因此我们应该考虑使用以下参数关闭验证。如果在启动时加载大量类,则关闭验证可能会提高启动速度。
			
JAVA_TOOL_OPTIONS="-noverify"

减小线程栈大小

大多数 Java Web 应用都是基于每个连接一个线程的模式。每个 Java 线程都会消耗本机内存(而不是堆内存)。这称为线程栈,并且每个线程默认为1MB。如果您的应用处理100个并发请求,则它可能至少有100个线程,这相当于使用了100MB的线程栈空间。该内存不计入堆大小。我们可以使用以下参数来减小线程栈大小。
			
JAVA_TOOL_OPTIONS="-Xss256k"
需要注意如果减小得太多,则将出现 java.lang.StackOverflowError。您可以对应用进行分析,并找到要配置的最佳线程栈大小。

Spring boot 应用优化

使用 Spring Boot 2.2 或更高版本

从 2.2 版开始,Spring Boot 已针对启动速度进行了大量优化。如果您使用的是低于 2.2 版的 Spring Boot,请考虑升级或 手动进行优化

使用延迟初始化

在 Spring Boot 2.2 及更高版本中,您可以开启全局延迟初始化,以提高启动速度,但代价是第一个请求的延迟时间可能变长,因为需要等待组件首次初始化。 您可以在 application.properties 中开启延迟初始化:
			
spring.main.lazy-initialization=true
相似文档
  • 自 Java 9 发布以来,Java 已经在诸多方面进行了显著的改进和增强,并伴随着一些针对 API 的修改,这其中的许多功能都可以改善您应用的启动速度、性能和内存占用。
  • 操作场景: 弹性微服务应用可以使用 CODING 构建持续集成方案,更多关于 CODING 持续集成功能和使用的说明,请参见 CODING 持续集成。 本文以 Java 应用为例,介绍如何使用 Coding 以 镜像 及 JAR/WAR 包 方式部署应用至弹性微服务。
  • 弹性微服务应用可以使用 Python 脚本来部署。 前提条件: 在开始持续集成之前,需要完成下述的准备工作: 1. 保证机器上安装的 Python 版本不低于 3.0 版本,并已安装 PIP 等 Python 包管理工具。 2. 获取腾讯云的 访问密钥SecretId 和 SecretKey。 3. 在弹性微服务创建了环境。 4. 安装脚本所需的依赖。
  • Terraform 是一个 IT 基础架构自动化编排工具,它的口号是“Write, Plan, and Create Infrastructure as Code”, 是一个“基础设施即代码”工具,通过 Terraform 您可以创建、更新和版本控制的 TEM 中的资源。了解更多关于 Terraform,请参见 Terraform 指南。
  • 操作场景: 在弹性微服务中,环境是一组计算、网络、存储等资源的集合。TEM 提供多环境管理的功能,您可根据自身业务需要,创建开发、测试、预发、生产等多个环境,分别部署应用,达成环境隔离的目的。不同环境中的应用彼此隔离。 本文介绍如何使用 Terraform 创建、编辑和删除 TEM 环境资源。
官方微信
联系客服
400-826-7010
7x24小时客服热线
分享
  • QQ好友
  • QQ空间
  • 微信
  • 微博
返回顶部