云原生时代的Java

前言

java的护城河从来都不是先进的语法和标准类库,而实庞大的软件生态及开发者群体。
危机来自自身基因:write once,run everywhere!(语言层面的虚拟化)
Docker:Build once,run everywhere!(Linux操作系统层面的虚拟化)

java的一些假设与当前的云原生理念不合,java假设构建大规模、长时间运行的程序。
啰嗦的语法,但是适合大规模团队协作。
静态类型,但是支持运行时加载新的类,适合组装出更大体量的软件产品。
GC、JIT、动态优化都是为了长时间运行越来越快,预热机制。
java诞生的年代认为程序应该由少量的大型实例构成。
云原生试代大量的小型实例,不强调所有团队都写出风格一致的代码,围绕业务能力去构建。同时也不追求长时间的稳定运行,而实容忍失败,具备弹性和韧性,快速恢复。

容器亲和性:镜像体积、快速启动、内存占用、尽快达到高速。
serverless架构更是追求极致的启动速度和达峰时间。

云原生试代的趋势:平台托管型语言 向 原生语言过度

如何应对

Panama

Vahalla(重点、难点)

程序 = 代码 + 数据

  1. Java的GIT可能是最优秀的,远胜GCC等。
    所以java的代码效率是极高的;
    Java的一切皆对象,导致java的内存利用方式是及其低效的,访问对象属性等都需要通过应用,呈现一个链式结构,而不是内存紧凑的。首先大量寻址,另外对多级缓存极不友好。
    结构体则在内存中是紧凑的(C、C++、C#都支持结构体)。

程序指令在cpu上的执行效率远远高于对存储的访问速度,可能是几百倍的差距,所以内存使用性能的提高收益远远高于代码层面的优化。
编译阶段代码逃逸分析:把局部变量使用标量替换,填充到静态字节码中。(对象的栈上分配暂时未实践)

泛型擦除:原生类型的拆箱,引发内存间接访问。

Loom(重点、难点)

java为了跨平台:统一的内存和线程模型,java当前的线程模型适合计算密集型任务,充分发挥cpu的算力;
但是创建线程的开销太大,不能很好的面对当前普遍的io密集型场景。
java实现携程不难,难点在于需要将携程和已有的thread、featuer、execuor等机制兼容起来,达到无缝衔接。

结构化并发:当作用域中有异步逻辑是,主线程应该在作用域的尾部阻塞,实现通过代码结构来控制并发的目的,而不是引入其他类库或工具。

Amber

Leyden

脱离JVM平台,以原生语言的行式直接跑在系统上
启动慢:需要启动JVM、
机制:构建时把运行态的机器码直接打进静态镜像。
难度:java最初就假设运行时的代码空间是开放的,运行时可以随时加载和卸载代码;
提前编译就导致其关闭,导致反射、动态代理、字节码增强等功能将不可实现,庞大的基于这些特性的开源库将失效。
SpringNative + grallVM,通过配置提前告诉编译器(启动一遍,然后收集动态部分),启动速度提升两个数量级。

Portola

构建物瘦身:jdk + alpineLinux,镜像从起码上百兆降到几十兆级别。

posted @ 2022-07-15 23:05  JaxYoun  阅读(403)  评论(0编辑  收藏  举报