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 フレームワークを使用します。
Golang の MySQL ドライバーは go-sql-driver を使用します。 Golang のコーディングスタイルは非常に明確です。すべてが見えるという姿勢。メイン関数はサーバーを起動し、リクエスト ハンドラーを構成し、DB 接続を開きます。 ローカル実行ファイルをコンパイルする Kotlin バージョン
データベース接続には、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 を使用して実行することもできます。 ストレステスト 次の設定で、ローカル マシン上ですべてのテストを実行します。
cAdvisor のツールを使用してコンテナの統計を監視します。 シナリオ
上記の各ケースは、次の 3 つの構成でテストされました。
私が主に関心を持っているのは以下の点です。
テスト結果 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 サービスステータスのトラブルシューティング
Baidu が最近行った検索アルゴリズム(青大根アルゴリズム)のアップグレードに関して、このアルゴリ...
機密情報ネットワークの運用環境は、最近かなり危険になっているようだ。過去数年間、58.com と G...
インターネット技術の継続的な革新と進歩に伴い、マーケティング モデルも絶えず変化しています。21 世...
ブログマーケティングとWeiboマーケティングはもはや同じではありませんが、ブログマーケティングを無...
ホスティング会社 sugarhost は 10 月のプロモーションを開始し、通常の仮想ホスティングと...
私自身の業務経験や情報をもとにまとめたブランドマーケティング運用マニュアルです。ブランド マーケティ...
最近、地元の新興インターネット企業をいくつか見てきました。彼らの良い発展を楽しみにしていますが、同時...
蔡旭坤ファンと周杰倫ファンによる微博超話題戦争からほぼ1年が経ち、微博は突如ショート動画分野への参入...
Namecheap は個人ドメイン名 .me を初年度 0.98 ドルで開始します。更新にいくらかか...
Wooservers は英国に登録されたホスティング会社です (英国登録番号: 07207169)。...
Xshell は、Windows で Linux VPS サーバーに接続するための一般的なソフトウェ...
セキュリティの専門家が、サイバー攻撃者が企業のクラウド コンピューティング環境に対して使用する一般的...
インターネットブランドは、オフラインで活動し、人々の空間に侵入し、現実世界で見られるようになることが...
ウェブサイトの最初から、開発プロセスと参加プロセス全体を決定する必要があります。 SEO プロジェク...
APPプロモーションチャネルでは不正行為が頻繁に発生します。今日は、APPプロモーションの不正行為防...