加入收藏 | 设为首页 | 会员中心 | 我要投稿 辽源站长网 (https://www.0437zz.com/)- 云专线、云连接、智能数据、边缘计算、数据安全!
当前位置: 首页 > 运营中心 > 建站资源 > 优化 > 正文

进击的 Java ,云原生时代的蜕变

发布时间:2019-09-20 16:32:12 所属栏目:优化 来源:易立
导读:【编者的话】云原生时代的来临,与Java 开发者到底有什么联系?有人说,云原生压根不是为了 Java 存在的。然而,本文的作者却认为云原生时代,Java 依然可以胜任巨人的角色。作者希望通过一系列实验,开拓同学视野,提供有益思考。 在企业软件领域,Java 依

为了实现“一次编写,随处运行”的能力,Java 程序会被编译成实现架构无关的字节码。JVM 在运行时将字节码转换成本地机器码执行。这个转换过程决定了 Java 应用的启动和运行速度。为了提升执行效率,JVM 引入了 JIT compiler(Just in Time Compiler,即时编译器),其中 Sun/Oracle 公司的 HotSpot 是最著名 JIT 编译器实现。

HotSpot 提供了自适应优化器,可以动态分析、发现代码执行过程中的关键路径,并进行编译优化。HotSpot 的出现极大提升了Java 应用的执行效率,在 Java 1.4 以后成为了缺省的 VM 实现。但是 HotSpot VM 在启动时才对字节码进行编译,一方面导致启动时执行效率不高,一方面编译和优化需要很多的 CPU 资源,拖慢了启动速度。我们是否可以优化这个过程,提升启动速度呢?

熟悉 Java 江湖历史的同学应该会知道 IBM J9 VM,它是用于 IBM 企业级软件产品的一款高性能的 JVM,帮助 IBM 奠定了商业应用平台中间件的霸主地位。2017 年 9 月,IBM 将 J9 捐献给 Eclipse 基金会,并更名 Eclipse OpenJ9,开启开源之旅。

OpenJ9 提供了 Shared Class Cache(SCC 共享类缓存)和 Ahead-of-Time(AOT 提前编译)技术,显著减少了 Java 应用启动时间。

SCC 是一个内存映射文件,包含了J9 VM 对字节码的执行分析信息和已经编译生成的本地代码。开启 AOT 编译后,会将 JVM 编译结果保存在 SCC 中,在后续 JVM 启动中可以直接重用。与启动时进行的 JIT 编译相比,从 SCC 加载预编译的实现要快得多,而且消耗的资源要更少。启动时间可以得到明显改善。

我们开始构建一个包含 AOT 优化的 Docker 应用镜像:

  1. $cat Dockerfile.openj9.warmed 
  2. FROM adoptopenjdk/openjdk8-openj9 AS build 
  3. RUN sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/' /etc/apt/sources.list 
  4. RUN apt-get update 
  5. RUN apt-get install -y  
  6.     git  
  7.     maven 
  8. WORKDIR /tmp 
  9. RUN git clone https://github.com/spring-projects/spring-petclinic.git 
  10. WORKDIR /tmp/spring-petclinic 
  11. RUN mvn install 
  12. FROM adoptopenjdk/openjdk8-openj9:jre8u222-b10_openj9-0.15.1-alpine 
  13. COPY --from=build /tmp/spring-petclinic/target/spring-petclinic-2.1.0.BUILD-SNAPSHOT.jar spring-petclinic-2.1.0.BUILD-SNAPSHOT.jar 
  14. # Start and stop the JVM to pre-warm the class cache 
  15. RUN /bin/sh -c 'java -Xscmx50M -Xshareclasses -Xquickstart -jar spring-petclinic-2.1.0.BUILD-SNAPSHOT.jar &' ; sleep 20 ; ps aux | grep java | grep petclinic | awk '{print $1}' | xargs kill -1 
  16. CMD ["java","-Xscmx50M","-Xshareclasses","-Xquickstart", "-jar","spring-petclinic-2.1.0.BUILD-SNAPSHOT.jar"] 

其中 Java 参数 -Xshareclasses 开启SCC,-Xquickstart 开启AOT。

在 Dockerfile 中,我们运用了一个技巧来预热 SCC。在构建过程中启动 JVM 加载应用,并开启 SCC 和 AOT,在应用启动后停止 JVM。这样就在 Docker 镜像中包含了生成的 SCC 文件。

然后,我们来构建 Docker 镜像并启动测试应用:

  1. $ docker build -t petclinic-openjdk-openj9-warmed-slim -f Dockerfile.openj9.warmed-slim . 
  2. $ docker run --name hotspot -p 8080:8080 --rm petclinic-openjdk-openj9-warmed-slim 
  3. ... 
  4. 2019-09-11 03:35:20.192  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path '' 
  5. 2019-09-11 03:35:20.193  INFO 1 --- [           main] o.s.s.petclinic.PetClinicApplication     : Started PetClinicApplication in 3.691 seconds (JVM running for 3.952) 
  6. ... 

可以看到,启动时间已经从之前的 8.2s 减少到 4s,提升近50%。

(编辑:辽源站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读