一、背景
AWS Graviton是AWS推出的ARM架构处理器,目前已经在AWS中国区域、全球区域大规模可用。使用Graviton处理器的EC2机型,以及基于Graviton处理器的托管服务包括RDS、Redis、OpenSearch,可获得比同配置的Intel处理器机型更高的性能,且同配置对比成本更低。
更多信息可参考:
https://aws.amazon.com/cn/ec2/graviton/
https://aws.amazon.com/cn/campaigns/graviton/
本文将展示Java的跨平台特性,即可以在ARM架构的EC2上构建Java应用,也可以在Intel处理器上构建好JAR包后,直接复制到ARM架构上运行。
二、在使用Graviton处理器的ARM架构EC2上构建Java应用
1、使用Amazon Linux 2023操作系统创建EC2
创建一台规格为t4g.medium
对应2vCPU/4GB的EC2机型,操作系统选择Amazon Linux 2023系统。选择Amazon Linux 2023作为操作系统而不是选择Amazon Linux 2(兼容CentOS7)和Ubuntu(ARM64版)等其他系统的原因是:Amazon Linux 2023为ARM架构处理器做了深度优化,可获得比其他OS的ARM发型版更好的性能。
创建完毕后,通过SSH登陆到这个Linux上。
执行如下命令:
yum update -y
yum install -y git tmux
为了防止网络导致SSH断线使得程序失败,可执行tmux
命令启动虚拟终端。这样即便SSH断开,也可以通过tmux ls
命令查询之前后台运行的会话,并通过tmux attach
命令来恢复之前断线的SSH会话。如果之前有多个tmux会话,还可以通过tmux attach-session -t 0
这样的命令选择连接到特定编号的会话。
2、准备Java环境安装JDK和Maven
执行如下命令:
yum search java-1
这样将返回所有Java版本包括Java 1.8/11/18。返回清单如下:
Last metadata expiration check: 1:43:23 ago on Fri Jun 16 05:43:42 2023.
===================================================================================================== Name Matched: java-1 ======================================================================================================
java-1.8.0-amazon-corretto.aarch64 : Amazon Corretto runtime environment
java-1.8.0-amazon-corretto-devel.aarch64 : Amazon Corretto development environment
java-11-amazon-corretto.aarch64 : Amazon Corretto development environment
java-11-amazon-corretto-devel.aarch64 : Amazon Corretto 11 development tools
java-11-amazon-corretto-headless.aarch64 : Amazon Corretto headless development environment
java-11-amazon-corretto-javadoc.aarch64 : Amazon Corretto 11 API documentation
java-11-amazon-corretto-jmods.aarch64 : Amazon Corretto 11 jmods
java-17-amazon-corretto.aarch64 : Amazon Corretto development environment
java-17-amazon-corretto-devel.aarch64 : Amazon Corretto 17 development tools
java-17-amazon-corretto-headless.aarch64 : Amazon Corretto headless development environment
java-17-amazon-corretto-javadoc.aarch64 : Amazon Corretto 17 API documentation
java-17-amazon-corretto-jmods.aarch64 : Amazon Corretto 17 jmods
Amazon Corretto 是开放 Java 开发工具包 (OpenJDK) 的免费、多平台、生产就绪型发行版。Corretto 提供长期支持,其中包括性能增强和安全修复。亚马逊在内部的数千种生产服务上运行 Corretto,并且 Corretto 已被证明能够兼容 Java SE 标准。借助 Corretto,您可以在常用操作系统(包括 Linux、Windows 和 macOS)上开发和运行 Java 应用程序。
执行如下命令搜索可用的Maven版本:
yum search maven-amazon
返回结果如下:
Last metadata expiration check: 1:44:56 ago on Fri Jun 16 05:43:42 2023.
================================================================================================== Name Matched: maven-amazon ===================================================================================================
maven-amazon-corretto11.noarch : Amazon Corretto 11 binding for Maven
maven-amazon-corretto17.noarch : Amazon Corretto 17 binding for Maven
maven-amazon-corretto8.noarch : Amazon Corretto 8 binding for Maven
本文以Java11为例,执行如下命令安装JDK和Maven:
yum install -y java-11-amazon-corretto maven-amazon-corretto11
3、构建测试应用
接下来从Graviton University Workshops下载代码:
git clone https://github.com/nwcd-samples/GravitonDemo.git
cd GravitonDemo/graviton-demo-springboot
这个测试应用的作用是在WEB页面上打印当前运行环境所在EC2的规格、机型、操作系统版本和所在Region和可用区。执行如下命令构建(请注意当前执行目录必须是graviton-demo-springboot
):
mvn package
注意:如果您的实验环境在中国区,可使用中国区特定Maven镜像提高下载速度。请参考下一小节。
构建完毕后,在当前目录下的target
目录中,graviton2-demo-0.0.1-SNAPSHOT.jar
文件。
4、在中国区域构建时候使用Maven镜像加速(可选)
如果是在AWS海外环境构建,不需要考虑网络因素。如果在国内构建,那么从Apache的Maven官方下载速度可能收到跨国网络限制。此时建议使用Maven镜像。
执行如下命令编辑Maven配置文件。
vim /etc/maven/settings.xml
找到<mirros>
章节的配置,加入如下一段:
<mirror>
<id>aliyun_nexus</id>
<mirrorOf>*</mirrorOf>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>
添加后的整个mirrors
章节的配置格式如下:
<mirrors>
<!-- mirror
| Specifies a repository mirror site to use instead of a given repository. The repository that
| this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
| for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
|
<mirror>
<id>mirrorId</id>
<mirrorOf>repositoryId</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://my.repository.com/repo/path</url>
</mirror>
-->
<mirror>
<id>maven-default-http-blocker</id>
<mirrorOf>external:http:*</mirrorOf>
<name>Pseudo repository to mirror external repositories initially using HTTP.</name>
<url>http://0.0.0.0/</url>
<blocked>true</blocked>
</mirror>
<mirror>
<id>aliyun_nexus</id>
<mirrorOf>*</mirrorOf>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>
</mirrors>
保存退出窗口。如果之前有构建过,执行如下命令可清除缓存。
mvn dependency:purge-local-repository
然后正常构建应用(请注意当前执行目录必须是graviton-demo-springboot
):
mvn package
构建完毕后,在当前目录下的target
目录中,graviton2-demo-0.0.1-SNAPSHOT.jar
文件。
5、在本机上测试Java应用运行
在当前目录下,执行如下命令即可启动应用。
java -jar target/graviton2-demo-0.0.1-SNAPSHOT.jar
启动成功后,返回如下。服务监听在8080端口。
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.7.8)
2023-06-16 07:31:55.473 INFO 49273 --- [ main] c.e.g.Graviton2DemoApplication : Starting Graviton2DemoApplication v0.0.1-SNAPSHOT using Java 17.0.7 on ip-172-31-14-80.cn-northwest-1.compute.internal withPID 49273 (/root/GravitonDemo/graviton-demo-springboot/target/graviton2-demo-0.0.1-SNAPSHOT.jar started by root in /root/GravitonDemo/graviton-demo-springboot)
2023-06-16 07:31:55.477 INFO 49273 --- [ main] c.e.g.Graviton2DemoApplication : No active profile set, falling back to 1 default profile: "default"
2023-06-16 07:31:56.934 INFO 49273 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2023-06-16 07:31:56.946 INFO 49273 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2023-06-16 07:31:56.947 INFO 49273 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.71]
2023-06-16 07:31:57.048 INFO 49273 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2023-06-16 07:31:57.048 INFO 49273 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1465 ms
2023-06-16 07:31:57.618 WARN 49273 --- [ main] ion$DefaultTemplateResolverConfiguration : Cannot find template location: classpath:/templates/ (please add some templates, check your Thymeleaf configuration, or setspring.thymeleaf.check-template-location=false)
2023-06-16 07:31:57.693 INFO 49273 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2023-06-16 07:31:57.710 INFO 49273 --- [ main] c.e.g.Graviton2DemoApplication : Started Graviton2DemoApplication in 2.98 seconds (JVM running for 3.565)
现在使用浏览器访问http://本机公网IP:8080
端口,即可正常打开应用。
请注意,请事先做好如下准备,才能从互联网使用浏览器访问本机8080端口:
- 本EC2位于Public Subnet,具有公网IP或者弹性EIP
- 本机的安全规则组允许来自互联网的请求访问本机TCP协议8080端口
- 中国区账号已经通过ICP备案(或者通过ICP白名单),海外区域账号不需要此步骤
在满足以上准备的情况下,浏览器访问成功。如下截图。
由此可以看到在使用Graviton处理器的ARM架构EC2上正常使用Java应用。当应用运行在ARM架构上时候,会显示Instance Type
一项为当前正在使用的机型是使用Graviton处理器的t4g.medium
。
三、将X86_64架构上构建的Java应用部署到ARM架构
1、在X86_64环境上完成构建
创建一台规格为t3.medium
的EC2。然后按照以上流程,在X86_64架构上运行构建,并在target
目录中获得名为graviton2-demo-0.0.1-SNAPSHOT.jar
的JAR包。此JAR包文件名叫做graviton2-demo-0.0.1-SNAPSHOT.jar
但其实是在X86_64平台构建的。因此可将其改名为intel.jar
。然后还会将其从X86_64架构的EC2上复制出来。
2、在X86_64环境上运行刚构建的应用
按照相同的流程,测试构建好的JAR包可以在X86_64平台上运行。执行如下命令:
java -jar intel.jar
注意此时应用会显示Instance Type
一项为当前正在使用的机型是使用Intel处理器的t3.medium
。如下截图。
在确认应用正常后,将intel.jar
从X86_64架构的EC2上复制出来,并上传到ARM架构的EC2上。
3、在ARM平台上运行X86_64平台上构建的JAR包
登陆到前文构建Java应用使用的t4g.medium
这台EC2,前文已经安装好Amazon Corretto(OpenJDK)的环境上,因此可运行从X86_64平台复制过来的JAR包。
java -jar intel.jar
返回结果中可看到应用正常启动。
root@ip-172-31-14-80 ~]# aws s3 cp s3://lxy-sa-software/intel.jar .
download: s3://lxy-sa-software/intel.jar to ./intel.jar
[root@ip-172-31-14-80 ~]# java -jar intel.jar
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.7.8)
2023-06-16 07:45:46.042 INFO 49750 --- [ main] c.e.g.Graviton2DemoApplication : Starting Graviton2DemoApplication v0.0.1-SNAPSHOT using Java 17.0.7 on ip-172-31-14-80.cn-northwest-1.compute.internal withPID 49750 (/root/intel.jar started by root in /root)
2023-06-16 07:45:46.045 INFO 49750 --- [ main] c.e.g.Graviton2DemoApplication : No active profile set, falling back to 1 default profile: "default"
2023-06-16 07:45:47.567 INFO 49750 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2023-06-16 07:45:47.579 INFO 49750 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2023-06-16 07:45:47.579 INFO 49750 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.71]
2023-06-16 07:45:47.664 INFO 49750 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2023-06-16 07:45:47.664 INFO 49750 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1501 ms
2023-06-16 07:45:48.206 WARN 49750 --- [ main] ion$DefaultTemplateResolverConfiguration : Cannot find template location: classpath:/templates/ (please add some templates, check your Thymeleaf configuration, or setspring.thymeleaf.check-template-location=false)
2023-06-16 07:45:48.297 INFO 49750 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2023-06-16 07:45:48.316 INFO 49750 --- [ main] c.e.g.Graviton2DemoApplication : Started Graviton2DemoApplication in 2.954 seconds (JVM running for 3.603)
然后通过浏览器测试,可看到其访问正常。当应用运行在ARM架构上时候,会显示Instance Type
一项为当前正在使用的机型是使用Graviton处理器的t4g.medium
。
由此可看到,在X86_64平台上构建的Java应用可直接部署在使用Graviton处理器的ARM架构的EC2上。
四、参考文档
Amazon Corretto介绍
https://aws.amazon.com/cn/corretto/
Amazon Corretto 下载(OpenJDK发行版)
https://docs.aws.amazon.com/corretto/latest/corretto-17-ug/downloads-list.html
使用网易Maven镜像
https://mirrors.163.com/.help/maven.html
Graviton University Workshops
https://catalog.us-east-1.prod.workshops.aws/workshops/238ba0d4-8abe-4d35-8740-0e3218cb5844/zh-CN/