2

データのストリームを解析しているシステムがあり、多くのユーザーのサブスクリプションに基づいて、それをフィルタリングする必要があります。ただし、これらのフィルターには正規表現を含めることができるため、悪意のあるユーザーがサービスを破壊するために意図的に CPU を消費する正規表現を挿入できないように、十分に安全にする必要があります。

どうするのが一番いいのか悩んでいますが、

私が作成した別のプログラムでは、正規表現検索を実行する新しいスレッドを生成することでこれを処理していました。このスレッドが制限を超えて実行されている場合、スレッドは強制終了され、エントリがブロックされました。

ただし、このシステムは毎分数千のレコードを処理している可能性があり、すべてのレコードに対して新しいスレッドを生成することは想像できません (実際、エントリごとにすべてのサブスクリプションをループする必要があるため、毎分数十万のスレッドになる可能性があります)。 .

これを処理するためのより良いアプローチはありますか? サブスクリプションが作成されたら、いくつかのテスト データを使用して正規表現をテストする必要がありますか? それとも、別のスレッドで解析されるユーザーごとに別のキューを使用するのでしょうか?

また、私の頭に浮かぶ別のアプローチは、各フィルターがかかる CPU 時間に関する統計を収集し、過度に消費するこれらを無効にすることですが、CPU の数分を必要とする可能性のある「非常に悪い」正規表現を実際には処理しません。終了時間

誰かが興味を持っていれば、私はC#で書いていますが、この質問はかなり一般的で、どの言語にも当てはまる可能性があります

4

4 に答える 4

4

C# を使用しているため、新しいスレッドをスピンオフする必要はありません。Regexコンストラクターには、タイムアウトを設定できるオーバーロードがあります。正規表現に時間がかかりすぎると、中止されてRegexMatchTimeoutExceptionがスローされます。

組み込みのタイムアウトを持たない正規表現エンジンの場合、スレッドを 1 つだけ生成して再利用するか、スレッド プールにスレッドを割り当てさせることで、おそらく管理できるでしょう。

正規表現が 1 回限りの使用ではない場合に行う価値のあるもう 1 つのことは、正規表現をコンパイルすることです。C# の正規表現は、将来の一致を高速化するためのプリコンパイルをサポートしています。

于 2013-07-30T12:29:37.437 に答える
1

正規表現ごとにスレッドを生成する必要はありません...代わりに、ループ内の残りの正規表現を処理するワーカースレッドを作成し、反復ごとにループの開始をログに記録します。次に、以前のソリューションを使用して、時間がかかりすぎるワーカー スレッドを強制終了し、正規表現を無効にして、ワーカー スレッドを再生成します。

そうすれば、常に新しいスレッドを開始するというオーバーヘッドはありませんが、時間がかかりすぎるスレッドを強制終了できます。

于 2013-07-30T12:10:14.160 に答える
1

ユーザーが新しいフィルターを追加するときに、この正規表現を実行するコストを評価した方がよいと思います。例えば:

  • ユーザーは、正規表現を使用してフィルター X を追加したいと考えています。
  • アプリケーションは、定義済みのデータ セットに対してこのフィルターを実行する必要があります。
  • この実行に Y ミリ秒以上かかる場合は、追加を許可しないでください。
  • ランクの高いユーザー (有料サービス、忠実なユーザーなど) には、より積極的なフィルター (より多くの処理ミリ秒) を許可できます。
于 2013-07-30T12:08:59.853 に答える