クラウドネイティブ時代は 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 サービスステータスのトラブルシューティング

推薦する

権威ある外部リンクを公開する最新の方法 - A5 Webmaster Network

外部リンクの品質は、検索エンジンにおけるウェブサイトの重みを直接決定します。これは、ウェブサイトの重...

クラウド コンピューティングに切り替える理由は何ですか?

AWS、Google Cloud、Microsoft Azure などのパブリック クラウド サービ...

人気のブログコミュニティを作る5つの方法

ご存知のとおり、ブログは今や広く人々に利用されています。人々はブログを通じて自分の気持ちや生活を自由...

百度の新しいアルゴリズム: フォーラムの署名とQ&Aの外部リンクの重要性が低下

今日はこの記事を皆さんと共有できてとても嬉しいです。中国の検索エンジン市場は急速に発展しています。B...

kvmla: 20% オフ - シンガポール VPS、日本 CN2 + ソフトバンク VPS、15% オフ - シンガポール cn2、日本 cn2 専用サーバー

kvmla (2011~) 年末プロモーションが始まりました: (1) シンガポール VPS、100...

SEO基準を満たすウェブサイトのホームページのタイトルの書き方

2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っていますSEO 基...

草の根ウェブマスターのサイト運営の重要な部分:訪問者との交流

草の根ウェブマスターにとって、「草の根ウェブマスター」という言葉は、インターネットビジネスを始めると...

4月の世界ウェブサーバー市場シェア:マイクロソフトが33.04%に増加し、Apacheに迫る

IDC Review Network (idcps.com) は 4 月 17 日に次のように報告し...

業界で人気のKubernetesディストリビューション10選

大規模なコンテナ オーケストレーションが必要な場合、Kubernetes が間違いなく最初の選択肢と...

内河SEO共有:ウェブサイトスナップショット関連知識分析

スナップショットの更新は、多くの SEO 担当者や個人ウェブマスターにとって常に関心事です。実際、B...

SaaS を実行するときに不安を回避するにはどうすればよいでしょうか?

1. 一生懸命働けば働くほど、不安は増しますか?海外のSaaS市場は急速に発展しており、企業の時価総...

App Store 中国、検索アルゴリズムを最適化:名前による検索を復活

8月24日、約1週間の不安が去った後、国内のiOSアプリケーション開発者はようやく落ち着きを取り戻し...

Fanhuan.com の生存モデル: 差別化された価格設定による利益率の確保

fanhuan.com の創設者、陳芳一氏リターンネットワーク【Eコマースサンプル】時間は長い川です...

インターフェース監視用の Prometheus エクスポーターを開発する

ブラックボックス監視については皆さんもよくご存知だと思います。ブラックボックスの監視には black...

2021 年に主流になるクラウド コンピューティング テクノロジーはどれでしょうか?

市場の需要はイノベーションを促進し、ビジネス モデルに新たな変化をもたらします。そのため、COVID...