graal java_使用SparkJava和Graal的本机微服务
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的本机微服务的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 公司名怎么能被百度收录(女生喝什么酒不会
- 下一篇: 有域名和空间怎么建站(有域名如何建站)
