実行時にのみ認識される一時的な依存関係の競合にどのように対処しますか?[閉まっている]


9

通常、大規模なソフトウェアプロジェクトで実行時に発生する一時的な依存関係の問題にどのように取り組みますか?

過去3週間、私はソフトウェアの別のコンポーネント内で大規模なソフトウェアのコンポーネントを開始しようとしましたが、実行時にのみ知られる一時的な依存関係の問題が原因で断続的に停止します。

一時的な依存関係の問題とは、特定のプロジェクトの依存関係の特定の依存関係が実行時に他の依存関係と衝突し、不安定性や瞬時の障害を引き起こすことを意味します。

何百、何百もの依存関係が使用されており、ツールに関連する約50のサブプロジェクトが他のチームによって分離されており、すべてのモジュールが相互に深くネストされた依存関係を持っています。プロジェクトの規模と複雑さを考えると、誰もがすべてのサブプロジェクトが何に使用されるのかを知りません。

この状況では、影響を受けるコンポーネントの依存関係ごとにDAGの視覚的な表現を生成し、実行時に衝突が発生する可能性のある場所を特定しようとしますか?他のサブプロジェクトで依存関係を管理する方法を制御できず、他の開発者が作成したJavaコードを変更できません

私が思いついたソリューションは、1〜2時間しか機能せず、その後、上流コンポーネントの変更により機能が停止します。上流コンポーネントの例は、私が取り組んでいるプロジェクトが依存する成果物であり、CIパイプラインの初期段階でビルドされます。


他の要求に応じて、使用されているテクノロジーに関する情報を含めます。情報が多すぎるために質問が閉じられたり、身体が長くなりすぎたりするリスクがあります。

  • Mavenは依存関係管理に使用されます。そして
  • SpringはDIコンテナーとして使用されます。
  • 依存関係の問題のほとんどは、実行時に読み込まれる他のモジュールのコンテキストの結果として、Beanコンテキストの重複を伴​​います
  • 製品は適切に動作し、単体テストのスモールガスド、およびプログラムの機能的な正確さを逃れる統合テストがあります

一般的に、特定のプロジェクトの依存関係の可能なすべての組み合わせを列挙することなく、依存関係の競合解決する方法を識別するための言語にとらわれないアプローチを探しています

プロジェクトを再構築したり、品質ゲートを追加したり、会社全体のパラダイムシフトを推進したり、解決策として言語を切り替えたりすることはできません。


IFooがIFooImplを使用することを知るために、DIコンテナーが適切に設定されていないようなことについて話しているのですか?
アンディ

いいえ、それはプロジェクト(b)のパッケージ(b)がプロジェクト(A)のパッケージ(a)の推移的な依存関係であることに似ていますが、(B)は実行時にのみ導入されます。ソフトウェアはすべて私が言えることから機能しますが、推移的な依存関係のすべてを適切に解決できるようにするには、適切な依存関係のセットが必要です。製品を適切に起動できるようにする一連の依存関係がありますが、これらの構成は非常に脆弱です。ジュニア開発者として。私はこれを制御できません。
タイラー

2
さて、「依存関係の問題」は非常に一般的な用語であり、これを読む誰もがおそらく別の何かを想定しています。現実のソフトウエアの場合、これはテクノロジーに依存するため、考えている特定のテクノロジーの実際の例を挙げてください。必要なコンポーネントがないために問題が発生していますか?または、間違ったバージョンが提供されているためですか?どのような種類の依存関係解決メカニズムがすでに導入されていますか?どうか明らかにしてください。
Doc Brown、

1
.Netの世界では、パッケージをメインのアプリケーションプロジェクトにインストールするだけでこの問題を解決できます。実際にプラグインライブラリを直接使用するアプリケーションコードはありませんが、.NetコンパイラはDLLがビルド中、つまりデプロイ中に適切な場所にあることを確認します。
アンディ

2
「私は依存関係の管理方法を制御できず、コードを変更できません」-実際に何を変更できますか?何も変更できない場合、質問は無意味なようです。
Doc Brown

回答:


6

カスタムクラスローダーを使用して問題を解決し、アプリケーション内の各モジュールに独自の実行環境を与えることができる場合があります。

基本的に、アプリケーションの小さなカーネルで構成されるコア環境と、普遍的に合意されている依存関係、およびモジュールが互いに通信するために必要なすべてのインターフェースを定義します。次に、ロードする各モジュールは、(1)ランタイム環境からのクラス、(2)アプリケーションコアからのクラス、および(3)そのモジュールとその直接の依存関係からのクラスにアクセスできる独自のクラスローダーを取得します。すべてのモジュール間通信は、コアで定義されたインターフェイスを経由するため、モジュールが別のモジュールに直接依存することはありません。

この手法はアプリケーションサーバーで使用され、アプリケーションに他の方法で競合する依存関係を持たせることができるため、たとえば、Tomcatでこの手法の実際の実装を確認できます(運が良ければ、Tomcatの少し変更を加えた実装)。


1
依存関係の問題を解決するためにプロジェクトを再構築することは許可されていません。しかし、マイクロカーネルのようなアーキテクチャーに切り替えるのは、ちょっとクールなことです。
タイラー

2
@タイラー:それでも、これは質問の一般的な部分に対する良い一般的な答えだと思います。
Doc Brown、

1
これはosgiのように聞こえます。
SpaceTrucker

4

私はMavenやSpringを使用したことがありませんが、一般的な質問に対する一般的な答えを与えるために、依存関係の問題に関しては、システムは可能な限り早期にそれらを検出し、それらの問題が検出されたときに設計する必要があります、考えられる原因を含めて、すぐに通知する必要があります。

理想的には、この時点は「本番稼働時」ではありません。最良の時点は「ビルド時間」ですが、あなたの場合それは不可能のようです。したがって、2番目に最適なオプションはランタイムテストです。「統合テスト」があるとおっしゃっていましたが、依存関係の問題が検出されないため、不完全であるか、または一般に依存関係の競合をテストしていません。そこで問題を解決しようとします。

さらに、テストをより効果的にするために、コンポーネントは依存関係の問題が発生したときに「速く失敗する必要があります。つまり、依存関係が解決されてコンポーネントが読み込まれるとすぐに、潜在的な依存関係の衝突がチェックされ、直ちに通知される必要があります。衝突が検出される前にシステムが最初に1時間実行されると、問題の原因を特定することが非常に困難になります。Maven / Springが組み込みの「フェイルファースト」戦略をすでに提供しているかどうかはわかりませんが、そうでない場合は、その方向で考えてみてください。

本番環境での問題を軽減するには、重要性の低いサブコンポーネントが含まれる依存関係の衝突が発生したときに、システムが完全に停止しないように設計する必要があります。もちろん、障害はマスクされるべきではありませんが、システムは理想的にはそのコンポーネントのロードを拒否し、問題を記録および/または信号で通知し、安定した状態を保つ必要があります。コンポーネントが最初に読み込まれると、システムが不安定になり、後で問題が検出された場合、おそらくシステムを完全にシャットダウンして再起動する必要がありますが、これは避けたいと思います。

たとえば、システムがWebショップであり、「ニュースレター購読」のサブモジュールを数時間ロードできない場合、これはショップ全体が機能しなくなったかのように許容されやすいものです。

最後に、これはあなたのケースではオプションではないかもしれませんが、コンポーネントを互いにより分離して実行させることができ、依存関係の衝突を回避できる場合、それは考える価値のあるアプローチかもしれません。


2

ここで大声で考えている私を考えてみてください。要件/時間の制約に応じて、私はこれを考慮するかもしれません:

1)インターフェースとその実装のリストを作成する(可能な場合はリフレクションを使用)

2)DIの周りに一種のラッパーを作成します。DIに具体的な実装を提供するように求められたら、DIルールがすでに存在しているかどうかを確認します。ルールが存在する場合-DIが提供するものを返すだけです。それ以外の場合は、インターフェースの単一の実装があり、インスタンスを作成できる場合-ログを記録してインスタンスを返します。それ以外の場合は、ログに記録して失敗します。

どれだけ関与したいかに依存すると思いますが、最終的には何が必要かについての完全なリストが欲しいだけです-このソリューションは最終的にそのリストを生成します。

しかし、これは間違いなく多くの作業であり、信頼性がありません-ブルームーンで一度特定の依存関係を必要とする奇妙な条件がある場合はどうでしょうか?

「上流コンポーネントの変更」とはどういう意味ですか?


申し訳ありませんが、あまり多くの背景情報を提供したくありませんでした-動作環境について説明すると、質問は通常、反対票が投じられ、激怒します。元の質問を定義セクションで更新します。
タイラー

2

私が正しくフォローしている場合、問題は、使用する必要のあるコードに、Spring XMLで表現されたモジュールに対する実行時の依存関係があることですが、mavenはそれらについて通知されません。したがって、それらを使用する場合、必要なもの(推移的な依存関係)はクラスパス上になく、必要なことを行いません。

あなたの同僚に尋ねたとき、私は推測している「私は仕事にこれを得るのですか?」、彼らが言う「明らかにあなたが必要とする35個のモジュールとバージョンのこのリストを、あなたがそれを知らないことができますか、?

おそらく統合テストが行​​われると、必要なモジュールがテスト依存関係として宣言されます。したがって、体系的なソリューションは、統合テストpomの検査を設定して、サードパーティのテストツールのみがテストの依存関係として宣言されていることを確認することです。これは、mavenエンフォーサプラグインによって自動化することもできます

どうやらそれはできないので、あなたの最良の選択肢はおそらくここにあります


それはまさに私が言えることから起こっていることです。これまでのところ、30の依存関係を調整し、スコープをいじって衝突を排除していますが、ここではピアレビューが必要です。
タイラー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.