在原生可执行文件中使用 Avro

几个月前,我写了一篇关于 Quarkus、Kafka 和 Avro(使用 Apicurio schema registry)的博客。

我们开发了一个简单的应用程序,它接收 HTTP 请求,将记录写入 Kafka,并从 Kafka 读取它们。它使用 Avro 来序列化和反序列化记录。

architecture

当时,该应用程序在原生模式下**无法**正常工作。

现在,借助 Quarkus 1.10.2,它可以在原生模式下工作了!

为什么它不能工作?

原生编译器并非支持 Java 中的所有功能。有些情况尚不支持,而 Avro 使用了其中一些不受支持的构造。幸运的是,我们可以实现*替换*(直接替换代码中不受支持的构造)并使用 Quarkus 扩展来正确配置编译器。因此,您的应用程序无需进行任何配置,“它就是能用™️”。

让我们回到 Avro。Avro 使用 GraalVM 原生编译器不支持的方法句柄

为了解决 Avro 使用的不受支持的构造,我们实现了一组替换。我们将方法句柄替换为反射。

GenericDatumReader 也需要做一些工作,因为它在构建时会触及线程。

最后,在 Quarkus Avro Processor(Quarkus 扩展的一部分)中,我们将所有用@AvroGenerated注解的类注册为使用反射,因为我们使用反射来创建它们的新实例。

给我看看!

查看应用程序的代码,并确保您已安装 GraalVM。然后,使用以下命令构建原生可执行文件:

mvn package -Pnative

喝杯咖啡或茶,这可能需要几分钟时间

使用以下命令启动 Kafka 代理和 schema registry:

docker-compose up -d

最后,使用 `./target/kafka-and-avro-1.0.0-SNAPSHOT-runner` 运行应用程序。

向应用程序发送一些电影

curl --header "Content-Type: application/json" \
--request POST \
--data '{"title":"The Shawshank Redemption","year":1994}' \
https://:8080/movies

curl --header "Content-Type: application/json" \
--request POST \
--data '{"title":"The Godfather","year":1972}' \
https://:8080/movies

curl --header "Content-Type: application/json" \
--request POST \
--data '{"title":"The Dark Knight","year":2008}' \
https://:8080/movies

curl --header "Content-Type: application/json" \
--request POST \
--data '{"title":"12 Angry Men","year":1957}' \
https://:8080/movies

在应用程序日志输出中检查它们是否已成功处理

2020-12-02 11:06:32,699 INFO  [MovieResource] (executor-thread-1) Sending movie 12 Angry Men to Kafka
2020-12-02 11:06:33,230 INFO  [MovieConsumer] (vert.x-eventloop-thread-0) Received movie: 12 Angry Men (1957)
2020-12-02 11:07:01,325 INFO  [MovieResource] (executor-thread-1) Sending movie The Shawshank Redemption to Kafka
2020-12-02 11:07:01,345 INFO  [MovieConsumer] (vert.x-eventloop-thread-0) Received movie: The Shawshank Redemption (1994)
2020-12-02 11:07:01,350 INFO  [MovieResource] (executor-thread-1) Sending movie The Godfather to Kafka
2020-12-02 11:07:01,361 INFO  [MovieConsumer] (vert.x-eventloop-thread-0) Received movie: The Godfather (1972)
2020-12-02 11:07:01,368 INFO  [MovieResource] (executor-thread-1) Sending movie The Dark Knight to Kafka
2020-12-02 11:07:01,378 INFO  [MovieConsumer] (vert.x-eventloop-thread-0) Received movie: The Dark Knight (2008)
2020-12-02 11:07:01,388 INFO  [MovieResource] (executor-thread-1) Sending movie 12 Angry Men to Kafka
2020-12-02 11:07:01,396 INFO  [MovieConsumer] (vert.x-eventloop-thread-0) Received movie: 12 Angry Men (1957)

原生模式下的 Avro 支持仍处于实验阶段。在最新的 Quarkus 版本中,我们取得了重大进展,但可能仍有一些未覆盖的领域。如果您发现任何异常,请告知我们!