ホームページ >バックエンド開発 >PHPチュートリアル >12306.cn ウェブサイトのパフォーマンス テクノロジーについて話す
春節が近づくにつれて、12306.cn ウェブサイトのチケットは刻々と不足しており、全国の人々が私たちを叱っています 12306 ウェブサイトのパフォーマンスと実装について議論しましょう。 UI、ユーザーエクスペリエンス、または支払いとチケットの購入と注文を分離する機能的なものではありません)
ビジネスニーズからテクノロジーを切り離すことはできないため、パフォーマンスはまず、ビジネス上の課題についてお話したいと思います。
1. これをQQやオンラインゲームに喩える人もいるかもしれません。しかし、オンライン ゲームと QQ オンラインまたはログイン時にユーザー自身のデータにアクセスするのに対し、チケット予約システムはセンターのチケット数量データにアクセスするという点で、この 2 つは異なると思います。オンライン ゲームも QQ も、機能するという理由だけで同じであるとは考えないでください。オンライン ゲームや QQ のバックエンド ロードは、電子商取引システムのバックエンド ロードよりもまだ単純です。
2. 春節中の列車の予約はウェブサイトのフラッシュセールイベントのようなものだと言う人もいます。確かによく似ていますが、表面的なことを考えなければ、多少違うことにも気づくでしょう。一方で、鉄道のチケットに関しては、大量のクエリ操作が伴いますが、さらに重要なのは、注文時にデータベースに対する多くの一貫した操作が必要になることです。一方、購入者はルート、列車、時間の選択肢が多く、注文方法も常に変更します。フラッシュセールに関しては、直接殺すだけです。クエリや一貫性の問題はそれほど多くありません。さらに、フラッシュ販売に関しては、最初の N 人のユーザーのリクエストのみを受け入れるようにすることもできます (バックエンドでデータを操作せず、ユーザーの注文をログに記録するだけです)。フラッシュ販売数については、100 個の製品を 10 台のサーバーに配置することもできます。その際、データベースを操作する必要はありません。注文数が十分に達したら、フラッシュ セールを停止し、データベースにバッチで書き込みます。そして、フラッシュセール品はあまりありません。鉄道チケットはフラッシュセールほど単純ではなく、春節旅行期間中はほとんどのチケットがホットチケットであり、ほとんどの人々が全国から来ます。また、複数の路線の在庫を処理する必要があります。それがどれほど難しいか考えてみませんか。 (タオバオのダブルイレブンのユーザー数はわずか 300 万人ですが、鉄道のチケットは瞬時に数千万人、場合によっては数億人に達する可能性があります)。
3.このシステムをオリンピックのチケット販売システムと比較する人もいます。まだ違うと思います。オリンピックのチケット販売システムはオンライン化されるとすぐに廃止されましたが。しかし、オリンピックでは抽選方式が採用されており、先着順はありません。また、事前に情報を受け取るだけでよく、事前にデータの整合性を確保する必要もありません。ロックが無く、横方向への拡張も容易です。
IV.チケット予約システムは、電子商取引注文システムと非常に似ている必要があります。どちらも在庫操作を実行する必要があります: 1) 在庫を占有し、2) 支払い (オプション)、3) 在庫を差し引きます。これには整合性チェックが必要です。つまり、同時実行中にデータをロックする必要があります。 B2C 電子商取引企業は、基本的にこれを非同期で実行します。つまり、注文はすぐに処理されず、正常に処理された場合にのみ、システムから注文が成功したことを示す確認メールが送信されます。 。多くの友人が注文登録が失敗したというメールを受け取ったと思います。 これは、データの一貫性が並行性の下でボトルネックであることを意味します。
鉄道の発券ビジネスは非常に異常です。それは突然の切符の発売を利用しており、一部の切符は全員が共有するのに十分ではないため、誰もが切符掴みなどの中国の特徴を持ったビジネスを行っています。 。 練習する。そのため、チケットが発売されると、何百万人、あるいは何千万人もの人々が問い合わせや注文をしに来るでしょう。数十分以内に、Web サイトに数千万のアクセスが訪れる可能性があります。これは恐ろしいことです。 12306の訪問ピークは10億PVと言われており、午前8時から午前10時までに集中し、1秒あたりのPVはピーク時には数千万PVに達します。
B2C にとって在庫は悪夢であり、在庫管理は非常に複雑です。信じられない場合は、従来の小売企業と電子商取引の小売企業すべてに、在庫管理がどれほど難しいかを尋ねてください。そうでなければ、万科の在庫について尋ねる人はこれほど多くないでしょう。 (「スティーブ・ジョブズの伝記」を読むと、なぜティムが Apple の CEO に就任したのかがわかります。主な理由は、彼が Apple の在庫サイクル問題を解決したことです)
Web サイトの場合、閲覧負荷が高いWeb ページの処理は簡単ですが、クエリの負荷は処理が若干困難ですが、クエリの結果をキャッシュすることで処理できます。最も難しいのは注文の負荷です。在庫にアクセスする必要があるため、注文は基本的に非同期で行われます。昨年のダブル 11 の期間、タオバオの 1 時間あたりの注文数は約 60 万件でしたが、JD.com は 1 日あたり 40 万件の注文しかサポートできませんでした (5 年前の Amazon が 1 時間あたり 70 万件の注文をサポートできたのよりさらに悪い)。注文の操作は私たちが思っているほど高性能ではないことがわかります。
タオバオは倉庫がないため、B2C ウェブサイトよりもはるかにシンプルです。そのため、同じ商品の在庫を更新してクエリするための N 個の倉庫がある B2C のような操作はありません。 B2C Web サイトは注文する際、ユーザーの近くにあり、在庫のある倉庫を探す必要があり、多くの計算が必要になります。想像してみてください。北京で本を購入した場合、北京の倉庫に在庫がない場合は、瀋陽または西安の倉庫に在庫があるかどうかを確認する必要があります。 、江蘇省の倉庫などを見なければなりません。タオバオでは、各販売者が独自の在庫を持っているわけではありません。在庫は単なる数値であり、在庫が販売者に分配されるため、業績の拡大につながります。
データの一貫性が実際のパフォーマンスのボトルネックです。 nginx は 1 秒あたり 100,000 件の静的リクエストを処理できると言う人もいますが、私はそれを疑いません。ただし、これは単なる静的なリクエストであり、帯域幅と I/O が十分に強力で、サーバーに十分なコンピューティング能力があり、サポートされる同時接続数が 100,000 の TCP リンクの確立に耐えることができます。問題ない。しかし、データの整合性を考えると、この 100,000 は完全に達成不可能な理論値となっています。
長々と言いましたが、ビジネスの観点から言いたいのは、春節鉄道切符予約ビジネスの異常性をビジネスの観点から真に理解する必要があるということです。
パフォーマンスの問題を解決するには、多くの一般的な方法があります。以下のテクノロジーを使用することで、12306 Web サイトのパフォーマンスが向上すると考えられます。
DNS ロード バランサー (通常、ルーティングに基づいてルーターの負荷をリダイレクトします) を使用すると、ユーザー アクセスを複数の Web サーバーに均等に分散できます。これにより、Web サーバーのリクエストの負荷が軽減されます。 HTTP リクエストは短いジョブであるため、この機能は非常に単純なロード バランサーを通じて完了できます。ユーザーが最寄りのサーバーに接続できる CDN ネットワークを用意するのが最善です (CDN には通常、分散ストレージが伴います)。 (負荷分散の詳細な手順については、「バックエンドの負荷分散」を参照してください)
12306.cn を見てみましたが、60 以上かかります。ホームページとチケット予約ページを開くための HTTP 接続 現在のブラウザでは 70 を超える HTTP リクエストが同時にリクエストされます (もちろん、ブラウザ ページに対する同時リクエストの数には制限がありますが、ユーザーが複数のリクエストを開くことを止めることはできません)。ページ、およびバックエンド サーバーの TCP リンク フロントエンドから開始すると、すぐには解放されず、重要でもありません)。したがって、100 万人のユーザーがいる限り、6,000 万のリンクが存在する可能性があります (最初の訪問後、ブラウザーのキャッシュにより、この数は減少します。たとえ 20% だけだったとしても、それでも 100 万レベルの数です)。リンク)、多すぎます。ログインクエリページであれば問題ありません。ファイルに js を入力し、ファイルに css を入力し、ファイルにアイコンを入力し、css を使用してブロックで表示します。リンクの数は最小限に抑えてください。
画像は帯域幅を大量に消費するため、世界中のすべての企業が画像サービスを提供しようとしているわけではありません。ブロードバンド時代の今、写真ページを作る際に写真を使うのが怖かったダイヤルアップ時代の状況は誰にも理解できません(携帯電話で閲覧する場合も同様です)。 12306 ホームページでダウンロードする必要がある合計ファイル サイズを確認したところ、約 900 KB でした。このホームページにアクセスしたことがある場合、ブラウザは大量のファイルをキャッシュするため、ダウンロードする必要があるのは約 10,000 個のファイルだけです。ただし、極端なケースとして、100 万人のユーザーが同時にアクセスし、全員が初めてアクセスする場合、120 秒以内に 1M をダウンロードする必要があります。 1M /120 * 8 = 66Gbps の帯域幅。すごい。したがって、その日の 12306 の輻輳は基本的にネットワーク帯域幅によるものであると推定され、応答がないことが表示される可能性があります。その後、ブラウザのキャッシュにより帯域幅の使用量が大幅に削減され、負荷がすぐにバックエンドに転送され、バックエンドのデータ処理のボトルネックがすぐに解消されました。そのため、http 500 エラーが大量に表示されます。これは、バックエンド サーバーがダウンしていることを意味します。
頻繁に変更されない一部のページとデータを静的にし、gzip 圧縮します。 もう 1 つの邪悪な方法は、これらの静的ページを /dev/shm の下に置くことです。このディレクトリはメモリから直接ファイルを読み取って返します。これにより、負荷の高いディスク I/O が削減されます。 nginx の sendfile 関数を使用すると、これらの静的ファイルをカーネル内で直接交換できるため、パフォーマンスが大幅に向上します。
多くの人が同じクエリを探しています。リバース プロキシを使用して、これらの同時かつ同一のクエリをマージできます。このテクノロジーは主にクエリ結果のキャッシュを使用して実装され、最初のクエリはデータベースにアクセスしてデータを取得し、後続のすべてのクエリはキャッシュに直接アクセスします。各クエリをハッシュし、NoSQL テクノロジーを使用してこの最適化を完了します。 (この技術は静的ページとしても使用できます)
電車の切符の金額を問い合わせる場合、数字を表示する代わりに「はい」または「いいえ」を表示するだけで、システムの複雑さが大幅に簡素化され、改善されると個人的には思います。パフォーマンス。 。データベース上のクエリの負荷を軽減し、データベースが注文者により適切にサービスを提供できるようにします。
キャッシュは、動的ページのキャッシュに使用でき、クエリ データのキャッシュにも使用できます。キャッシュには通常、いくつかの問題があります:
1) キャッシュの更新。キャッシュおよびデータベースの同期とも呼ばれます。いくつかの方法があります。1 つはキャッシュをタイムアウトし、キャッシュを無効にして再度確認する方法です。もう 1 つは、バックエンドが変更された場合に、フロントエンドに更新を通知する方法です。前者は実装が比較的簡単ですが、リアルタイム性は高くありません。後者は実装が比較的複雑ですが、リアルタイム性は高くなります。
2) キャッシュされたページング。メモリが十分ではない可能性があるため、非アクティブなデータをメモリからスワップアウトする必要があります。これは、オペレーティング システムのメモリ ページングとメモリのスワップに非常に似ています。 FIFO、LRU、および LFU はすべて、比較的古典的なページング アルゴリズムです。関連コンテンツについては、Wikipeida のキャッシュ アルゴリズムを参照してください。
3) キャッシュの再構築と永続化。キャッシュはメモリ内にあり、システムは常に維持する必要があるため、キャッシュが失われると、データ量が大きい場合は再構築する必要があり、キャッシュの再構築プロセスが非常に遅くなります。実稼働環境に影響を与えるため、キャッシュの耐久性も考慮する必要があります。
多くの強力な NoSQL は、上記の 3 つの主要なキャッシュの問題を非常によくサポートしています。
フロントエンドのパフォーマンス最適化テクノロジーについては以前に説明したため、フロントエンドはボトルネック問題ではない可能性があります。その場合、パフォーマンスの問題はバックエンド データに発生します。ここでは、一般的なバックエンドのパフォーマンス最適化手法をいくつか紹介します。
データの冗長性、つまりデータベース内のデータの冗長処理は、テーブル接続などの負荷の高い操作を削減するためのものですが、これによりデータの一貫性が犠牲になります。リスクは比較的高いです。多くの人がデータに NoSQL を使用しています。データが冗長であるため高速ですが、これはデータの一貫性に大きなリスクをもたらします。これは、さまざまなビジネスに応じて分析および処理する必要があります。 (注: リレーショナル データベースを NoSQL に移植するのは簡単ですが、逆に NoSQL からリレーショナル データベースに切り替えるのは困難です)
ほとんどすべての主流データベースはミラーリング、つまりレプリケーションをサポートしています。データベース ミラーリングの利点は、負荷分散に使用できることです。データの一貫性を確保しながら、1 つのデータベースの負荷を複数のプラットフォームに均等に分散します (Oracle の SCN)。最も重要なことは、これにより、1 台のマシンに障害が発生した場合でも、もう 1 台のマシンが引き続き稼働できるということです。
データ ミラーリングのデータの一貫性は複雑な問題である可能性があるため、データを 1 つのデータに分割する必要があります。つまり、ベストセラー製品の在庫を異なるサーバーに均等に分散する必要があります。販売商品には 1 があり、在庫が 10,000 の場合、B2C 倉庫と同様に、それぞれに 1,000 の在庫を持つサーバーを 10 台セットアップできます。
データ ミラーリングでは解決できない問題の 1 つは、データ テーブル内のレコードが多すぎるため、データベースの操作が遅すぎることです。そこで、データを分割します。データを分割するにはさまざまな方法があります。一般的には次のとおりです。
1) 何らかのロジックに従ってデータを分類します。例えば、鉄道チケットの予約システムは、鉄道局ごと、機種ごと、出発駅ごと、目的地ごとなどに分けることができます。とにかく、表を同じ内容で複数のシートに分割することです。フィールドはさまざまなタイプのテーブルであるため、これらのテーブルは負荷を共有するために別のマシンに存在できます。
2) データをフィールドごとに分割します。つまり、テーブルを垂直に分割します。たとえば、頻繁に変更されないデータを 1 つのテーブルに配置し、頻繁に変更されるデータを他の複数のテーブルに配置します。このようにして、テーブルを 1 対 1 の関係に変えると、テーブル内のフィールドの数が減り、パフォーマンスもある程度向上します。さらに、多くのフィールドがあると、レコードの保存が異なるページ テーブルに配置されるため、読み取りおよび書き込みのパフォーマンスに問題が生じます。しかし、複雑なコントロールがたくさんあります。
3) 平均スコア表。最初の方法は必ずしも均等に分割されるわけではないため、特定の種類のデータが依然として大量に存在する可能性があります。そこで、主キーIDの範囲に応じてテーブルを分割する平均的な分散方法もあります。
4) 同じデータパーティション。これについては、上記のデータ ミラーリングで説明しました。つまり、同じ製品の在庫値が異なるサーバーに割り当てられます。たとえば、在庫が 10,000 個ある場合、それらを 10 台のサーバーに割り当てることができ、1 台のサーバーには 1,000 個の在庫があります。次にロードバランス。
これら 3 種類のパーティションには長所と短所があります。最も一般的に使用されるのは最初のものです。データが分割されたら、フロントエンド プログラムにデータの場所を知らせるために 1 つ以上のスケジューラが必要です。 鉄道チケットのデータを分割してさまざまな省や都市に配置すると、12306 システムのパフォーマンスが非常に有意義かつ質的に向上します。
データのパーティショニングはある程度の負荷を軽減できますが、鉄道チケットの場合は負荷を軽減できません。一部の主要路線のチケットは大都市とみなされます。これには、負荷を軽減するためにデータ ミラーリングを使用する必要があります。データ ミラーリングを使用する場合は、バックエンドで負荷分散を使用する必要があります。トラフィックはサーバーの混雑度を表すものではないため、ルーターなどのロード バランサーを使用するのは難しい場合があります。したがって、各サーバーの負荷も監視できるタスク分散システムが必要です。
タスク配布サーバーにはいくつかの問題があります:
負荷状況が比較的複雑です。何が忙しいのか? CPUが高いのか?それともディスク I/O が高いのでしょうか?それともメモリ使用量が多いのでしょうか?それとも同時実行性が高いのでしょうか?それともメモリのページングレートが高いのでしょうか?それらすべてを考慮する必要があるかもしれません。この情報はタスク アロケータに送信され、タスク アロケータは処理のために負荷が最も軽いサーバーを選択します。
タスク配布サーバーはタスクをキューに入れる必要があり、タスクを失うことができないため、永続化する必要もあります。また、タスクをバッチでコンピューティング サーバーに割り当てることができます。
タスク配布サーバーが停止した場合はどうすればよいですか?これには、ライブスタンバイやフェイルオーバーなどの高可用性テクノロジーが必要です。また、永続タスクのキューが他のサーバーにどのように転送されるかにも注意を払う必要があります。
多くのシステムが静的メソッドを使用して割り当てを行ったり、ハッシュを使用したり、単純に順番に分析したりするシステムもあることがわかりました。これらは十分ではありません。1 つは、完全に負荷分散できないことです。静的メソッドのもう 1 つの致命的な欠点は、コンピューティング サーバーがクラッシュした場合、または新しいサーバーを追加する必要がある場合に、アロケーターがそれを認識する必要があることです。さらに、ハッシュを再計算する必要があります (一貫したハッシュを使用すると、この問題を部分的に解決できます)。
もう 1 つの方法は、負荷分散にプリエンプティブな方法を使用することです。この方法では、ダウンストリームのコンピューティング サーバーがタスク サーバーにアクセスしてタスクを取得します。これらのコンピューティング サーバーがタスクを必要とするかどうかを自分で決定できるようにします。この利点は、システムの複雑さを簡素化できることと、リアルタイムでコンピューティング サーバーを増減できることです。ただし、唯一の欠点は、特定のサーバーでのみ処理できるタスクがある場合に、多少の複雑さが生じる可能性があることです。ただし、全体的には、この方法の方が負荷分散に優れている可能性があります。
非同期、スロットル、およびバッチ処理はすべて、同時リクエスト数のキュー処理を必要とします。
ビジネスにおける非同期とは、通常、リクエストを収集してから処理を遅らせることを意味します。技術的には各処理プログラムを並列化したり、水平拡張したりすることが可能です。ただし、非同期の技術的な問題はおそらく次のとおりです。 a) 呼び出し先によって返される結果には、プロセス スレッド間の通信の問題が含まれます。 b) プログラムをロールバックする必要がある場合、ロールバックは少し複雑になります。 c) 非同期は通常、マルチスレッドとマルチプロセスを伴い、同時実行制御は比較的面倒です。 d) 多くの非同期システムはメッセージ メカニズムを使用しており、メッセージの損失や混乱も複雑な問題となる可能性があります。
スロットル テクノロジは、主に、処理能力を超えるトラフィックによってシステムが過負荷になるのを防ぐための保護メカニズムです。一般に、スロットル テクノロジは、Web サイトに接続されている銀行システムなど、制御できないシステムに対して使用されます。
バッチ処理技術は、基本的に同じリクエストの束をバッチ処理することです。例えば、全員が同じ商品を同時に購入する場合、あなたが購入する必要はなく、一度に一定数のリクエストを集めてデータベースに書き込むことができます。このテクニックはさまざまな方法で使用できます。たとえば、ネットワーク帯域幅を節約するために、ネットワーク上の MTU (最大伝送単位) はイーサネットの場合は 1500 バイト、光ファイバーの場合は 4000 バイトを超えることは誰もが知っています。ネットワーク パケットの 1 つがこの MTU を満たさない場合、それは MTU になります。ネットワーク カード ドライバーはブロックごとにしか効率的に読み取ることができないため、これはネットワーク帯域幅の無駄です。したがって、ネットワーク上でパケットを送信する場合は、ネットワーク I/O を実行する前に十分な情報を収集する必要があります。これもバッチ処理方法です。バッチ処理の敵はトラフィックの少なさです。そのため、バッチ処理システムでは通常、ジョブの量とタイムアウトの 2 つのしきい値が設定されます。1 つの条件が満たされる限り、送信処理が開始されます。
したがって、非同期である限り、通常はスロットルメカニズムがあり、キューに入れるためのキューが存在します。キューがある場合は永続性があり、システムは通常バッチ処理を使用します。 。
Yunfengが設計した「キューイングシステム」がこのテクノロジーです。これは、電子商取引の注文システムと非常によく似ています。つまり、私のシステムはチケット購入注文リクエストを受け取りましたが、実際にはまだ処理していません。このシステムは、独自の処理能力に基づいてこれらの大量の数を調整します。リクエストは少しずつ作成され、処理されます。処理が完了したら、実際にチケットを購入できることをユーザーに伝える電子メールまたはテキスト メッセージを送信できます。
ここでは、ビジネスとユーザーのニーズの観点から、Yunfeng のキュー システムについて説明したいと思います。技術的には、この問題は解決されているように見えますが、ビジネスとユーザーのニーズの観点からは、まだ注目に値する点がいくつかあるかもしれません。深く考えるべき点:
1) キュー DoS 攻撃。まず考えてみましょう、このチームはただの行列なのでしょうか?これでは不十分です。ダフ屋を排除することはできず、単純な ticket_id は DoS 攻撃を受けやすいためです。たとえば、N ticket_id を開始してチケット購入プロセスに入った場合、購入しなければ半額の費用がかかります。チケットを買いたい人が数日間チケットを購入できないようにするのは簡単です。ユーザーは ID カードを使用して列に並ぶ必要があり、購入にはこの ID カードを使用する必要があると言う人もいますが、それでもスキャルピングの列や口座ディーラーを排除することはできません。 N 個のアカウントを登録して列に並ぶことはできますが、購入しないからです。現時点でダフ屋がやるべきことは 1 つだけです。それは、Web サイトを一般人がアクセスできないようにして、ユーザーがその Web サイトを通じてのみ購入できるようにすることです。
2) 列の一貫性?このキューの操作にはロックが必要ですか?ロックがある限り、パフォーマンスは向上しません。想像してみてください。100 万人が同時に場所番号の割り当てを要求すると、このキューがパフォーマンスのボトルネックになります。データベースのパフォーマンスが良くないといけないので、現在よりも悪くなる可能性があります。 データベースの強盗とキューの取得は本質的に同じです。
3) キューの待ち時間。チケット購入には30分もあれば十分ですか?過度に?そのときにユーザーがたまたまインターネットにアクセスできなかったらどうなるでしょうか?時間が短ければ、操作時間が足りないとユーザーから苦情が来ます。時間が長ければ、並んで待っている人たちからも苦情が来ます。この方法は実際の運用には多くの問題を引き起こす可能性があります。さらに、30 分は長すぎます。これはまったく非現実的です。例として 15 分を使用します。ユーザーは 1,000 万人いますが、各時点で入力できるのは 10,000 人だけです。この 10,000 人のユーザーがすべての操作を完了するのに 15 分かかります。この 1,000 万人のユーザーをすべて処理するには、1000*15m = 250 時間、10 日半かかり、電車は早めに出発しました。 (私はただ馬鹿なことを言っているわけではありません。鉄道省の専門家の説明によると、ここ数日、1日平均100万件の注文が出されています。したがって、1,000万人のユーザーを処理するには10日かかります。)この計算は少し単純かもしれません。私が言いたいのは、そのような低レベルでは、負荷の高いシステムではキューイングはビジネス上の問題を解決できない可能性がある)
4) キューの分散です。この待ち行列システムは 1 つの待ち行列だけですか?十分じゃない。なぜなら、切符を購入できる人が同じ列車の同じ種類の切符(電車の寝台など)を購入している場合、彼らは依然として切符を手に入れていることになるため、システムの負荷は依然として高い可能性があります。それらの間で特定のサーバーに集中しています。したがって、最善の方法は、ユーザーのニーズに基づいて、出発地と目的地を提供してユーザーをキューに入れることです。このように、キューは複数存在することができ、キューが複数存在する限り、水平方向に拡張することができます。これによりパフォーマンスの問題は解決できますが、ユーザーが長時間キューに入れられる問題は解決されません。
オンラインショッピングから間違いなく学べると思います。 列に並ぶ(注文する)ときに、ユーザーの情報と購入したいチケットを収集し、ユーザーがチケットを購入する優先順位を設定できるようにします。たとえば、列車 A の寝台寝台が買えない場合は、寝台寝台を購入します。列車 B の寝台を購入できます。それでも購入できない場合は、列車 B の寝台を購入できます。硬めの座席などを購入するだけです。その後、ユーザーが最初に必要な金額をチャージし、システムが注文を完全に処理します。自動的かつ非同期的に。成功したかどうかにかかわらず、ユーザーにはテキスト メッセージまたは電子メールで通知されます。このようにして、システムはユーザーの対話時間を 30 分節約し、処理を自動的に高速化できるだけでなく、同じチケット購入リクエストを持つユーザーを統合してバッチ処理することもできます (データベース操作の数を削減します)。 この方法の最も優れた点は、キューに並んでいるユーザーのニーズを把握できることです。ユーザーのキューを最適化し、ユーザーを異なるキューに分散できるだけでなく、鉄道省が Amazon のウィッシュリストのように列車のスケジュールを作成できることです。座標の調整と調整 (最後に、キュー システム (順序付けシステム) は、メモリだけでなくデータベースに保存するか永続化する必要があります。そうしないと、マシンがダウンしたときに叱られます)。
まとめ
長々と書いてきましたので、以下にまとめておきます:
0) どのように設計しても、システムは水平方向に拡張しやすいものでなければなりません。言い換えれば、データ フロー全体のすべてのリンクは水平方向に拡張できる必要があります。このようにすると、システムにパフォーマンスの問題が発生した場合に、「30 倍のサーバーを追加する」ということは笑い話にならないでしょう。
1) 上記の技術は長期的な蓄積がなければ一朝一夕には実現できません。どちらを使用してもある程度の複雑さが発生し、設計は常にトレードオフになることがわかります。
2) 集中チケット販売は処理が困難です。上記のテクノロジーを使用すると、チケット予約システムのパフォーマンスが何百倍も向上します。さまざまな省や都市にサブステーションを建設し、チケットを個別に販売することが、既存のシステムのパフォーマンスを質的に向上させる最善の方法です。
3) 春節旅行前夜にチケットを入手するというビジネスモデルは、需要に比べてチケットの供給がはるかに少なく、この種のビジネスでは数千万人、場合によっては数億人がログインすることができます。朝の8時に同時にチケットを手に入れるパターンは、倒錯中の倒錯です。その営業形態の異常さから、何をやっても必ず叱られると判断されている。
4) たった1、2週間だけこれだけ大きなシステムを構築して、残りの時間を無為に過ごすのは残念です。これは鉄道にしかできないことです。