クラウドネイティブ時代は Java か Go か?

クラウドネイティブ時代は Java か Go か?

Java のかつての有名なモットー、「一度書けばどこでも実行できる」は、今ではコンテナ内でコードを実行するだけなので、時代遅れになっています。コンテナでは、「ジャストインタイム」コンパイラはあまり意味がありません。

このため、そしておそらくクラウド コンピューティングへの適応性を高めるために、Java エコシステムは変革の真っ只中にあります。 Oracle の GraalVm を使用すると、バイトコードを Linux 実行可能ファイル (ELF) にコンパイルできます。一方、Rad Heat の Quarkus やその他のフレームワークは、応答性の高いサービスを容易にすることを目的としています。 Quarkus は Netty と Vertx.x に基づいており、非常に効率的で応答性の高い Web サービスを構築するために使用できます。

Java は実行可能なバイナリ ファイルにコンパイルされ、数ミリ秒で起動し、メモリをほとんど使用しません。これにより、Java エコシステムを活用し、Scala や Kotlin などの他の JVM 言語で記述することもできます。オンライン プロジェクト ジェネレーターを使用して Quarkus を試したり、Maven プラグインを使用してローカルでプロジェクトを生成したりできます。

一方、Golang はクラウド用に生まれたため、コンテナ内で実行してもレガシーな問題はありません。クラウドのプログラミング言語として考えられています。生成されたバイナリ実行ファイルは小さく、起動が速く、メモリをほとんど消費しません。これは、Go が誕生して以来備わっている機能です。 Golang の人気は Java の世界に深刻な課題をもたらしました。

Javaにチャンスはあるでしょうか?おそらく、最終的な答えは時間だけが教えてくれるでしょう。しかし、好奇心から、Java と Golang のクラウドネイティブ サービスをパフォーマンスと開発体験の観点から比較したいと思いました。

この記事では、同じサービスを2つの言語で記述します。 CPU 使用率、RAM、レイテンシ、動作速度を比較します。これらのサービスは、同じリソース割り当てを持つコンテナで起動され、ab を使用してテストされます。

これは私のケースでは「十分に良い」ベンチマークです。これは、最良/最悪のベンチマーク結果を見つけることを想定しているのではなく、比較のために同じ環境で両方のベンチマークを実行することを想定しているからです。

シナリオ

これら 2 つのサービスは、1 つのテーブルと 3 行のデータを持つ、別のコンテナーで実行されている MySQL データベースに接続します。

各サービスはすべてのレコードを取得し、オブジェクトに変換して、JSON 配列を出力します。

ab は同時実行レベル 100 で 10K のリクエストを発行し、quarkus JVM バージョンは 2 回実行されます (「コールド」/「ウォーム」JVM をテストするため)。

Go言語バージョン

Go 言語バージョンでは、gin フレームワークを使用します。

  1. # サービス
  2. パッケージメイン
  3.  
  4. 輸入 (
  5. 「データベース/SQL」  
  6. 「fmt」  
  7. 「github.com/gin-gonic/gin」  
  8. _ "github.com/go-sql-driver/mysql"  
  9. 「ネット/http」  
  10.  
  11. フルーツ構造体型{
  12. ID int `json: "id" `
  13. 名前文字列 `json: "name" `
  14. }
  15.  
  16. var con *sql.DB
  17.  
  18. 関数init(){
  19. //別のコンテナとのmysql接続プールを開く
  20. db、エラー:= sql。開く( "mysql" "root:password@tcp(host.docker.internal:3306)/payments" )
  21. err != nil の場合 {
  22. panic( "mysql接続を開けませんでした" )
  23. }
  24. コン = デシベル
  25. }
  26.  
  27. 関数main() {
  28. r := gin.Default ()です。
  29. r.GET( "/果物" , 果物)
  30. r.Run() // 8080サーバーを起動
  31. }
  32.  
  33. // リクエストハンドラ
  34. func fruit(c *gin.Context) {
  35. 果物:= getFruits()
  36. c.JSON(http.StatusOK、果物)
  37. }
  38.  
  39. getFruits()関数 []フルーツ{
  40. 、_ := con.Query( "SELECT * FROM 果物" )
  41. フルーツ := []果物{}
  42. のために 行.次へ( ) {
  43. var r フルーツ
  44. .Scan(&r.Id, & r.Name )
  45. 果物 = append(果物, r)
  46. }
  47. 果物を返す
  48. }

Golang の MySQL ドライバーは go-sql-driver を使用します。 Golang のコーディングスタイルは非常に明確です。すべてが見えるという姿勢。メイン関数はサーバーを起動し、リクエスト ハンドラーを構成し、DB 接続を開きます。

ローカル実行ファイルをコンパイルする

Kotlin バージョン

  1. パッケージ org.acme
  2. io.vertx.core.json.JsonArray をインポートします。
  3. io.vertx.core.json.JsonObject をインポートします。
  4. io.vertx.mutiny.mysqlclient.MySQLPool をインポートします。
  5. io.vertx.mutiny.sqlclient.Row をインポートします。
  6. io.vertx.mutiny.sqlclient.RowSet をインポートします。
  7. java.util.concurrent.CompletionStage をインポートします。
  8. javax.inject.Inject をインポートする
  9. javax.ws.rs.GET をインポートする
  10. javax.ws.rs.Path をインポートする
  11. javax.ws.rs.Produces をインポートする
  12. javax.ws.rs.core.MediaType をインポートします。
  13.  
  14. @Path( "/果物" )
  15. クラス FruitResource {
  16. @フィールド:挿入
  17. lateinit var client: MySQLPool
  18.  
  19.  
  20. @得る
  21. @Produces(メディアタイプ.APPLICATION_JSON)
  22. 楽しいリストフルーツ(): 完了ステージ<JsonArray> {
  23. client.query( "SELECT * FROM fruit" )を返します実行する()
  24. .map {: RowSet<行> ->
  25. .fold(JsonArray()) { 配列、行 ->
  26. 配列.add (JsonObject()
  27. .put( "id" 、row.getLong( "id" )) は、
  28. .put( "名前" , row.getString( "名前" )))
  29. }
  30. }.subscribeAsCompletionStage()
  31. }
  32. }

データベース接続には、Quarkus React Mysql 拡張機能が使用されます。

CDI 依存性注入、javax アノテーションを使用した宣言型ルーティング、自動構成解決、データソース/接続作成/サーバー ブートストラップなど、コードは Go バージョンとはかなり異なります。これはフレームワークを使用する際の代償であり、フレームワークがあなたに代わって面倒な作業を実行し、物事の実行方法を決定します。ただし、go バージョンのコードよりもはるかに短くなります。

ここでは、Vert.x マルチイベント ループでラップされた Netty リアクティブ Web サーバーと、Vert.x リアクティブ MySQL ドライバーを使用して、1 つのスレッドで複数の DB 接続を処理できるようにします。

あるいは、Kotlin のコレクション ライブラリの fold 関数を使用することもできますが、これにはまだ一般的な Go バージョンがありません。

実行ファイルのJavaバージョンをコンパイルする

ビルド プロセスで何が起こっているのかがわかりましたが、その中心にあるのは SubstrateVM です。これは、AOT プロセスに埋め込み可能な仮想マシンとして設計されており、コードにリンクされ、ユニットとしてコンパイルされます。しかし、Oracle によれば、SubstrateVM は HotSpot VM よりも最適化が少なく、ガベージ コレクターもシンプルです。

この AOT コンパイラは「Graal」と呼ばれ、言語に依存しません。 Java バイトコードは中間表現 (Truffle 言語) に変換する必要があります。これについては、GraalとTruffleに関するこの記事[1]で確認できます。

Java ネイティブ実行可能ファイルの構築はより複雑で、コンパイルが遅く、Go バージョンのほぼ 2 倍の大きさのバイナリが生成されます。ただし、35 MB の実行可能バイナリ ファイルは、Java FatJar よりはるかに小さいです。 35MB あれば、AWS Lambda を使用して実行することもできます。

ストレステスト

次の設定で、ローカル マシン上ですべてのテストを実行します。

  • MacBook Pro (15インチ、2017)
  • 2.9GHz Intel Core i7(8コア)。
  • 16 GB 2133 MHz LPDDR3

cAdvisor のツールを使用してコンテナの統計を監視します。

シナリオ

  • Quarkus JVM ホットスポット
  • Quarkus Javaネイティブ
  • Go言語

上記の各ケースは、次の 3 つの構成でテストされました。

  • 100MB / 0.5CPU | 200MB / 1CPU | 300MB / 2CPU

私が主に関心を持っているのは以下の点です。

  • CPU/RAM 使用率 (マルチコア使用率)
  • CPU/RAM ピーク
  • CPU/RAM空き容量
  • 起動時間
  • 応答遅延の平均/最大
  • スループット(1秒あたりのリクエスト数)

テスト結果

Quarkus は実稼働環境に対応しており、JVM/ネイティブ リリース/開発モードが簡単に使用でき、ネイティブ テストをローカルで実行できるようになっているようです。リフレクションや JNI を使用しない限り、GraalVM の構成に応じてこれが可能です。それ以外の場合は、Graal コンパイラを自分で構成する必要がありますが、これにも解決策があります。

レイテンシとスループット

Golang とネイティブ Java のテスト結果は非常に近いですが、平均すると Golang バージョンの方がわずかにパフォーマンスが優れています。ただし、Java ネイティブ バージョンのテスト結果はより安定しています。 Golang サービスは 1.25μs 以内に応答することもあります。しかし、完了するまでに 7 秒かかることもあります。

「ウォームアップ」された JVM バージョンの結果も悪くはありませんが、ネイティブ バージョンや Go バージョンに比べるとわずかに劣ります。

CPU使用率

Go と native-java はどちらも、0.5 コアを使用すると負荷がかかったときのパフォーマンスが低下するようで、2 コアで開始しても大きな改善は見られません。これは、ワークロードが IO によってボトルネックになっていることが原因である可能性があります。あるいは、gin/Netty のデフォルト設定ではマルチコアの問題が考慮されていないことが原因である可能性があります。

一方、JVM バージョンでは、与えられたすべてのコアを活用し、あらゆる面でパフォーマンスが向上します。

メモリ使用量

ストレス下では、Java ネイティブは 40MB を使用し、Golang は 24MB を使用します。どちらの場合も悪くありませんが、Golang バージョンではほぼ 2 倍のメモリを使用します。

JVM は 140MB を使用しました。 Quarkus の公式統計と全く同じです。 JVM としては悪くないですが、Golang バージョンと比べると 6 倍近くになります。

起動時間

Golang とクラウドネイティブ Java はどちらも即座に起動しますが、JVM バージョンでは数秒かかり (割り当てられた CPU によって異なります)、起動時に CPU スパイクが発生します。適切に構成されていない場合、k8s HPA が爆発的に増加し、ポッドの数が増加します。

開発経験

これは実用的な問題というよりも宗教的な問題です。 Quarkus は、Java の世界で一般的な抽象化 (アノテーションベースの DI など) を使用します。サーバーを起動し、接続プールを作成します。コレクションとジェネリックの豊富な標準ライブラリを使用できます。しかし、これは少し黒魔術のように感じられることもあり、何かが機能しなくなると無力感を感じることがあります。さらに、Java コードをネイティブ バイナリにコンパイルするのはそれほど簡単ではありません。注意しなければならない制限と考慮事項がいくつかあり、すべての Java ライブラリがネイティブ コンパイルと互換性があるわけではありません。互換性のないライブラリ (Guice など) を使用するとすぐに、Graal VM を自分で構成する必要があります。

Quarkus と Graal VM は「比較的」新しいものです。したがって、いくつか問題がある可能性があります。ただし、デュアル モード (JVM またはネイティブ) のためです。ネイティブ バージョンの一部のコンポーネントが動作しなくなった場合に備えて、フォールバックが常に用意されており、これは新しい問題に対する優れた回避策となります。

一方、Golang では、ジェネリックが必要であることを認めるまでに、誕生から 10 年かかりました。そして、フレームワークが多くの魔法の操作を使用するのは確かに好ましくありません。これは多くの点で良いことでもあり、悪いことでもあります。さらに、Go コミュニティは素晴らしい仕事をしていますが、利用できるツールやライブラリは比較的少ないです。ただし、コンパイルとビルドのプロセスはより高速かつ簡単です。また、すべての Golang パッケージと互換性があり、Java ネイティブ プラットフォームによってもたらされる制限はありません。

結論は

Java はクラウドネイティブに対応しており、Golang もそれほど先を進んでいません。今後、クラウドネイティブJavaが大規模に利用されるようになると考えています。

元のアドレス: https://medium.com/swlh/cloud-native-java-vs-golang-2a72c0531b05

この記事はWeChatの公開アカウント「高可用性アーキテクチャ」から転載したものです。以下のQRコードからフォローできます。この記事の転載については、Igor Domrevの公式アカウントまでご連絡ください。

<<:  Spring Boot Redis は分散ロックを実装しているので、とても良いです! !

>>:  OpenStack Cinder サービスステータスのトラブルシューティング

推薦する

Kubernetes をより良くする 11 個のツール

[51CTO.com クイック翻訳] 強力で大規模なものであっても、すべてのニーズを満たすことができ...

身代金 - 5 ドル / Kvm / 512m メモリ / 10g ハードディスク / 200g トラフィック / オーストラリア

ransomit は 2008 年からホスティング サービスに従事しており [資格を確認してください...

オンサイト最適化に関する重要な知識をまとめる

ウェブサイト構築において最適化は非常に重要です。競争力を高めるために、多くのウェブサイトが最適化対策...

Max Movie Programを使用して最適化する方法

最適化のために Max Movie Program を使用する方法 - 私のような SEO 初心者向...

おすすめ: Bluehost - 年間 12 ドル - 感謝祭/ブラックフライデー/サイバーマンデー

Bluehost は現在、米国最大の仮想ホスティング会社です。10 年以上の歴史があり、EIG コン...

最近の考え:中規模・大規模ウェブサイトのコンテンツ構築について

短い考えを見ると、自然にいくつかの発散した考えや、最近感じたことの組み合わせなど、外部とのつながりが...

ユーザーが積極的にウェブサイトにアクセスしているかどうかを検索エンジンがどのように判断するかを簡単に分析します。

最近、百度ウェブマスタープラットフォームは「ウェブマスターが見落としがちなコンテンツ:ユーザーデータ...

アリババクラウドのビッグデータプラットフォームODPSが2022年の世界有数のインターネット科学技術成果の一つに選ばれました

11月9日、世界インターネット会議烏鎮サミットにて、2022年世界インターネット先端科学技術成果発表...

エッジコンピューティングの6つの特徴

1. エッジコンピューティングとは何ですか?エッジ コンピューティングとは、ネットワーク、コンピュー...

概要: 2012 年 5 月 4 日の Google PR 値の更新

tui56フォーラムの王宝塵さんのように、GoogleのPR値の更新を待っているウェブマスターは間違...

このツールは素晴らしいです!ルート権限なしでXposedフレームワークの仮想ツールを直接使用する

[[419583]] Android は Apple の iOS よりもプレイしやすいとよく言われま...

#期間限定# hostodo-年間30ドル/メモリ4g/コア4個/ハードドライブ150g/トラフィック5T/ロサンゼルス

Hostodo は、ロサンゼルス、ダラス、マイアミのデータ センターで利用できるハイエンド VPS ...

hostsolutions: 50 ユーロ/3 年、KVM/512M メモリ/1 コア/1T ハードディスク/5T トラフィック、ノルウェー、ルーマニア

Hostsolutions はノルウェーにデータセンターを新たに開設し、大容量ハードドライブ VPS...

ウェブサイトのデザインが失敗する原因とは?ユーザーエクスペリエンスの「アンチパターン」について簡単に説明します

ウェブサイトのユーザーとして、ウェブサイトを使用する際に時々煩わしい点があることに気付くかもしれませ...

新しいサイトの内部ページを迅速に収集するための計画

新しい Web サイトの非常に明白な特徴は、通常、ホームページが最初にインデックスされ、その後少し長...