graalvm + dubbo3

Dubbo AOT demo体验,并修复dubbo3 aot的编译报错问题
https://github.com/apache/dubbo/pull/12735

搭建环境

  1. 下载graalvm
    graalvm 类似增强版的Jdk,安装方法与jdk完全一致,但是得确认好版本

    GraalVM 目前支持两个java版本: jdk17 与jdk21

    下载地址:GraalVM社区版(注意不是简单的GraalVM-jdk组件)

  2. 配置GraalVM 环境变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 配置JDK路径
export JAVA_8_HOME=/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home
export JAVA_11_HOME=/Library/Java/JavaVirtualMachines/openjdk-11.jdk/Contents/Home
export JAVA_17_HOME=/Library/Java/JavaVirtualMachines/openjdk-17.jdk/Contents/Home
export GRAALVM_17_HOME=/Library/Java/JavaVirtualMachines/graalvm-community-openjdk-17.0.7+7.1/Contents/Home
# 设置默认JDK版本
# export JAVA_HOME=$JAVA_17_HOME
export JAVA_HOME=$GRAALVM_17_HOME
CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:.
# 配置alias命令动态切换JDK版本
alias jdk8="export JAVA_HOME=$JAVA_8_HOME && export PATH=$JAVA_8_HOME/bin/:$PATH"
alias jdk11="export JAVA_HOME=$JAVA_11_HOME && export PATH=$JAVA_11_HOME/bin/:$PATH"
alias jdk17="export JAVA_HOME=$JAVA_17_HOME && export PATH=$JAVA_17_HOME/bin/:$PATH"
alias graal17="export JAVA_HOME=$GRAALVM_17_HOME && export PATH=$GRAALVM_17_HOME/bin/:$PATH"
export JAVA_HOME
export PATH=$JAVA_HOME/bin/:$PATH
export CLASSPATH

3.验证

1
java -version

控制台输出

1
2
3
openjdk version "17.0.7" 2023-04-18
OpenJDK Runtime Environment GraalVM CE 17.0.7+7.1 (build 17.0.7+7-jvmci-23.0-b12)
OpenJDK 64-Bit Server VM GraalVM CE 17.0.7+7.1 (build 17.0.7+7-jvmci-23.0-b12, mixed mode, sharing)
  1. 目前最新的GraalVM-CE版已经默认集成里native-image工具
    可以用
1
sudo gu install native-image

验证或者安装

1
2
3
Downloading: Component catalog from www.graalvm.org
Processing Component: Native Image
Component Native Image (org.graalvm.native-image) is already installed.

dubbo 环境

zookeeper: 3.7.1

prettyZoo
dubbo-aot-demo

由于dubbo-aot 还未成熟,需要git clone 最新代码,自行编译安装到本地maven 仓库
dubbo-jars

dubbo-demo工程配置

目前dubbo aot 只能用json2的序列化方式,hession2 存在问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
spring:
application:
name: dubbo-samples-nativeimage-provider
dubbo:
application:
name: ${spring.application.name}
logger: slf4j
# compiler: jdk
protocol:
name: dubbo
port: -1
serialization: fastjson2
registry:
id: zk-registry
address: zookeeper://127.0.0.1:2181
config-center:
address: zookeeper://127.0.0.1:2181
metadata-report:
address: zookeeper://127.0.0.1:2181
provider:
# proxy: jdk
serialization: fastjson2
consumer:
# proxy: jdk
serialization: fastjson2

logging:
pattern:
level: '%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]'

server:
port: 9090

编译命令

1
mvn clean package -P native native:compile -Dmaven.test.skip=true

报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Exception in thread "main" java.lang.IllegalStateException: No constructor or factory method candidate found for Root bean: class [org.apache.dubbo.config.spring.ServiceBean]; scope=singleton; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodNames=null; destroyMethodNames=null and argument types []
at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorOrFactoryMethod(ConstructorResolver.java:944)
at org.springframework.beans.factory.support.RegisteredBean.resolveConstructorOrFactoryMethod(RegisteredBean.java:209)
at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.<init>(BeanDefinitionMethodGenerator.java:86)
at org.springframework.beans.factory.aot.BeanDefinitionMethodGeneratorFactory.getBeanDefinitionMethodGenerator(BeanDefinitionMethodGeneratorFactory.java:100)
at org.springframework.beans.factory.aot.BeanDefinitionMethodGeneratorFactory.getBeanDefinitionMethodGenerator(BeanDefinitionMethodGeneratorFactory.java:115)
at org.springframework.beans.factory.aot.BeanRegistrationsAotProcessor.processAheadOfTime(BeanRegistrationsAotProcessor.java:48)
at org.springframework.beans.factory.aot.BeanRegistrationsAotProcessor.processAheadOfTime(BeanRegistrationsAotProcessor.java:36)
at org.springframework.context.aot.BeanFactoryInitializationAotContributions.getContributions(BeanFactoryInitializationAotContributions.java:67)
at org.springframework.context.aot.BeanFactoryInitializationAotContributions.<init>(BeanFactoryInitializationAotContributions.java:49)
at org.springframework.context.aot.BeanFactoryInitializationAotContributions.<init>(BeanFactoryInitializationAotContributions.java:44)
at org.springframework.context.aot.ApplicationContextAotGenerator.lambda$processAheadOfTime$0(ApplicationContextAotGenerator.java:58)
at org.springframework.context.aot.ApplicationContextAotGenerator.withCglibClassHandler(ApplicationContextAotGenerator.java:67)
at org.springframework.context.aot.ApplicationContextAotGenerator.processAheadOfTime(ApplicationContextAotGenerator.java:53)
at org.springframework.context.aot.ContextAotProcessor.performAotProcessing(ContextAotProcessor.java:106)
at org.springframework.context.aot.ContextAotProcessor.doProcess(ContextAotProcessor.java:84)
at org.springframework.context.aot.ContextAotProcessor.doProcess(ContextAotProcessor.java:49)
at org.springframework.context.aot.AbstractAotProcessor.process(AbstractAotProcessor.java:82)
at org.springframework.boot.SpringApplicationAotProcessor.main(SpringApplicationAotProcessor.java:80)
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for dubbo-samples-native-image 1.0-SNAPSHOT:
[INFO]
[INFO] dubbo-samples-native-image ......................... SUCCESS [ 0.241 s]
[INFO] dubbo-samples-native-image-interface ............... SUCCESS [ 0.492 s]
[INFO] dubbo-samples-native-image-provider ................ FAILURE [ 3.659 s]
[INFO] dubbo-samples-native-image-consumer ................ SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.537 s
[INFO] Finished at: 2023-07-16T22:24:41+08:00
[INFO] ------------------------------------------------------------------------

解决

已经提交 pr 到 github
https://github.com/apache/dubbo/pull/12735

1
2
3
4
5
org.apache.dubbo.config.spring.ServiceBean
//添加无参构造函数
public ServiceBean() {
this.service = null;
}

编译成功

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
[2/8] Performing analysis...  [******]                                                (59.7s @ 2.39GB)
25,479 (91.57%) of 27,824 types reachable
44,360 (68.92%) of 64,369 fields reachable
128,368 (65.62%) of 195,631 methods reachable
7,828 types, 462 fields, and 8,536 methods registered for reflection
88 types, 95 fields, and 65 methods registered for JNI access
5 native libraries: -framework CoreServices, -framework Foundation, dl, pthread, z
[3/8] Building universe... (19.0s @ 2.41GB)
[4/8] Parsing methods... [***] (7.6s @ 1.70GB)
[5/8] Inlining methods... [****] (2.5s @ 1.73GB)
[6/8] Compiling methods... [******] (35.4s @ 2.55GB)
[7/8] Layouting methods... [***] (11.9s @ 2.25GB)
[8/8] Creating image... [****] (14.4s @ 1.39GB)
61.84MB (54.73%) for code area: 86,261 compilation units
49.84MB (44.11%) for image heap: 545,697 objects and 228 resources
1.31MB ( 1.16%) for other data
112.99MB in total
------------------------------------------------------------------------------------------------------
Top 10 origins of code area: Top 10 object types in image heap:
13.75MB java.base 14.76MB byte[] for code metadata
6.81MB jdk.compiler 6.27MB java.lang.Class
4.49MB fastjson2-2.0.34.jar 5.38MB java.lang.String
4.14MB tomcat-embed-core-10.1.7.jar 4.79MB byte[] for java.lang.String
3.42MB dubbo-3.3.0-beta.1-SNAPSHOT.jar 4.06MB byte[] for general heap data
2.91MB java.xml 2.14MB c.o.svm.core.hub.DynamicHubCompanion
1.92MB jackson-databind-2.14.2.jar 1.58MB byte[] for reflection metadata
1.59MB svm.jar (Native Image) 1.14MB byte[] for embedded resources
1.53MB spring-core-6.0.7.jar 1.07MB java.lang.String[]
1.23MB spring-boot-3.0.5.jar 914.65kB c.o.s.c.h.DynamicHub$ReflectionMetadata
19.56MB for 156 more packages 7.33MB for 4935 more object types
------------------------------------------------------------------------------------------------------
Recommendations:
HEAP: Set max heap for improved and more predictable memory usage.
CPU: Enable more CPU features with '-march=native' for improved performance.
------------------------------------------------------------------------------------------------------
42.2s (26.7% of total time) in 308 GCs | Peak RSS: 2.95GB | CPU load: 5.43
------------------------------------------------------------------------------------------------------
Produced artifacts:
/Users/promisechan/Desktop/code/java_code/dubbo-samples-native-image/dubbo-samples-native-image-consumer/target/dubbo-samples-native-image-consumer (executable)
======================================================================================================
Finished generating 'dubbo-samples-native-image-consumer' in 2m 37s.
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for dubbo-samples-native-image 1.0-SNAPSHOT:
[INFO]
[INFO] dubbo-samples-native-image ......................... SUCCESS [ 0.276 s]
[INFO] dubbo-samples-native-image-interface ............... SUCCESS [ 0.570 s]
[INFO] dubbo-samples-native-image-provider ................ SUCCESS [02:47 min]
[INFO] dubbo-samples-native-image-consumer ................ SUCCESS [02:45 min]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 05:34 min
[INFO] Finished at: 2023-07-16T23:13:56+08:00
[INFO] ------------------------------------------------------------------------

执行

1
./dubbo-samples-native-image-provider/target/dubbo-samples-native-image-provider

日志

1
2
2023-07-16T23:17:40.712+08:00  INFO [dubbo-samples-nativeimage-provider,,] 5376 --- [           main] o.a.d.n.p.NativeDemoProviderApplication  : Started NativeDemoProviderApplication in 0.348 seconds (process running for 0.359)

1
./dubbo-samples-native-image-consumer/target/dubbo-samples-native-image-consumer 

日志

1
2
3
4
5
6
7
8
9
10
o.a.d.c.d.DefaultApplicationDeployer     :  [DUBBO] Dubbo Application[1.1](dubbo-samples-nativeimage-consumer) is ready., dubbo version: 3.3.0-beta.1-SNAPSHOT, current host: 192.168.3.150
2023-07-16T23:17:58.943+08:00 INFO [dubbo-samples-nativeimage-consumer,,] 5381 --- [ main] o.a.d.n.c.NativeDemoConsumerApplication : Started NativeDemoConsumerApplication in 0.194 seconds (process running for 0.206)

...
...

o.a.d.remoting.transport.DecodeHandler : [DUBBO] Decode decodeable message org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcResult, dubbo version: 3.3.0-beta.1-SNAPSHOT, current host: 192.168.3.150
2023-07-16T23:17:58.947+08:00 DEBUG [dubbo-samples-nativeimage-consumer,,] 5381 --- [ main] i.m.c.u.i.logging.InternalLoggerFactory : Using SLF4J as the default logging framework
result: world

对比

jvm 启动耗时 1.933 s, native-image 启动耗时 0.359 s
是 native-images的 5.38 倍

1
2023-07-16T23:20:32.967+08:00  INFO [dubbo-samples-nativeimage-provider,,] 5434 --- [           main] o.a.d.n.p.NativeDemoProviderApplication  : Started NativeDemoProviderApplication in 1.933 seconds (process running for 2.203)