Java16支持alpine体验
- 前言
- 体验
- 总结
- 参考资料
前言
最近Java16发布了,其中一个很重要的特性就是可以支持在AlpineLinux 中运行了,由于AlpineLinux 采用了musl libc和busybox以减小系统的体积和运行时资源消耗,得以使AlpineLinux的docker镜像非常小,只有5-6M,这在云原生环境下非常有优势。然而jdk16之前的版本都是运行在glibc上的,要想在alpine上运行,一般都给alpine装上gclib,这样增加了体积,大概12M左右(https://hub.docker.com/r/frolvlad/alpine-glibc)。为此JEP 386,就是为了在AlpineLinux 移植OpenJdk。 java16之前也有其他的openjdk的发行版支持musl libc,比如zulu jdk,https://cn.azul.com/downloads/zulu-community/?version=java-11-lts&os=alpine-linux&architecture=x86-64-bit&package=jdk。 Adopt的jdk16-alpine镜像似乎还是用先下载gclib的方式来构建镜像,没有用上新特性。https://github.com/AdoptOpenJDK/openjdk-docker/blob/master/16/jdk/alpine/Dockerfile.hotspot.releases.full
体验
下载OpenJdk的发行版adoptopenjdk,官网地址:https://adoptopenjdk.net/releases.html?variant=openjdk16&jvmVariant=hotspot
可以看到和普通的Liunx版本的大小差不多,这里不得不吐槽下,Java9之后jdk的体积增大了不少,生产上可以使用jre作为基础镜像,但是我们线上为了方便排查问题,将arthas作为基础工具增加到镜像中,而arthas必须要依赖jdk,导致镜像体积增了很多。
下载最新的alpine镜像,
docker pull alpine
启动容器,
docker run -t -i 302aba9ce190
复制jdk到容器中,配置环境变量
docker cp /opt/alpine-jdk16/OpenJDK16-jdk_x64_alpine-linux_hotspot_16_36.tar.gz 54dbb340c7c0:/opt/java
编写一段代码,也可以用jshell命令。
import java.util.concurrent.ConcurrentHashMap;
public class AlpineTest {
public static void main(String[] args) {
String str = "this ";
System.out.println(str + "is the first alpine java ...");
ConcurrentHashMap<String, Object> map = new ConcurrentHashMap<>(16);
map.put("a", "a");
System.out.println(map.get("a"));
}
}
Java16可以不用编译成class,可以直接用java命令运行出结果。
08d3aedb8cf5:/opt# java AlpineTest.java
this is the first alpine java ...
a
简单的demo代码似乎没有问题。 接着测试下是否可以运行springboot,在spring官网下载最新的springboot,加上web。
@RestController
public class DemoController {
@GetMapping("/stu")
public Student getStudent() {
return Student.builder().stuNo("20200801").age(20).name("张三").classNo("301").build();
}
@Builder
@Data
static class Student {
private String stuNo;
private String name;
private int age;
private String classNo;
}
}
配置properties
server.port=8081
server.servlet.context-path=/spring-boot
打包成FatJar到容器中运行。
运行成功,到浏览器中输入http://192.168.1.115:8081/spring-boot/stu,返回的结果也正常。
至此,简单SpringBoot项目也运行成功,对于复杂的中间件和代码,不知道有没有其他的坑。
总结
目前来看,jdk16-AlpineLinux是可以alpine中运行的,但是由于jdk本身的体积很大,省的这一点体积似乎不够看,如果装的是jre还是有一些优势的,可以使基础镜像减少几十兆。另外现在springboot打包的FatJar很大,动辄200M大小,使得基础镜像的体积减小好像意义不大。 GraalVM AOT可以很好的解决Java环境下包体积过大,传输和启动缓慢的问题,SpringBoot现在也支持AOT(beta还没有GA)https://spring.io/blog/2021/03/11/announcing-spring-native-beta,包减少到只有几兆,启动只有零点几毫秒,再搭配Alpine基础镜像,那真的非常契合云原生时代,但是因为缺少Jre,JVM等运行环境,对于之前的生态很难完美兼容,应该是一个新的生态了。