「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > コードから Reactive システム アーキテクチャを削除したのはなぜですか?

コードから Reactive システム アーキテクチャを削除したのはなぜですか?

2024 年 9 月 2 日に公開
ブラウズ:968

この記事では、ソフトウェア プロジェクトでリアクティブ アーキテクチャから移行するという決定について説明します。リアクティブ システムの中核原則、ノンブロッキング I/O の利点、リアクティブ アプローチで直面した課題について詳しく説明します。

リアクティブアーキテクチャスタイルを理解する

Reactive には、応答性の高い分散システムとアプリケーションの構築を目的とした一連の原則とガイドラインが含まれており、次のような特徴があります。

  1. 応答性: 高負荷時でもリクエストを迅速に処理できます。
  2. 復元力: 最小限のダウンタイムで障害から回復できます。
  3. 弾力性: リソースをそれに応じてスケーリングすることで、ワークロードの変化に適応できます。
  4. メッセージ駆動: 非同期メッセージングを利用してフォールト トレランスを強化し、コンポーネントを分離します。

リアクティブ システムの主な利点の 1 つは、ノンブロッキング I/O の使用です。このアプローチにより、I/O 操作中のスレッドのブロックが回避され、単一のスレッドで複数のリクエストを同時に処理できるようになります。これにより、従来のブロッキング I/O と比較してシステム効率が大幅に向上します。
従来のマルチスレッドでは、ブロック操作がシステムの最適化において大きな課題となります (図 1)。過剰なメモリを消費する貪欲なアプリケーションは非効率的であり、他のアプリケーションに悪影響を及ぼし、多くの場合、メモリ、CPU、またはより大きな仮想マシンなどの追加リソースの要求が必要になります。

Why we discarded Reactive systems architecture from our code?

図 1 – 従来のマルチスレッド


I/O 操作は最新のシステムに不可欠であり、貪欲な動作を防ぐには、I/O 操作を効率的に管理することが最も重要です。リアクティブ システムはノンブロッキング I/O を採用し、少数の OS スレッドで多数の同時 I/O 操作を処理できるようにします。

リアクティブ実行モデル

ノンブロッキング I/O には大きな利点がありますが、従来のフレームワークとは異なる新しい実行モデルが導入されます。リアクティブ プログラミングは、ブロック操作中にアイドル状態になるプラットフォーム スレッドの非効率性を軽減するため、この問題に対処するために登場しました (図 2)。

Why we discarded Reactive systems architecture from our code?

図 2 – リアクティブ イベント ループ


クォーカスとリアクティブ

Quarkus は、Eclipse Vert.x と Netty を活用したリアクティブ エンジンを活用し、ノンブロッキング I/O インタラクションを促進します。 Mutiny は、Quarkus でリアクティブなコードを記述するための推奨アプローチであり、イベント駆動型のパラダイムを採用しており、受信したイベントによってリアクションがトリガーされます。

Mutiny は 2 つのイベント駆動型と遅延タイプを提供します:

  1. Uni: 単一のイベント (項目または失敗) を発行します。これは、結果が 0 または 1 つある非同期アクションを表すのに適しています。
  2. Multi: 項目のストリームを表す複数のイベント (n 個の項目、1 つの失敗、または 1 つの完了) を発行し、場合によっては制限がありません。

リアクティブの課題

リアクティブ システムには利点がありますが、開発中にいくつかの課題に直面しました。

  • パラダイム シフト: リアクティブ プログラミングでは開発者の考え方の根本的な変化が必要ですが、特に命令型プログラミングに慣れている開発者にとっては困難な場合があります。 Streams API のような補助ツールとは異なり、事後対応アプローチでは考え方の完全な見直しが必要です。
  • コードの読みやすさと理解: リアクティブ コードは、新しい開発者にとって理解が難しく、解読と理解に費やす時間が増加します。反応的なパラダイムによってもたらされる複雑さが、この問題をさらに悪化させます。

「確かに、読み取り時間と書き込み時間の比率は 10 対 1 をはるかに超えています。私たちは新しいコードを書く努力の一環として常に古いコードを読んでいます。...[したがって] 読みやすくすることで、書きやすいです。」
ロバート C. マーティン、クリーン コード: アジャイル ソフトウェア クラフトマンシップのハンドブック

  • デバッグの課題: ラムダがほとんどのコードをカプセル化しているため、標準の IDE デバッガではリアクティブ コードをデバッグするのはほぼ不可能であることがわかります。さらに、例外中に意味のあるスタック トレースが失われると、デバッグ作業がさらに妨げられます。 開発とテストの労力の増加: リアクティブ コードに固有の複雑さにより、作成、変更、テストに時間がかかるため、開発サイクルが長くなる可能性があります。

複雑さを説明するために Mutiny を使用したリアクティブ コードの例を次に示します:

Multi.createFrom().ticks().every(Duration.ofSeconds(15))
    .onItem().invoke(() - > Multi.createFrom().iterable(configs())
    .onItem().transform(configuration - > {
  try {
    return Tuple2.of(openAPIConfiguration,
        RestClientBuilder.newBuilder()
            .baseUrl(new URL(configuration.url()))
            .build(MyReactiveRestClient.class)
            .getAPIResponse());

  } catch (MalformedURLException e) {
    log.error("Unable to create url");

  }
  return null;
}).collect().asList().toMulti().onItem().transformToMultiAndConcatenate(tuples - > {

  AtomicInteger callbackCount = new AtomicInteger();
  return Multi.createFrom().emitter(emitter - > Multi.createFrom().iterable(tuples)
      .subscribe().with(tuple - >
          tuple.getItem2().subscribe().with(response - > {
              emitter.emit(callbackCount.incrementAndGet());

  if (callbackCount.get() == tuples.size()) {
    emitter.complete();
  }
                    })
                ));

}).subscribe().with(s - > {},
Throwable::printStackTrace, () - > doSomethingUponComplete()))
    .subscribe().with(aLong - > log.info("Tic Tac with iteration: "   aLong));

将来の展望 - プロジェクトの可能性とその先へ

Java エコシステムの最近の開発である Project Loom は、操作のブロックに関連する問題を軽減すると約束しています。 Project Loom は、ハードウェアを変更せずに何千もの仮想スレッドを作成できるようにすることで、多くの場合、事後対応型のアプローチの必要性を排除できる可能性があります。

「Project Loom はリアクティブ プログラミングを廃止しようとしている」
ブライアン・ゲッツ

結論

結論として、プロジェクトの長期的な保守可能性への実用的なアプローチであるリアクティブ アーキテクチャ スタイルから脱却するという決定が下されました。リアクティブ システムには潜在的な利点がありますが、私たちの特定の状況では、リアクティブ システムがチームにもたらした課題の方が利点を上回りました。

重要なのは、この変更によってパフォーマンスが損なわれることはありませんでした。これは、適切に設計された非リアクティブ (命令型) アーキテクチャが、このケースのリアクティブ アーキテクチャに伴う複雑さを伴うことなく、必要なパフォーマンスを提供できることを示しているため、肯定的な結果です。

私たちは将来に向けて、機能的なだけでなく、あらゆる経験レベルの開発者にとって理解しやすく保守しやすいコードベースを構築することに引き続き重点を置いています。これにより、開発時間が短縮されるだけでなく、チーム内でのコラボレーションと知識の共有が促進されます。

以下のグラフでは、X 軸は進化に伴うコードベースの複雑さの増加を表し、Y 軸はこれらの開発上の変更に必要な時間を表しています。

Why we discarded Reactive systems architecture from our code?

リリースステートメント この記事は次の場所に転載されています: https://dev.to/yanev/why-we-discarded-reactive-systems-architecture-from-our-code-19ni?1 侵害がある場合は、[email protected] までご連絡ください。それを削除するには
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3