10

ページの読み込みを可能な限り軽減するよう努めています。ViewStateはページの100kまで膨らむことがあるので、完全に排除したいと思います。

他の人がViewStateをカスタムプロバイダーに移動するために使用したいくつかのテクニックを聞きたいです。

とはいえ、いくつかの注意点があります。

  • 1時間あたり平均200万人のユニークな訪問者にサービスを提供しています。
  • このため、データベースの読み取りはパフォーマンスの重大な問題であり、ViewStateをデータベースに保存したくありません。
  • また、ロードバランサーの背後にいるため、どのソリューションも、ポストバックごとにマシン間でバウンスするユーザーと連携する必要があります。

アイデア?

4

15 に答える 15

5

セッション状態をどのように処理しますか?組み込みの「ビューステートをセッション状態に保存する」プロバイダーがあります。セッション状態をprocシステム外の高速に保存している場合は、それがビューステートに最適なオプションである可能性があります。

編集:これを行うには、次のコードをページクラス/グローバルページ基本クラスに追加します

    protected override PageStatePersister PageStatePersister {
        get { return new SessionPageStatePersister(this); }
    }

また...これは、大きなビューステートに対する完璧な(または優れた)ソリューションではありません。いつものように、ビューステートのサイズを可能な限り最小化します。ただし、SessionPageStatePersisterは比較的インテリジェントであり、セッションごとに無制限の数のビューステートを保存することを回避し、セッションごとに1つのビューステートのみを保存することを回避します。

于 2008-09-07T04:14:27.207 に答える
2

前に述べたように、私は過去にデータベースを使用してViewStateを保存しました。これは私たちにとってはうまくいきますが、1時間あたり200万人のユニークビジターに近づくことはありません。

StrangeLoop製品を使用する場合でも、別の製品を使用する場合でも、ハードウェアソリューションは間違いなく進むべき道だと思います。

于 2008-09-07T03:23:49.513 に答える
2

ページからビュー ステートの負荷を取り除くために多くの方法をテストしましたが、すべてのハックといくつかのソフトウェアの中で、本当にスケーラブルなのは StrangeLoops As10000 アプライアンスだけです。透過的で、基礎となるアプリケーションを変更する必要はありません。

于 2008-09-07T03:07:41.283 に答える
2

以下は私にとって非常にうまく機能します:

string vsid;

protected override object LoadPageStateFromPersistenceMedium()
{
  Pair vs = base.LoadPageStateFromPersistenceMedium() as Pair;
  vsid = vs.First as string;
  object result = Session[vsid];
  Session.Remove(vsid);
  return result;
}

protected override void SavePageStateToPersistenceMedium(object state)
{
  if (vsid == null)
  {
    vsid = Guid.NewGuid().ToString();
  }
  Session[vsid] = state;
  base.SavePageStateToPersistenceMedium(new Pair(vsid, null));
}
于 2008-09-17T12:03:10.070 に答える
1

ViewState はいつでも圧縮できるので、それほど肥大化することなく ViewState の利点を得ることができます。

public partial class _Default : System.Web.UI.Page {

  protected override object LoadPageStateFromPersistenceMedium() {
    string viewState = Request.Form["__VSTATE"];
    byte[] bytes = Convert.FromBase64String(viewState);
    bytes = Compressor.Decompress(bytes);
    LosFormatter formatter = new LosFormatter();
    return formatter.Deserialize(Convert.ToBase64String(bytes));
  }

  protected override void SavePageStateToPersistenceMedium(object viewState) {
    LosFormatter formatter = new LosFormatter();
    StringWriter writer = new StringWriter();
    formatter.Serialize(writer, viewState);
    string viewStateString = writer.ToString();
    byte[] bytes = Convert.FromBase64String(viewStateString);
    bytes = Compressor.Compress(bytes);
    ClientScript.RegisterHiddenField("__VSTATE", Convert.ToBase64String(bytes));
  }

  // ...

}

using System.IO;
using System.IO.Compression;

public static class Compressor {

  public static byte[] Compress(byte[] data) {
    MemoryStream output = new MemoryStream();
    GZipStream gzip = new GZipStream(output, 
                      CompressionMode.Compress, true);
    gzip.Write(data, 0, data.Length);
    gzip.Close();
    return output.ToArray();
  }

  public static byte[] Decompress(byte[] data) {
    MemoryStream input = new MemoryStream();
    input.Write(data, 0, data.Length);
    input.Position = 0;
    GZipStream gzip = new GZipStream(input, 
                      CompressionMode.Decompress, true);
    MemoryStream output = new MemoryStream();
    byte[] buff = new byte[64];
    int read = -1;
    read = gzip.Read(buff, 0, buff.Length);
    while(read > 0) {
      output.Write(buff, 0, read);
      read = gzip.Read(buff, 0, buff.Length);
    }
    gzip.Close();
    return output.ToArray();
  }
}
于 2011-03-27T02:03:32.477 に答える
0

典型的な組織の肥大化のため、新しいハードウェアの要求には何年もかかり、現在のセットアップの完全な再配線を伴うハードウェアの要求は、おそらくエンジニアリング部門から厳しい抵抗を受けるでしょう。

私は本当にソフトウェアソリューションを考え出す必要があります。それは私がある程度制御できる唯一の世界だからです。

Yay for Enterprise :(

于 2008-09-07T03:28:52.577 に答える
0

私は過去に調査した製品のいくつかを見つけようとしましたが、StrangeLoopsと同じように機能します(ただしソフトウェアベース)。それらはすべて廃業したようです。私のリストからまだScaleOutがあるのは、それらだけです。セッション状態のキャッシュに特化しています。

上級管理職にハードウェアソリューションを販売するのがいかに難しいかは理解していますが、少なくとも管理職にハードウェアの営業担当者の話を聞いてもらうことは常に良い考えです。私はむしろ、他の実際の仕事を成し遂げることができる(または私を購入する)ことができるので、すぐに解決策を提示するハードウェアをいくつか置いています。

私は理解しています、それは本当にひどいですが、代替案は最適化のためにあなたのコードを変更することであり、それはおそらくアプライアンスを入手するよりもはるかに多くの費用がかかるでしょう。

別のソフトウェアベースのソリューションを見つけたら教えてください。

于 2008-09-07T03:54:10.987 に答える
0

現在の状態サーバーを活用してビューステートをメモリに含める方法を考え出すことができるかどうかを確認します。ユーザーセッションIDを使用して、マシン間で同期を維持できるはずです。

良い解決策を思いついたら、IPで保護されたコードをすべて削除し、公開します。

于 2008-09-07T04:08:06.927 に答える
0

ああ、お役所仕事。さて、これは満たすのが難しい注文になるでしょう。ここで、セッション状態を提供するために状態サーバーを使用すると述べました。この設定はどのように行いますか?たぶんあなたはここでも同じようなことをすることができますか?

編集

ああ@ジョナサン、あなたは私がこの答えをタイプしている間に投稿しました。そのルートに行くことは有望だと思います。1つは、メモリを大量に消費することです。

@Mikeビューステートのメモリを大量に消費し、ビューステートにアクセスする必要がある回数もあるため、セッション情報に保存するのは良い考えではないと思います。SessionStateは、ビューステートほど頻繁にアクセスされません。私は2つを別々に保ちます。

究極の解決策は、ViewStateをクライアントに何らかの方法で保存することであり、おそらく一見の価値があると思います。Google Gearsを使用すれば、これが可能になる可能性があります。

于 2008-09-07T04:12:31.550 に答える
0

別の投稿で簡単な解決策があるかもしれません。これは、アプリに含める単純なクラスであり、asp.netページ自体に数行のコードを含めます。分散キャッシングシステムと組み合わせると、ビューステートが大きくてコストがかかるため、多くの生地を節約できます。Microsoftの速度は、この方法を適用するのにも良い製品かもしれません。あなたがそれを使ってたくさんのお金を節約するなら、私はそれについて少し言及したいのですが。また、不明な点がある場合はお知らせください。直接お話しすることができます。

これが私のコードへのリンクです。リンクテキスト

スケーリングに関心がある場合は、セッショントークンを一意の識別子として使用するか、セッションに状態を保存することで、Webファームのシナリオで機能することがほぼ保証されます。

于 2008-11-07T05:02:43.060 に答える
0

少し前にこれについてブログを書きました - 解決策はhttp://www.adverseconditionals.com/2008/06/storing-viewstate-in-memcached-ultimate.htmlにあります

これにより、カスタム PageAdapter を使用して、各 Page クラスを変更することなく、ViewState プロバイダーを任意のプロバイダーに変更できます。ViewState を memcached に保存しました。振り返ってみると、データベースまたはディスクに保存する方がよいと思います。memcached はすぐにいっぱいになりました。その非常に低摩擦のソリューションです。

于 2009-08-12T15:24:53.023 に答える
0

これが少し古くなっていることはわかっていますが、squid と ecap を使用してオープンソースの「仮想アプライアンス」で数日間作業してきました。

1.) gzip 2.) ssl を処理する 3.) リクエスト/レスポンスで viewstate をトークンに置き換える 4.) オブジェクト キャッシング用の memcache

とにかく、それはかなり有望に見えます。基本的に、ロードバランサーの前に配置され、クライアントのパフォーマンスを大幅に向上させるはずです。セットアップも非常に難しいようには見えません。

于 2009-07-29T02:44:10.977 に答える
0

そのすべてのビューステートが本当に必要かどうかを検討しましたか? たとえば、データベースからデータグリッドを作成すると、デフォルトですべてのデータがビューステートに保存されます。ただし、グリッドがデータを表示するためだけのものである場合は、フォームをすべて必要としないため、viewstate は必要ありません。

ビューステートが必要なのは、ポストバックによるユーザーとのやり取りがある場合だけです。その場合でも、実際のフォーム データでビューを再作成するのに十分な場合があります。ページ上のコントロールのビューステートを選択的に無効にすることができます。

実際に100K のビューステートが必要な場合は、非常に特別な UIを使用できます。ビューステートを絶対に必要なものまで減らすと、ページ内でビューステートを維持するのが最も簡単で最もスケーラブルになる場合があります。

于 2008-09-17T12:00:20.577 に答える
0

ビューステートの肥大化を解消するために何かを売買する必要はありません。HiddenFieldPageStatePersister を拡張するだけです。100 ~ 200 KB の ViewState はサーバーに残り、代わりにページで 62 バイトのトークンのみを送信します。

これを行う方法に関する詳細な記事は次のとおりです。

http://ashishnangla.com/2011/07/21/reducing-size-of-viewstate-in-asp-net-webforms-by-writing-a-custom-viewstate-provider-pagestatepersister-part-12/

于 2011-11-22T05:59:26.893 に答える
0

viewstate をセッション オブジェクトに格納し、分散キャッシュまたは状態サービスを使用して、Microsoft Velocity などのサーバーとは別にセッションを格納します。

于 2009-01-11T04:56:02.360 に答える