graal java

使用SparkJava编写的微服务只是使用标准Java库的普通Java代码。 没有注释魔术,只有代码。 这种简单的编程风格的优点在于,它很简单。 非常简单,以至于Graal本机编译器只需编译就不会闪烁 ,这对于例如Spring之类的更复杂的框架而言,目前是非常困难的。

SparkJava / Graal组合本身就很有趣,人们对此的体验也开始 出现 。 此外,作为Java库,应该可以从其他基于JVM的语言中使用它,我想知道Graal将如何应对。 实际上,事实证明这很简单,在本文中,我们将看到为Java,Kotlin甚至Clojure构建本机微服务二进制文件非常容易。

入门

如果您还没接触过Graal,我建议您访问他们的网站 ,看看它提供了什么。 在这里,我们使用的是本机编译功能,但实际上这只是在摸索。

要首先使用Graal,您需要安装最新版本的Graal SDK。 撰写本文时为1.0.0-rc9 。 我使用SdkMan做到了 :

sdk install java 1.0.0-rc9-graal

从那时起

sdk use java 1.0.0-rc9-graal

然后创建一个基本的Gradle项目并添加最小依赖项:

dependencies {compile "com.sparkjava:spark-core:2.7.2"compile "org.slf4j:slf4j-simple:1.7.13"
}

(我假设您已经熟悉Gradle,如果愿意的话,可以使用Maven进行 。请注意,选择的Slf4j实现与SparkJava所需的版本匹配非常重要。)

在SparkJava中,微服务端点本质上是lambda表达式形式的路径或回调之间的绑定或route 。 这是我们将用作基础的标准“ hello world”示例。 当然,现实世界中的服务将利用请求和响应对象。 请参阅文档以获取更多详细信息。

import static spark.Spark.*;public class HelloWorld {public static void main(String[] args) {get("/sayHello", (req, res) -> "Hello world!");}
}

要将其作为命令行程序运行,将所有依赖项一起复制到同一目录中非常方便。 我们也可以使用Gradle做到这一点。

task copyDependencies(type: Copy) {from configurations.defaultinto 'build/libs'shouldRunAfter jar
}assemble.dependsOn copyDependencies

生成服务并运行它以检查其是否有效。

> ./gradlew clean assemble
> java -cp "build/libs/*" HelloWorld
...
[Thread-0] INFO org.eclipse.jetty.server.Server - Started @363ms
> curl localhost:4567/sayHello
Hello World!

让我们使用Graal将其编译为本地二进制文件。 幸运的是,该命令与java命令非常相似:

> native-image -cp "build/libs/*" HelloWorld
...
Build on Server(pid: 31197, port: 52737)*
[helloworld:31197]    classlist:   2,142.65 ms
[helloworld:31197]        (cap):   2,154.21 ms
...
...
[helloworld:31197]        write:     443.13 ms
[helloworld:31197]      [total]:  56,525.52 ms

现在,我们应该在当前目录中拥有本机二进制文件。 让我们运行它:

> ./helloworld
...
[Thread-2] INFO org.eclipse.jetty.server.Server - Started @2ms
> curl localhost:4567/sayHello
Hello World!

可执行文件为14Mb,但看该启动时间2ms基本上是瞬时的! 从内存角度讲,过多地关注top是不明智的,但是很明显,从运行时删除JVM具有其优势。 这在部署大量独立进程的微服务系统中尤其重要。

Kotlin呢?

Kotlin是一种JVM语言,正在Swift发展并且并非没有道理。 它结合了功能样式和OO功能,无缝的Java互操作性和简洁的语法,使其成为通用的良好语言,并且是Java的明显替代。 首先要使用Kotlin构建我们的服务,我们将Kotlin库依赖项添加到Gradle(撰写本文时版本为v1.3.10)。

dependencies {
...compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.10"
}

并使用Kotlin编译器插件。

plugins {id 'org.jetbrains.kotlin.jvm' version '1.3.10'
}

使用Kotlin,我们荒唐的简单微服务变得更加简单。

import spark.Spark.*fun main(args: Array<String>) {get("/sayHello") { req, res -> "Hello World!" }
}

生成服务并运行它以检查其是否有效。

> ./gradlew clean assemble
> java -cp "build/libs/*" HelloWorldKt
...
[Thread-0] INFO org.eclipse.jetty.server.Server - Started @363ms
> curl localhost:4567/sayHello
Hello World!

让我们本地编译它。 因为它 Java,所以命令几乎与Java版本相同(Kotlin编译器会自动将Kt后缀添加到生成的类中)。

> native-image -cp "build/libs/*" HelloWorldKt
Build on Server(pid: 53242, port: 51191)
[helloworldkt:53242]    classlist:     783.03 ms
[helloworldkt:53242]        (cap):   2,139.45 ms
...
[helloworldkt:53242]        write:     591.88 ms
[helloworldkt:53242]      [total]:  53,074.15 ms

并运行它:

> ./helloworldkt
...
[Thread-2] INFO org.eclipse.jetty.server.Server - Started @2ms
> curl localhost:4567/sayHello
Hello World!

可执行文件的大小和启动速度几乎与Java版本相同,这是可以预期的,因为它实质上是相同的代码。

这是一个基本示例,但Kotlin实现简化SparkJava简化 实现 微服务Graal简化部署相结合,对于微服务开发而言是一个非常诱人的主张。

尽管如此,除了更好的语法外,Kotlin与Java非常相似。 我们还可以使用其他JVM语言,这些语言可能会进一步推动Graal。

需要Clojure

使用Clojure构建微服务是一个有趣的想法。 服务本质上是自然的功能,实际上服务一种功能,语言的动态特性可能使其成为某些以数据为中心的情况的理想选择。

而不是使用Gradle,我们将从一个新的Leiningen项目开始:

lein new hello-clojure

依赖关系放在main project.clj文件中,以及我们将用来启动服务器的主类的名称。

:dependencies [[org.clojure/clojure "1.9.0"][com.sparkjava/spark-core "2.7.2"][org.slf4j/slf4j-simple "1.7.13"]]:main hello_clojure.core)

Clojure可与Java互操作,但程度不及Kotlin。 为了克服这些差异,我编写了一些适配器,以允许惯用的clojure代码使用SparkJava的类。

(ns hello_clojure.core(:gen-class)(:import (spark Spark Response Request Route)))(defn route [handler](reify Route(handle [_ ^Request request ^Response response](handler request response))))(defn get [endpoint routefn](Spark/get endpoint (route routefn)))

(后来我发现了一篇不错的文章 ,其中提供了使用Clojure和SparkJava的完整服务。它们的适配器比我的适配器稍好,因此我在后面的文章中结合了一些想法。)

然后,我们准备创建从main方法执行的控制器,以便可以从命令行轻松调用它。 还要注意,在上面我们使用gen-class指令来确保在清单中指定了主类:

(defn -main [](get "/sayHello" (fn [req resp] "Hello World!!")))

为了简化服务的生成,我们可以使用Leiningen构建一个自包含的jar。

> lein clean && lein uberjar

和以前一样,我们首先检查该服务是否可以正常运行Java:

$ java -cp target/hello-clojure-0.1.0-SNAPSHOT-standalone.jar hello_clojure.core
...
[Thread-0] INFO org.eclipse.jetty.server.Server - Started @1033ms
> curl localhost:4567/sayHello
Hello World!

编译为本地映像就像使用Java和Kotlin的先前示例一样简单。

> native-image -cp target/hello-clojure-0.1.0-SNAPSHOT-standalone.jar hello_clojure.core
Build on Server(pid: 35646, port: 53994)*
[hello_clojure.core:35646]    classlist:   2,704.82 ms
[hello_clojure.core:35646]        (cap):     909.58 ms
...
[hello_clojure.core:35646]        write:     647.23 ms
[hello_clojure.core:35646]      [total]:  54,900.61 ms

并运行它:

> ./helloworld_clojure
...
[Thread-2] INFO org.eclipse.jetty.server.Server - Started @2ms
> curl localhost:4567/sayHello
Hello World!

本地二进制文件再次大约为15M,并且启动时间几乎是瞬时的。

结论

将Graal与其他基于JVM的语言结合使用是一个非常诱人的主张,值得进一步研究,但是我确实对生产用途存在一些担忧。 主要是如果出现问题,公共领域中几乎没有什么信息可以为您提供帮助,而纯Java之外的信息则更少。 另一方面,这些都是开源项目,所以什么都没有隐藏:)

另一个限制是,许多库根本无法与Graal一起使用。 这并不是完全消极的,因为它会鼓励我们回到简单的编码实践中,但是您可能会遇到无法更改的依赖关系,这可能会造成很大的麻烦。 我认为最初的主要缺点是反射驱动的映射,无论是序列化还是ORM品种。 为了使许多库和框架与Graal 兼容 ,已经进行了很多工作,但是还处于初期。

第三,主要是实际的考虑是对原始映像的编译非常慢。 即使是这个非常简单的示例,也几乎需要花费一分钟的时间来构建。 当然,您可以仅将开发编译为字节码,但是兼容性问题可能会消失。 持续的构建流程和全面的测试将是减轻这种风险的一种方法。

显然,要使它成为一个功能齐全的服务还有许多工作要做,并且在投入生产使用之前要进行适当的考虑,但是如果我们选择继续使用简单的代码,那么问题将被最小化。

翻译自: https://www.javacodegeeks.com/2019/01/native-microservices-sparkjava-graal.html

graal java

graal java_使用SparkJava和Graal的本机微服务相关推荐

  1. 使用SparkJava和Graal的本机微服务

    使用SparkJava编写的微服务只是使用标准Java库的普通Java代码. 没有注释魔术,只有代码. 这种简单的编程风格的优点在于,它很简单. 非常简单,以至于Graal本机编译器无需闪烁就可以对其 ...

  2. graal java_如何在CircleCI上构建支持Graal的JDK8?

    graal java 引用:博客上的专题图片可以在flickr上找到,并由Luca Galli创建. 以下部分之一中的图像也可以在flickr上找到,并由fklv(过时的时髦)创建. GraalVM编 ...

  3. java b2b 开源_springcloud微服务多用户商城系统java_代码开源_B2B电商系统_B2C电商系统...

    Spring Cloud是一系列框架的有序集合.利用Spring Boot的开发模式简化了分布式系统基础设施的开发,如服务发现.注册.配置中心.消息总线.负载均衡.断路器.数据监控等(这里只简单的列了 ...

  4. docker 部署java_使用Docker堆栈部署的微服务-WildFly,Java EE和Couchbase

    docker 部署java 关于微服务的资料很多,只是用谷歌搜索就可以了 ! 几年前,我在比利时的Devoxx上发表了有关将单片重构为微服务的演讲,它获得了很好的评价: 该博客将展示Docker如何简 ...

  5. 腾讯 tars java_腾讯TARS开源团队郑苏波:腾讯微服务开发框架的源码剖析

    郑苏波:大家下午好!我是腾讯微服务的郑苏波.先做一个框架的介绍,Tars是一个支持多语言内嵌服务治理功能的框槛,能跟DevOps比较好的协同开发.这个框架四大特点: 一是对用户透明实现,让业务可以聚焦 ...

  6. mockwebserver java_在Java中使用WireMock和SOAP Web服务

    我是WireMock的创造者. 我最近使用WireMock在客户端项目上模拟了SOAP接口的集合,所以我可以证明它是可能的.至于它是否比SOAP UI更好或更差,我会说有一些明确的好处,但有一些权衡. ...

  7. go兼容java_兼容dubbo的微服务框架dubbogo;dubbo的完整go语言实现

    1 说明 一个支持 dubbo 协议的 go 微服务框架:dubbo 的完整 go 语言实现dubbogo,以及其代码示例dubbogo-examples. 2 feature v0.2 featur ...

  8. 毛刺现象 java_记一次微服务耗时毛刺排查

    点击蓝字关注这个神奇的公众号- 前段时间的某天,注意到一个服务的平均耗时出现了如下图的毛刺现象. 注意到毛刺出现极其规律,每30分钟出现一个毛刺.考虑到这种规律性,并结合服务的流量较小(20 QPS) ...

  9. 基岩版刷铁傀儡机制和Java_我的世界:刷铁机没有傀儡只刷猫?作为基岩版玩家,你的痛我都懂...

    刷铁机是<我的世界>生存模式中必不可少的自动农场,建造优先度与刷怪塔齐名.java版的刷铁机效率高超但运输僵尸的环节会花费玩家大量的时间,而基岩版虽然无需运输僵尸,但它的效率较低,加上村庄 ...

最新文章

  1. Camera框架初探
  2. reserve和resize - 力为的技术博客 - C++博客
  3. 2springboot:快速创建springboot项目
  4. 电脑删除的文件怎么恢复?你要找的方案
  5. Spring EclipseLink NoSQL - 使用MongoDB和Oracle NoSQL DB构建
  6. PTA19、通过两个列表构建字典 (10 分)
  7. 全球 Python 调查报告:Python 2 正在消亡,PyCharm 比 VS Code 更受欢迎!
  8. 算法列表-java实现
  9. c++ 后台 sendstring_苹果狂杀微信后台,微信官方出必杀技!
  10. 美团知识图谱问答技术实践与探索
  11. Android Hessian 通信
  12. (笔记)涉及到的WinAPI函数
  13. GAMP学习-函数流程图调用(部分)(一)
  14. 微信H5开发wx.config授权invalid signature
  15. java 正则 标点符号_js实现正则匹配中文标点符号的方法
  16. Accessorize to a Crime: Real and Stealthy Attacks on State-of-the-Art Face Recognition
  17. 稳定版正式发布 | 用 Flutter 构建 Windows 桌面应用程序
  18. harmonyos蓝牙,鸿蒙OS 蓝牙概述
  19. QuickCam Gev 2.0 开发
  20. 什么是极大似然估计?

热门文章

  1. CodeForces 1610H Squid Game(延迟贪心 + 构造 + 树状数组)
  2. [AtCoder Regular Contest 125] A-F全题解
  3. 9.27模拟:至暗时刻
  4. P3302-[SDOI2013]森林【主席树,LCA,启发式合并】
  5. P3369-[模板]普通平衡树【替罪羊树】
  6. nssl1155-遨游【二分答案,SPFA】
  7. JSP的<c:foreach/>标签只输出一次标签体内容的坑
  8. ​通俗理解神经网络BP反向传播算法
  9. 违反ClassLoader双亲委派机制三部曲第二部——Tomcat类加载机制
  10. JVM-对象的存活与死亡