尝试使用cAdvisor检查在GraalVM上进行原生化的Javalin容器【2019年10月版】
发生了什么事?
用Javalin构建WebAPI服务器,然后使用GraalVM将其编译为本机的单个二进制文件,进一步将其制作成Docker镜像并以容器的形式运行,但说实话它到底有多轻量呢?为了确认这一点,我们可以使用cAdvisor + Prometheus & Grafana来检查容器的资源使用情况,这是一篇依然信息量很多的烦人文章。嗯,对不起。。。
行动环境 zuò
操作系统:macOS Mojave 10.14.6
Docker:Docker桌面版Mac 2.1.0.3(引擎:19.03.2,Compose:1.24.1)
Graalvm SDK:1.0.0-rc-6
Javalin:2.2.0
如果有一个支持Docker和Docker Compose的环境,我认为Windows也是可以的。
我不会深入讨论Javalin,它是一个轻量级的Web框架,将Jetty封装起来。
- A simple web framework for Java and Kotlin
那么,让我们立即开始吧。
在Docker上构建Javalin和Graal的配置
我希望按照原始的教程进行操作,尽管Graal和Javalin不是最新版本。
- Running Javalin on GraalVM (22MB total size)
在这篇文章中,介绍了使用GraalVM构建Javalin简易Web应用,并将其直接转换为Docker容器的步骤。
据说他们可以通过使用Scratch Image(保持二进制可执行文件)来将Java Web应用程序转化为容器,这样可以将其容量减小到仅有22MB。(我并没有实际测量过。)
现在,我们开始构建吧。
获取示例源代码
突然ですが、今度の目標はcAdvisor(+Prometheus+Grafana)を使用してコンテナを監視することです。そのため、Javalinのサンプル実装は既に構築された成果物をそのまま利用させていただきたいと思います。
让我们把以下的存储库进行克隆吧。
$ git clone git@github.com:tipsy/graal-javalin.git
2. docker-compose.yaml文件的描述
我已经克隆了,但没有进入graal-javalin目录,我会在同一个目录下继续创建以下的docker-compose.yaml文件。
version : "3"
services:
javalin-graalvm:
build:
context: graal-javalin
ports:
- 7000:7000
stdin_open: true
tty: true
我会直接运行克隆的代码。
在Graalvm上运行Javalin容器。
好,让我们使用以下命令快速启动吧。
$ docker-compose up -d
当使用 curl 命令访问端口号为7000时……
$ curl http://localhost:7000
{"someValue":"Hello World!"}
所以,我快速构建了一个REST API的示例,结果以JSON格式返回。
太棒了!
3-1. 闲聊:关于容器镜像 “scratch”。
在上述的Dockerfile中构建容器时,包含GraalVM的容器会将构建的二进制文件复制到scratch镜像中,并进行容器化,这样可以通过两个阶段来构建映像。scratch镜像是一种特殊的空白镜像。
换句话说,通过GraalVM构建的二进制文件几乎原封不动地由docker进程启动,只有运行docker进程的环境(操作系统和机器架构)相同才能正常运行。
由于我们这次只是为了验证目的,所以可以不用太在意,但是在实际的生产环境中采用可能会相对困难一些。上述的文章只是强调“仅有22MB的scratch!我真厉害!”这一内容,请理解一下。
在中国本土,一键启动cAdvisor、Prometheus和Grafana。
让我们尝试运行 cAdvisor、Prometheus 和 Grafana 服务。
这次的项目正好在以下文章中介绍!
- Prometheus、Grafana、cAdvisorによる監視をコマンド一つで行える「dockprom」
因此,我们将创建一个”dockprom”的克隆品。
目錄仍然保持不變……
$ git clone git@github.com:stefanprodan/dockprom.git
然后,使用docker-compose up来启动!
$ cd dockprom
$ docker-compose up -d
...
Creating alertmanager ... done
Creating prometheus ... done
Creating caddy ... done
Creating grafana ... done
Creating pushgateway ... done
Creating nodeexporter ... done
Creating cadvisor ... done
下载图片需要一些时间,我们耐心等待。一段时间后,在所有容器创建完成后,访问等待中的Grafana容器(http://localhost:3000)。
当我查看Grafana的仪表盘时…
第一次使用时可能需要重置密码等操作,不过应该可以顺利使用。哇,太棒了。。。
因为 Grafana 很容易启动,所以我有些感动,但是让我们集中注意力,从屏幕左上角的 “Dashboards” 中选择 Docker Containers。我想你会看到刚刚启动的 javalin-graalvm 容器显示在那里。
聪明的是,Prometheus、Grafana 和其他用于监控的容器不会显示出来,应该只会显示除监控容器之外的容器的状态信息。
在我的环境中,情况如上。我尝试访问http://localhost:7000,以获得JSON数据,但内存使用量远未达到20MB。
哦… 呀,好輕…
画面上的图表显示资源消耗量急剧上升,但由于原本的内存单位是5 MiB,所以这是一个小小的世界。真是个小小的世界!
虽然这只是一个简单的打印”Hello World”的程序,但是我已经包含了Jetty和JRE等相应的二进制文件…即使只运行JVM,也会消耗数百兆字节的内存,不是吗!
春やMicronautも… (Haru ya Micronaut mo…)
看起来Micronaut和Spring都在积极地进行GraalVM的兼容性开发。
-
- GraalVM の native image を使って Java で爆速 Lambda の夢を見る
- Spring Boot ApplicationをMicronaut for Springでnative-imageにしてみる
GraalVM能够支持多少程度的本地化操作还需要进一步调查,但一旦使用GraalVM将Java应用本地化,就可以轻松将其部署到Docker或Kubernetes等超轻量级容器中……这真是令人兴奋!
今天就到这里吧!