この記事では、スパイクアーキテクチャの関連コンテンツについて話し始めました。スパイクアーキテクチャは非常に包括的なシナリオと言えますが、インタビュアーは特にこのシナリオに基づいて質問するのが好きなので、理解する必要があります。上手。
正式に開始する前に、以前の記事の内容を確認しましょう。
第5章では、キャッシュについて説明しました。最初にデータをキャッシュに保存します。各リクエストはキャッシュを介してデータを読み取るため、データベースの読み取りリクエストの負荷が大幅に軽減されます。6番目の記事では、書き込みキャッシュについて説明しました。トラフィックがピークに達すると、最初にデータをキャッシュに書き込み、次にデータをデータベースに徐々に移動します。これにより、データベースの書き込み要求のプレッシャーが大幅に軽減されます。7番目の記事では、データ収集について説明しました。メッセージキューを使用して、キャッシュ内のデータをデータベースに移動できます。この記事では、これらの記事に含まれるアーキテクチャ設計のアイデアを使用します。
1、ビジネスシナリオ7
10月10日22時10分0秒にユーザーが正式にseckillを開始するための100の特別な製品(商品価格が非常に安い)を提供するseckillイベントがあります。
当時、プラットフォームには数千万人のユーザーが蓄積しており、数十万人のユーザーがこの特別オファーに興味を持っていると予想されていました。スパイク活動の調性によると、スペシャルは通常1〜2秒以内に奪われ、残りの時間の流れはスパイクエンドインターフェイスしか見ることができないため、スパイクが回される瞬間があると予測しますピークトラフィック。
これも短期間のイベントです。サーバーを追加したり、リファクタリングに多くの時間を費やしたりすることはできません。率直に言って、このスパイクアクティビティを最小限の技術コストで取得する必要があることを意味します。
したがって、今回のスパイクアーキテクチャの設計目標は、スパイク時のトラフィックの急流がサーバーを圧倒しないように、小さな変更を加えることです。
スパイクアーキテクチャの設計では、僧侶が多すぎるという問題があります。したがって、スパイクアーキテクチャを設計するときは、一般的に、物事が売られ過ぎたり、成功した注文データが失われたりすることはありません。データベースをリンクすることはできず、ロボットが製品を盗むことを許可しないようにしてください。4つの原則。
これらの4つの原則を達成する方法は?全体的なアイデアから始めましょう。
2.全体的な考え方
実際、スパイクアーキテクチャの設計スキームは、要求を絶えずフィルタリングするプロセスです。システムアーキテクチャの観点から、スパイクシステムの階層設計のアイデアを次の図に示します:
上の図からわかるように、スパイクシステムのアーキテクチャ設計の目標は、ユーザーの要求を上位レベルで処理し、それが泳ぎ落ちるのを防ぐことです。それを実現するにはどうすればよいですか。
スパイクシステム全体には複数のユーザー操作ステップが含まれるため、システムの上位レベルでリクエストをインターセプトする方法の問題を解決するときは、実際のビジネスプロセスを組み合わせて、各ユーザーの操作ステップを考慮する必要があります。
理解を容易にするために、次の図に示すように、画像を使用してスパイクシステムの特定のビジネスプロセスを説明します。
次に、スパイクアーキテクチャシステムのビジネスプロセスに従って、システムのアップストリームでリクエストをインターセプトする方法を段階的に説明します。
(1)ページを閲覧するときにアップストリームのリクエストをブロックするにはどうすればよいですか?
スパイクシステムアーキテクチャの過去の経験では、そのような蛾がありました:当時、私たちはシステムのすべての側面を考慮に入れました。チェックした後、私たちは非常に気分が良かったのですが、アクティビティがオンラインになると、システムはすぐに表示されました異常を確認したところ、エクスポート帯域幅に問題があったことを除けば、すべてのサーバーのパフォーマンス指標に問題がないことがわかりました。(満員です)
その結果、イベントに参加したときにページが深刻にフリーズしたことを誰もが知っており、ユーザーは引き続き不満を漏らしていました。
この辛い経験を通して、私たちはデザイン思考に関連する調整を行いました。後の段階で、静的リソースにCDNを使用できます。PC Webサイトが関係する場合は、最初にフロントエンドとバックエンドを分離する必要があります。その後、CDNを静的リソースに使用できます。
これを見て、まずCDNとは何かを理解する必要があります。
たとえば、私たちが通常アクセスするリクエストはhttps://static.resource.xx/1.jpgです。
このアドレスは独自のサーバーを指しています。変換後、ドメイン名static.resouce.xxをCDNサービスプロバイダーに解決します。 。CDNサービスプロバイダーは全国にサーバーを持っているため、サーバーは必要な静的リソースのキャッシュを保存します。CDNはこのドメイン名を受信すると、最初に応答が最も速いサーバーを見つけて、このサーバーのIPをポイントします。(一般的にはそうです。詳細に興味があれば、メッセージを残して教えてください。記事で紹介します。公式アカウントに注意してください:サーバー技術を選択してメッセージを残してください)
したがって、CDNを使用する利点は、独自のサーバーリソースと帯域幅を浪費せず、応答速度が速いことです。このようにして、システム階層外の静的リソースのプレッシャーを阻止できます。
動的リクエストの場合はどうなりますか?以下の3つの実装方法があります。
- たとえば、コメント、製品属性の詳細、購入数のリクエストは、通常、JSのバックグラウンドを介して動的に呼び出されます。このシナリオでは、各スパイク製品の詳細ページを静的ページに変換してからCDNに配置するなど、動的データをページと統合できます。変換が大きすぎる場合は、Redisキャッシュに入れることもできますが、私はCDNを好みます。
- サーバー時間を判断してseckillロゴを有効にする:通常、ページにはJSがあり、サーバーにアクセスしてサーバー時間を取得し、時間に基づいてseckill注文ボタンをオンにします。つまり、seckillが開始と判断された場合、注文ボタンを購入可能に設定します。このリクエストでサーバー時間を取得するために、静的リソースまたは負荷分散レイヤーに配置して、ユーザーリクエストがシステムのダウンストリームに入らないようにすることができます。
- スパイクの結果の判断:私たちのアプローチは、スパイクの終わりのマークをCookieに配置することです。Cookieにエンドマークがない場合、リクエストはバックエンドサーバーに送信されます。バックエンドサーバーは、あると判断します。ローカルメモリに終了マークがなく、キャッシュに入ります。キャッシュ内にある場合終了記号がないため、スパイクが終了していません。
一般に、ページを閲覧する際のユーザーの行動については、CDN、静的リソース、または負荷分散側でユーザーのリクエストを可能な限りインターセプトする必要があります。キャッシュ内でそれらをインターセプトすることは不可能です。
(2)注文ページはどのようにアップストリームのリクエストをインターセプトしますか?
ユーザーが注文ページに入ると、主に2つの操作アクションに分けられます。注文ページに入ると注文を送信することです。これらの2つのリンクでシステムのアップストリームでリクエストをインターセプトする方法について話しましょう。
(1)注文ページに入る
他のユーザーがクローラーを介して注文ページ情報をクロールしてサーバーへの負荷を増大させないようにするには、注文ページで次の2層の保護を実行して、(悪意のある)要求が繰り返し送信されないようにする必要があります。
- ページURLバックグラウンド動的取得:通常のアクティビティ設計プロセスによれば、ユーザーはスパイクアクティビティが開始された後にのみ注文ページに入ることができますが、ピアが注文ページURLを直接取得し、アクティビティが開始する前に継続的に更新することは避けられません。そのため、悪意のあるリクエストが行われます。バックグラウンドサーバーに送信されました。バックエンドサーバーは悪意のあるリクエストを傍受することもできますが、多くのプレッシャーがかかります。現時点では、主に奇妙なURLを使用して処理しています。(静的ページには配置しませんが、バックグラウンドを介して動的に取得します。)以前、JSを使用してスパイクの開始時間を決定できることを紹介しました。スパイク時間が経過すると、URLを取得できます。別のリクエストを通じて。
- ユーザーが注文ページの購入ボタンをクリックして直接無効にするため、ユーザーが購入ボタンを常にクリックしないようにする必要もあります。
(2)注文の送信
スパイクシステムアーキテクチャソリューションの焦点は、注文送信ステップが最も複雑であり、他のステップはページ表示のロジックのみであるため、注文送信です。キャッシュまたはCDNを使用して高い同時実行性の問題に対処することは難しくありません。
したがって、注文送信リンクでは、システムの各レイヤーで不要なリクエストを除外するために、可能な限りのことを行う必要があります。
ゲートウェイレベルのフィルタリングリクエスト
システムにとって、ゲートウェイレベルでユーザーの要求を傍受できれば、このソリューションは非常に費用対効果が高いと言えます。リクエストの95%以上をこのレベルでフィルタリングできる場合、システム全体が非常に安定します。
ゲートウェイレベルでリクエストフィルタリングを実装するにはどうすればよいですか?ここで私は3つの方法を共有します。
- 各ユーザーのアクセス頻度を制限します。たとえば、5秒ごとに注文します。
- 各IPへのアクセス頻度を制限する:このように、ロボットを介して自動的に注文する人がいるのではないかと心配しているため、実際のユーザーを誤って殺してしまいます。
- 一定期間内に一定の割合のリクエストをインターセプトするか、特定の数のリクエストのみがバックグラウンドサーバーに入ることを許可します。(ここでは、フロー制限リーキーバケットまたはトークンアルゴリズムを使用できます。これについては、後の記事で詳しく説明します)
バックエンドサーバーのフィルタリングリクエスト
リクエストがバックエンドサーバーに入った後、私たちの目標は、リクエストをフィルタリングする方法ではなく、スペシャルが売られ過ぎないようにする方法と、スペシャルの注文データの正確さを確保する方法です。
それを実装する方法は?以下の3つの方法があります。
- 商品在庫はキャッシュに配置されます:すべてのリクエストがデータベースに送信されて商品在庫を照会すると、データベースは確実にそれを運ぶことができないため、ユーザーが配置するたびに在庫をキャッシュに保存する必要があります注文の場合、最初にdecrを使用して在庫を差し引き、返品額を判断します。Redisの在庫が0未満で差し引かれる場合、スパイクが失敗し、在庫の増分が返されることを意味します。Redisの在庫が0より大きい場合、スパイクが成功し、注文が作成されることを意味します。
- 注文はキャッシュに書き込まれます:キャッシュの書き込みの第6章で、スキームについて説明しました。つまり、注文データは最初にデータベースに入れられるのではなく、最初にキャッシュに入れられ、次に定期的に注文をバッチ挿入します。 (100ms)。注文後、ユーザーは最初に待機ページに入り、次にこのページが定期的にバックグラウンドで注文データをポーリングします。注文データをポーリングするプロセスでは、バックエンドは最初にRedisで注文データをクエリします。注文データが見つからない場合は、データベースにアクセスして注文データをクエリし、ユーザーに直接返します。ユーザーは次のことができます。メッセージ通知を受け取った後、直接支払いを入力します。ページは支払い済みです。データベース内の注文データを照会するときに、スパイクが失敗したことを示すものは見つかりません。(理論的には、見つけることは不可能ではありません。見つけることができなかった場合は、フォローアップとフォローアップのために例外をスローすることを忘れないでください。)
- 注文のバッチドロップオフ:定期的に注文をバッチでドロップし、注文がドロップされたときにデータベースの在庫を差し引く必要があります。
上記は、注文送信操作のアーキテクチャ設計です。主にゲートウェイ層とバックエンドサーバーで関連する設計を行っていることを理解するのは難しいことではありません。
(3)支払いページはどのようにアップストリームのリクエストをブロックしますか?
支払いページでは、基本的にユーザーのリクエストをフィルタリングする必要はありません。このリンクでは、データの整合性を確保することに加えて、1つの重要な点にも注意を払う必要があります。ビジネスロジックで時間内に支払われなかったために注文がキャンセルされた場合は、データベースとRedis在庫を追加し直すことを忘れないでください。
第三に、全体的なサーバーアーキテクチャ
スパイクシステムアーキテクチャの以前の階層化された設計アイデアを確認しましょう。これは、スパイクシステムの全体的なサーバーアーキテクチャスキームでもあります。
スパイクシステムの高可用性を確保するには、サーバーアーキテクチャ全体で、上の図のすべてのレベルが高可用性であることを確認する必要があります。したがって、静的リソースサーバー、ゲートウェイ、およびバックエンドサーバーは負荷分散を使用して構成する必要があり、キャッシュRedisおよびデータベースはクラスターモードを使用して構成する必要があります。
サーバーアーキテクチャ全体の重要な部分であるMQもあります。これは、今回のスパイクアーキテクチャソリューションには設計ロジックが含まれていないため、上記の階層化では言及していません。ただし、サービス間で通知がトリガーされた場合は、それを使用する必要があるため、高可用性を確保する必要もあります。(ここでは、マスタースレーブ、フラグメンテーション、およびフェイルオーバーのメカニズムを考慮に入れる必要があります。)
4、まとめ
そうは言っても、スパイクアーキテクチャの予防策は終わりました。第5章、第6章、および第7章で多くの注意点が紹介されているため、この記事の内容は比較的簡潔です。
次の表は、スパイクアーキテクチャのチェックリストをまとめたものです。知識のこの部分は、スパイクシステムを設計するときに役立つ場合があります。
処理する | 案件 |
---|---|
ページを閲覧する | 静的リソースのCDN |
ページを閲覧する | スパイク中に、一部の動的データ要求が静的ページに配置されます |
ページを閲覧する | スパイクの開始時間はサーバーによって異なります |
ページを閲覧する | スパイクの終わりのサインはさまざまな場所に配置されています |
注文する | 注文URLの動的背景を取得する |
注文する | 購入ボタンをクリックするとグレー表示になります |
注文する | ゲートウェイは、次の3つの側面から要求をフィルタリングします。<br> 1.ユーザーアクセス頻度。<br> 2.IPアクセス頻度。<br> 3.全体的なフロー制御。 |
注文する | 在庫はRedisに配置され、キャッシュは毎回売られ過ぎを防ぐと判断されます。 |
注文する | 注文はキャッシュに入れられ、バッチアウトされます。 |
支払い | 注文がキャンセルされた場合は、データベースとRedisインベントリに追加し直すことを忘れないでください。 |
サーバーアーキテクチャ | 静的リソースサーバーの負荷分散。 |
サーバーアーキテクチャ | ゲートウェイの負荷分散 |
サーバーアーキテクチャ | バックエンドサービスの負荷分散 |
サーバーアーキテクチャ | Redisクラスター |
サーバーアーキテクチャ | MQクラスター |
サーバーアーキテクチャ | データベースクラスター |
この記事では、言及していない2つのポイントがあります。
- ゲートウェイ層での現在の制限。
- バックグラウンドの特定のサービスがスパイクのためにダウンしたと仮定して、他のサービスの雪崩を回避する方法。
次の記事では、最も単純なサービス管理から始めて、マイクロサービス関連の知識について話します。注意を払うことを歓迎します。!!