クラウドネイティブJavaとGolang

クラウドネイティブJavaとGolang

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

このため、Java エコシステムは、クラウドにより適合するように変革している最中である可能性があります。 Oracle の GraalVm を使用すると、バイトコードを Linux 実行可能ファイル (ELF) や Rad Heat の Quarkus などのフレームワークにコンパイルできるため、React アプリケーションのブートストラップと同じくらい簡単に実行できます。 Quarkus は、非常に効率的でレスポンシブな Web サービスを構築するために、Netty と Vertx.x をコアとして使用します。


> quarkus 公式パフォーマンス統計

Java は、数ミリ秒で起動し、メモリフットプリントが小さい実行可能バイナリにコンパイルされます。これにより、Java エコシステムを活用でき、Scala や Kotlin などの他の JVM 言語で記述することもできます。

信じられないほど良い話ですね…

信じられない場合は、オンライン プロジェクト ジェネレーターを使用するか、Maven プラグインを使用してローカルでプロジェクトを生成して、Quarkus を試してみることができます。

一方、Golang はクラウドで生まれたため、コンテナ内で実行しても何も変わりません。クラウドのプログラミング言語として考えられています。小さなバイナリ、高速起動、小さなメモリフットプリントは、最初から求められていたものです。そしてそれは広く採用されています。 Java の世界にとって重大な課題です。

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

この投稿では、2つのサービスを紹介します。 CPU、RAM、レイテンシ、稼働時間を比較します。サービスは、同じリソース割り当てを持つコンテナ内で起動され、Apache ベンチマークによって厳しいテストが行​​われます。

これは私のケーススタディにとって「十分に良い」ベンチマークです。私は最良/最悪のベンチマーク結果を見つけることではなく、同じ環境で実行された 2 つのベンチマークを比較することだと考えています。

シナリオ

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


> データベース

各サービスは 3 つの行すべてを取得し、それらをドメイン オブジェクトに変換してから、JSON 配列応答を書き込みます。

Apache ベンチマークは、同時実行レベル 100 で 10K リクエストを実行します。これは、quarkus JVM バージョン (「コールド」/「ホット」JVM のテストにも使用されます) の 2 倍です。


> Apacheベンチマークコマンド

Golang サービス

優れたベンチマークを持つ、人気のリアクティブ Web フレームワーク gin を使用します。

golang のノンブロッキング MySQL ドライバーを探していたところ、何も見つからなかったのですが、インターネットでは go-sql-driver も使用することを提案されていたので、これを使用することにしました。

golang スタイルは非常に明確です。正面からぶつかる態度。メイン関数はサーバーを起動し、リクエスト ハンドラーを構成し、データベース接続を開きます。

ネイティブ Go 実行ファイルをビルドする


> 簡単で高速なビルドプロセス。使用しなければならなかった唯一のツールは、go コンパイラでした。全然慌てる必要ありません。

Kotlin クラウド ネイティブ サービス — Quarkus

これは、quarkus reactive MySql 拡張ガイドにほぼ従った Kotlin の例です。


> データソース構成

Go バージョンと比較すると、暗黙的な要素、CDI 依存性注入、javax アノテーションを使用した宣言型ルーティング、自動構成解決、データソース/接続作成/サーバー ブートストラップなどがあります。しかし、それはフレームワークを使用することの代償であり、フレームワークがあなたに代わって大変な作業を行い、どのように動作するかを決定します。ただし、黒魔術を気にしない限り、Go バージョンよりもはるかに短くなります。

内部的には、Vert.x マルチイベント ループでラップされた Netty リアクティブ Web サーバーがあり、Vert.x リアクティブ MySQL ドライバーは単一のスレッドで複数のデータベース接続を処理できます。

また、Kotlin の素晴らしいコレクション ライブラリを使用してリストを折りたたむことができますが、Go バージョンにはまだジェネリックがなく (ただし、近々登場します)、豊富な標準コレクション ライブラリがないため、手動で記述または生成する必要がありました。

Javaネイティブ実行ファイルの構築


> 4分かかりました。これはGradleがLinux Graa内でネイティブイメージのコンパイルを実行するためです。

基本的に私が理解できたのは、ネイティブ実行可能ファイルをビルドするコンテナー内で何が起こるか、つまり SubstrateVM です。事前にコンパイルされるように設計された埋め込み可能な仮想マシンがコードにリンクされ、ユニットとしてコンパイルされます。これは素晴らしいことですが、コストがかからないわけではありません。Oracle によると、SubstrateVM は HotSpot VM よりも最適化が少なく、ガベージ コレクターもシンプルです。

これを実行するコンパイラは「Graal」と呼ばれ、言語に依存しません。Java バイトコードを使用する前に、中間表現である Truffle 言語に変換する必要があります。これは非常に興味深いもので、Graal と Truffle の詳細な説明はこの記事でご覧いただけます。

Java ネイティブ イメージの構築はより複雑で、時間がかかり、生成されるバイナリのサイズもほぼ 2 倍になります。しかし、それは機能します!これは実際に、35 MB の実行可能バイナリと、簡単に 10 倍の大きさになる可能性がある Java Uber (fat) Jar とを比較したものです。 35MB は AWS Lambda にも収まります。

サービス重視

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

使用に適さないもの:

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

コンテナの状態を監視するには、cAdvisor というツールを使用します。

シナリオ

  • Quarkus JVM ホットスポット コンテナ
  • quarkus Java ネイティブ コンテナ
  • Golang コンテナ

それぞれに以下のリソースが割り当てられます

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

私は…に興味があります。

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

ここで、多くのベンチマークを実行し、各ベンチマークごとに多くのデータ ポイントを収集します。情報が多すぎる場合は、要約の最後まで読み飛ばしてください。

この実験のgithubリポジトリとすべてのコードはここにあります

quarkus jvm ホットスポット — 100MB / 0.5 CPU

  • アイドルCPU使用率0.25%
  • 空きRAM使用量 66MB
  • ブートストラップ時間 6秒

> ブートストラップ中の CPU 使用率。 (スパイク、おそらく JIT + JVM の起動)

ストレステストの第 1 ラウンド (Cold JVM)

驚いたことに、失敗したリクエストはありません。


> ストレス時の CPU 使用率。

> RAM は 60 MB からほぼ 100 MB (制限) まで増加し、その値を維持しました。

ストレステスト第2ラウンド(ウォームJVM)

quarkus jvm ホットスポット — 200MB / 1 CPU

  • アイドルCPU使用率0.13%
  • 空きRAM使用量 66MB
  • 起動時間 3秒

> ブートストラップ中の CPU 使用率。 (またスパイク)

ストレステストの第 1 ラウンド (Cold JVM)


> ストレス下でのCPU / RAMの使用率

> 驚いたことに、JVMは割り当てられた200MBをすべて消費せず、140MBで十分でした。

ストレステスト第2ラウンド(ウォームJVM)

quarkus jvm ホットスポット — 300MB / 2 CPU

  • アイドル状態のCPU/RAMは前のシナリオと同じ
  • 起動時間 1.1 秒 (NICE)

> ブートストラップ中の CPU 使用率が再び急上昇しました。

ストレステストの第 1 ラウンド (Cold JVM)


> CPU使用率が良好

> 142MBのRAMで十分でした

ストレステスト第2ラウンド(ウォームJVM)

それでは、ローカルイメージがどのように機能するかを見てみましょう。

quarkus Java ネイティブ — 100MB / 0.5 CPU

  • 起動時間: 0.125秒。 (!!!)
  • 起動時にCPUスパイクなし

> ブートストラップ中のCPU / RAM

ストレステストの結果


> CPUは予想通り0.5の制限に達しました

> RAM の使用率は良好で、アクティブ メモリは 19 MB です。おお

quarkus Java ネイティブ — 200MB / 1 CPU

  • 即時起動(0.0125秒)
  • 4 空きRAM使用量
  • プレッシャーの下で19種類の記憶を活用する
  • CPU使用率100%
  • 起動時にCPUスパイクなし

テスト結果

quarkus Java ネイティブ — 300MB / 2 CPU

改善なし。

golang — 100MB / 0.5 CPU

  • アイドルCPU 0
  • 空きメモリ 2.3MB (良好)
  • 起動時間: ほんの一瞬
  • 起動時にCPUスパイクなし

結果は少し歪んでいます。何らかの理由で、リクエストのごく一部が完了するまでに約 7 秒かかります。

歪んだ結果が再現できるかどうかを確認するためにテストを再度実行しようとしたところ、テストは実際にそれを打ち破りました。

ランタイム エラー: 無効なメモリ アドレスまたは nil ポインター参照。うーん...何か間違っているのでしょうか? go-sql ライブラリにバグがあるようです。テーブルから読み取るコードは 100% ドキュメントどおりであり、99% の確率で動作します。こんなことは起こるはずがない。

golang — 200MB / 1CPU

ランタイムエラーが繰り返し発生します。疑いは常にテストの最後に残ります。ただし、go-mysql ドライバーの修正は大きな問題ではなかったため、リクエストの 90% を完了した後、テストは手動で終了されました。

  • ストレス下でのCPU/RAMの使用率

> ストレス時のCPU使用率

> ストレス時の RAM 使用量。 12.27MB、とてもいいですね。

golang — 300MB / 2 CPU

目立った改善はなく、すべての統計はほぼ同じです。 CPU使用率は1.0未満です。 go がなぜより多くのコアを最大限に活用しないのかはわかりません。興味深いですね... プロセスが IO バウンドであるためか、複数のコアをより有効に活用するために gin を手動で構成する必要があるためかもしれません。

まとめ


> 集計された統計情報 (warm jvm/native イメージ | golang)

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

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

Golang とクラウドネイティブ Java はどちらも同様の結果を生成しましたが、平均的には Golang サービスがわずかに有利でした。ただし、Java ネイティブの結果はより安定しています。 Golang サービスは 1.25µs 以内に応答することもあれば、7s 以内に応答することはほとんどありません。

「ウォームアップされた」JVM は良い結果を生成しましたが、ネイティブ バージョンや Go バージョンよりも悪い結果になりました。

CPU使用率

go と native-java はどちらも、コアが 1 つ未満の場合は負荷がかかった状態でのパフォーマンスが低下し、コアが 2 つで起動しても目立った改善は見られません。おそらくワークロードが IO バウンドであるためです。または、gin/Netty のデフォルト構成では複数のコアが考慮されていないためです。

一方、JVM は割り当てられたすべてのコアを活用し、あらゆる面でパフォーマンスを向上させます。

RAM使用量

圧力は非常に高く、ネイティブ Java は 40 MB、Golang サービスは 24 MB です。どちらのケースも良好ですが、golang バージョンでは RAM の使用量がほぼ 2 倍少なくなります。

JVM はストレス下で 140MB を使用しました。完全に公式なクォーカス統計。 JVM としてはまったく悪くありませんが、golang バージョンよりもほぼ 6 倍高速です。

起動時間

golang とクラウド ネイティブ Java はどちらも即座に起動しますが、JVM バージョンでは数秒かかり (割り当てられた CPU によって異なります)、起動時に CPU スパイクが発生します。

開発経験

これは実用的な問題というよりも宗教的な問題です。これは非常に不気味なので、注意して答えてください。 Quarkus は、Java の世界では非常によく知られている抽象化 (アノテーションベースの DI など) を作成します。サービスが開始され、接続プールが作成されます。コレクションとジェネリックの豊富な標準ライブラリが利用可能です。しかし、これは少し黒魔術のように感じられ、それが機能しなくなると、無力感を覚えます。さらに、Java コードをネイティブ バイナリにコンパイルするのはそれほど簡単ではなく、制限と注意事項に注意する必要があります。Red Hat は拡張機能で大きな進歩を遂げていますが、すべての Java ライブラリがネイティブ コンパイルと互換性があるわけではありません。 。 (ネイティブにコンパイルされた Java ライブラリとして事前構成されています)。ネイティブ コンパイルと互換性のないライブラリ (Guice など) を使用する場合は、Graal VM を手動で構成する必要があります。可能ですが、jar を使用するほど簡単ではありません。 Quarkus と Graal VM も比較的新しいものです。したがって、多くの冒険が待っています。ただし、デュアル モード (JVM またはネイティブ) であるためです。ネイティブ バージョンが動作しなくなった場合に備えて、フォールバックが常に用意されており、これは発生する問題を解決するのに適した方法です。

一方、Golang は、ジェネリックの必要性を (登場から 10 年経って) ようやく認識しました。もちろん、隠されたイベントの継続は好まれません。多くの点で、これは良いことです。また、Go コミュニティは追いつくのに非常にうまくいっていますが、利用できるツールやライブラリは少なくなっています (たとえば、人気のあるブロッキング MySQL ドライバーは 1 つだけです)。一方、コンパイルとビルドのプロセスは非常に高速かつ簡単です。すべての golang パッケージは、Java ネイティブ プラットフォームによって導入される制限なしに動作します。

結論は

Java はクラウド ネイティブになり、Golang は JVM のようにやり過ぎませんでした。これは素晴らしいことです。今後、広く利用されるようになると信じています。しかし、golang は間違いなく戦うことができます。

慎重に選択してください!

サボテンに水をあげるのを忘れないで

<<:  Dell EMC の再構築とイノベーションにより、ハイパーコンバージェンスによる新たなエッジ コンピューティングのパワーが実現

>>:  クラウドデータベースがローカルデータセンターに進出、AWSハイブリッドクラウドプラットフォームは2つのオープンソースデータベースをサポート

推薦する

Baidu は 2012 年に変化しました。ウェブマスターはどのように変化すべきでしょうか?

私は出張で町を離れていたため、1日インターネットの最新ニュースに注意を払っていませんでした。ホテルで...

cloudcone: クリスマス プロモーション、米国 VPS (ロサンゼルス) は年間 12 ドルから、メモリ 1G/コア 1/ハードディスク 40g/トラフィック 2T/帯域幅 1Gbps

Cloudcone の毎年恒例のクリスマス プロモーションが正式に開始されました。プロモーションは、...

国内初の分散型データベース調査:TDSQL製品技術とサービス能力が第1位

このたび、ITPUBとIT168が共同で作成した初の「国内分散型データベースの選択と満足度調査レポー...

検索機能を使用してウェブサイトのコレクションの量を増やす方法についての簡単な説明

多くのウェブマスターが毎日コンピュータの電源を入れて最初にすることは、自分のウェブサイトのエントリ数...

モバイルインターネットマーケティングディレクターの運用・プロモーション企画事例

近年、モバイルインターネットは急速に発展し、PCトラフィックは徐々にモバイルトラフィックに移行し、モ...

ウェブサイトのスナップショットを同じ日に変えるのはとても簡単です

ウェブサイトのスナップショットを同じ日に作成するのはとても簡単です。私は初心者ですが、ここでは私の個...

MaibaobaoのTaobaoキーワードランキングが消えた理由と解決策の分析

2012年8月15日は忘れられない日です。オンラインとオフラインの両方で多くの論争を引き起こしたJD...

Pinterest のビジネス モデルの議論: 関連データを活用して収益を上げる

北京時間3月27日、海外メディアの報道によると、Baynoteはオンライン小売業者向けにパーソナライ...

クラウドベースの CI/CD プラットフォームを選択するにはどうすればよいでしょうか?

[[413408]]この記事はWeChat公式アカウント「新チタンクラウドサービス」から転載したもの...

SmartVPS (香港) シンプルレビュー

午後、私が仕事中だったとき、smartvps の社員を名乗る人物が QQ で私を追加し、彼らの VP...

AWSテクノロジーサミット2018北京駅が大盛況のうちに開幕

AWS テクノロジーサミット 2018 (北京) が北京国際会議センターで開催されました。北京は、中...

Dockerボリュームについて知っておくべきこと

データボリュームとはDocker コンテナを使用すると、一連のデータ ファイルが生成されます。これら...

クラウド最適化に関する包括的な理解を提供します

[51CTO.com クイック翻訳] 多くの IT プロフェッショナルは、クラウドを最適化する方法は...

ウェブサイト最適化事例分析 - 老人ホームを愛する

私の友人が、主に高齢者向けの医療用品を販売するウェブサイトを開設したばかりです。彼の依頼で、私は週末...

2014 年にウェブサイトを最適化する方法はどこにあるのでしょうか?

SEO が始まったばかりの頃は、時間の問題でした。どんなウェブサイトでも、一定の時間を投資し (時間...