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

推薦する

ウェブサイトの最適化: 404 ページの作成方法と関連事項

SEO の経験が少しある SEO 担当者は、404 ページがウェブサイトで重要な役割を果たしているこ...

中国SNSは定着率の危機に直面、ユーザーの需要が変革の鍵に

インターネット トラフィック監視機関 ComScore は最近、2011 年グローバル ソーシャル ...

新しいサイトと高品質のフレンドリーリンクを交換する方法についての簡単な説明

ウェブサイトの重みが増すほど、交換されるリンクの品質も向上することは誰もが知っています。これは、ウェ...

SEOとeコマースの関係を探る

「電子商取引」という言葉は、2007 年にインターネット上で最もホットな言葉の 1 つになるはずです...

エッジコンピューティングにおける階層化セキュリティの重要性

この記事では、モノのインターネットにおける情報セキュリティの役割、そのアーキテクチャ、エッジコンピュ...

TOM、クレイジーなブラックハットSEO!

少し前に、TOM がブラックハット SEO を使用してキーワード「Audition」を最適化したとい...

rectified はどのように機能しますか? rectified.net VPS レビュー、KVM、無制限帯域幅 VPS

先日、「良い x: 修正済み - 年間支払い $12/KVM/1000M ポート/無制限トラフィック...

企業公式ウェブサイト構築の要素と注意点

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

ロングテールキーワードのタイトルを最適化する7つの個人的な経験

ロングテール キーワードがウェブサイトの最適化に含まれていないのではないかと心配していませんか? 退...

良いタイトルはあなたのウェブサイトに一生役立つでしょう。ウェブサイトのタイトルを最適化するにはどうすればよいでしょうか?

ユーザーにウェブサイトを訪問してクリックしてもらうにはどうすればよいでしょうか。検索エンジンの最適化...

Google、スマートフォン検索ランキングを変更

Googleの公式ブログによると、スマートフォンユーザーはインターネットユーザーの増加が最も著しい市...

キーワードレイアウトはどうすればいいですか?

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

vpscreed-クリスマススペシャル: 50% オフ/マネージド VPS/ダブルメモリ

年に設立された vpscreed は、ドイツと米国にデータ センターを持つインドの商人です。マネージ...

データクラブ: 6 ユーロ、スウェーデン/オランダ/リトアニア、KVM 仮想化、無制限帯域幅 VPS

dataclubは主にスウェーデン(ストックホルム)、リトアニア、オランダの3つのデータセンターで独...