2014 年の双十二節の終わりにタオバオのホームページを引き継いでからほぼ 1 年半が経ちました。ホームページ上の関連業務の引き継ぎはつい最近完了しました。 2 回の改訂と PHP から Node への 1 回の移行を経て、まだ多くの感想が残っています。それを以下に共有します。
タオバオのサイト ページには、ホームページ、その他のチャネル ページ、イベント ページなどが含まれます。これらのページはすべて、タオバオのフロントエンドで 1 行ずつコード化されているわけではありません。この方法に忙しくしていません。実際、ほとんどのページは内部構築プラットフォーム (操作またはモジュール構築によるフロントエンド) に基づいて構築されており、フロントエンドの焦点はプラットフォーム自体の構築と、その汎用性と再利用率の保証にあります。もちろん、モジュール、そしてエンジニアリング関連のものも。
構築プラットフォームを使用して構築されたページの場合、フロントエンドは、ページを構成するアトミック モジュールの開発のみを考慮する必要があります。全体的なレンダリングは、構築プラットフォームによって提供される統合スクリプトに完全に責任があります。タオバオのホームページでは、膨大な数のページ モジュールと、部門間およびチーム間のコミュニケーションが少量であることを考慮して、レンダリング モデルが若干異なります。
2. タオバオのホームページの全体的な変更
背景で述べたように、タオバオのホームページは内部構築プラットフォームに依存しており、その変更は構築システムの変更に自然に追随します。
1. PHP でのタオバオのホームページ
私がタオバオのホームページを引き継いでから間もなく、私はその時、まだ PHP 環境で稼働していました。ここで説明する必要があるのは、タオバオのホームページ上のすべてのコードはフロントエンドによって完全に制御されており、フロントエンドはデータベースを直接扱わず、そのデータソースは2つの部分に分かれているということです。
データソース
まず、操作によって入力されたデータです。フロントエンドディギングの形式を使用して、オペレーターが入力データを取得するためのピットを予約します。次のようなものです (疑似コード):
オペレーターがこれらの穴を埋めると、この PHP テンプレートに対応するデータが生成され、最終的に完全な HTML フラグメントにレンダリングされます (リアルタイム レンダリング)。
2 つ目は、バックエンドまたはパーソナライゼーション プラットフォームによって提供されるデータです。さまざまなビジネスにはさまざまな需要があります。一部の企業は独自のバックエンドを持ち、自社で生成したデータを使用する必要があります。また、ユーザーが異なるコンテンツを閲覧することを期待し、アルゴリズムに接続されることを期待している企業もあります。投資促進データ、および一部の企業はデータプールからフィルタリングされたデータの使用を期待しています... つまり、タオバオのホームページはさまざまなシステムに接続する必要があり、多くのインターフェイスがあります。動的データソースの統合については後述します。
そして、これらのシステムに対応するドメイン名が異なるため、必然的に JSONP 形式が第一の選択肢になります。ただし、広告などの一部の特殊なシステムでは、そのレンダリングは単純な JSONP リクエストではなく、JS のロードやレンダリング制御の引き渡しなど、広告レンダリング プロセス全体に介入する場合もあります。
ページの構造
データのソースとサブモジュールの構造は上で紹介しましたが、ページ全体はどのように構成されているのでしょうか?モジュールの構築には 2 つのタイプがあり、1 つは、オペレーションまたはフロントエンドが開発したモジュール (またはモジュール ライブラリから選択したモジュール) をコンテナにドラッグ アンド ドロップしてページを形成する方法です。
もちろん、上記の写真は単なるモデルであり、ページレイアウト、マルチターミナル対応、モジュールの一時的な非表示、位置調整、スキンの選択、モジュールのコピーなど、システムとして考慮する必要がある問題はたくさんあります。 。
次のソース コード (疑似コード) を使用してビルドすることもできます:
モジュール ID を使用してモジュールを導入し、レンダリング リズムとデータ入力の制御を容易にするために、lazyload などのいくつかのタグを追加します。 。ソースコード構築とモジュール構築の違いは、前者の方がモジュールの構造とモジュールのレンダリング順序を制御しやすいことです。
このプラットフォームにはデータ ソースにアクセスする機能があります。つまり、私たちが掘った穴では、操作でデータを入力できるだけでなく、さまざまなデータ ソースからデータを直接インポートすることもできます。 、ここではデータフィールドマッピング変換が必要です。バックエンドによって提供されるインターフェイスは次のとおりです:
フロントエンドによって合意されたインターフェイス形式は次のとおりです:
ただし、ここで注意する必要があるのは、ページ上のインターフェイスはプラットフォームを通じて統合されていますが、これは、ページに対するすべてのリクエストが最初にプラットフォームを通じて流れ、その後さまざまなバックエンドに分散されることも意味するということです。プラットフォームの抵抗 圧力要件は非常に高くなります。
2. PHP から Node への移行
タオバオのホームページでの 1 日あたりの平均リクエストのレベルは、10 台または 20 台を超えるサーバーでは維持できません。
すべての CDN ノードには PHP レンダリング機能があり、ページが公開されると、ページのすべてのモジュールとデータがすべての CDN ノードに同期されます。見た目はかなり良好ですが、一定期間の運用とメンテナンスの後、多くのセキュリティとパフォーマンスの問題がゆっくりと明らかになりました:
パフォーマンスの問題。各 PHP ページには複数のサブモジュールが含まれており、サブモジュールは PHP のインクルード操作にも負荷がかかり、それらの数千がレンダリング ノードで実行されると想像できます。非常に効率的であること。
プッシュ機構の問題。ファイル同期 (図の同期アクション) は、かなり不快なメカニズムです。まず、ファイルがすべてのノードに同期されるまでの時間を制御することはできません。また、同期プロセスが失敗する可能性もあり、健全性テストのコストも非常に高くなります。高い。発行が比較的コンパクトな場合、同期する必要があるファイルが多数あるため、キューの蓄積が容易に発生し、同期エクスペリエンスが悪化する可能性があります。
強力なリアルタイム要件に伴う問題。ファイルがプッシュされる前に、一部のフロントエンド システムも通過する可能性があります。公開リンクが長いほど、オンラインでの有効時間が遅くなり、有効になるまでに約 5 分かかります。リアルタイム要件(フラッシュセールなど)の場合、これは需要の観点からはまったく受け入れられません。
もちろん、運用保守コストの増加、セキュリティリスクの増加、PHP の上級人材の不足など、他にも多くの問題があります。したがって、PHP レンダリング コンテナーは廃止される運命にあります。
上の図はゲームプレイを変更します。サービス クラスターは Cache CDN であり、静的ファイル処理機能のみを備えており、PHP/Node のレンダリング機能を備えていないため、高い処理効率と優れたパフォーマンスを備えています。 、強い耐圧性があり、耐えられない場合は、お金を出してサービスを購入し、キャッシュ クラスターを拡張することもできます。
キャッシュ応答ヘッダーの制御、クライアント上のページのキャッシュ時間の制御、および max-age によるキャッシュ上のキャッシュの制御。
多くの利点があるため、ここではすべてを列挙しません。このモデルでは、ディザスタ リカバリの層も追加されます。オリジン サーバーは、キャッシュとして同じコンピュータ ルームにあるバックアップ サーバーに定期的にデータをプッシュします。オリジン サーバーに障害が発生した場合、ディザスタ リカバリはバックアップ データに自動的に転送されます。
モデルの変更により、運用とメンテナンスが画期的になるだけでなく、CDN が攻撃された場合のセキュリティ リスクも軽減され、同期に必要なさまざまな検出メカニズムが不要になり、100 万以上のコストが削減されます。年間コストを考えると、その利点は依然として明白です。
上記の PHP モジュールでは、HTML とデータの部分についてのみ説明しましたが、注意深い読者は、CSS や JS などの静的リソースについては言及していないことに気づいたはずです。ページはどのようにレンダリングされますか?
古いバージョンの PHP ページでは、CSS と JS を直接導入しました。これらの静的リソースは Git バージョンの反復リリースを使用して、Git ウェアハウスに直接配置されます。以上です:
git ファイルを公開するたびに、PHP バージョン番号を変更して、PHP コードを公開します。もちろん、git のリリース時にバージョン番号を自動的に更新するなど、関連する最適化も行われています。
新しいバージョンのプラットフォームのページ レンダリング モードは、PHP のページ レンダリング モードとは異なります。
モジュールの掘り出しもテンプレートから独立しており、データ形式は JSON スキーマの形式で定義されます:
モジュールは互いに独立して分離されているため、ある程度の冗長性が存在しますが、モジュールの分離のメリットはこの冗長性よりもはるかに大きくなります。実際、私たちは倉庫を通じて個々のモジュールを管理しています。ページのレンダリングは比較的単純です。上の図に示すように、ソース ノード コンテナーはすべてのindex.xtplを1つのpage.xtplにマージします。これにより、cssとjsも1つのファイルに結合されます。 / cdn/??mod1.css、mod2.css、mod3.css。
次回システムに入るときに、ページはモジュールの更新を認識します。モジュールとページをアップグレードする必要があるかどうかを尋ねるメッセージが表示されます。
3. タオバオホームページのパフォーマンスの最適化
ホームページモジュールがたくさんあるので、一度に吐き出すとDOMの数は確実に4kを超え、結果として最初は非常に長くなります。上映時間。 TMS の開発仕様によれば、各 TMS モジュールにはindex.js とindex.css が含まれており、最後に js と css の 2 つの組み合わせが表示されます。ホームページがロードされるときに、すべてのindex.jsが一度に実行されることはありません。そうしないと、最初にページのブロックが非常に深刻になります。
ページのレンダリングロジック
すべてのTMSモジュールをトラバースします(J_Modを含む) ule フック);
一部の TMS モジュールには JS コンテンツがありませんが、index.js がロードされ、モジュールの JS の実行をスキップするために tb-pass クラスがモジュールに追加されます。 2 つの部分、最初の画面が 1 つ、最初以外の画面全体が 2 番目のブロックになります。まず、最初の画面モジュールを遅延読み込みモニタリングに追加します。
最初の画面モジュールがロードされた後、またはユーザーがページの操作 (スクロール、マウスの動きなど)、最初以外の画面モジュールが遅延読み込み監視に追加されます
は読み込みを開始するいくつかの特別なモジュールを処理します。ウィンドウに入る前に数百ピクセル;
スクロールを監視し、上記のロジックに従ってモジュールをレンダリングします。
一部のモジュールは実行されても、優先度が高くないためレンダリングされない場合があります。コンテンツをレンダリングする前に、mouseover/onload イベントがトリガーされるまで待機するなど、イベント監視がモジュール内に追加されます。
4. タオバオホームページの安定性保証
大規模なトラフィックの下では、どんな小さな問題も大きな問題に拡大されるため、開発プロセス中に遭遇する偶発的な問題には注意を払う必要があります。ただし、地域関連の問題 (上海の CDN ノードがダウンしているなど)、ユーザー属性の問題 (最後のニックネームが文字 s であるユーザー ページの天窓など) など、多くの散発的な問題はテスト環境では見つかりません。 、ブラウザのプラグインの問題、オペレーターの広告挿入の問題など。
オンライン化する前にすべての問題を検討することは困難ですが、災害復旧 + 監視と早期警告という 2 つのことをしっかりと行う必要があります。
1. 完全な災害復旧メカニズム
完全な災害復旧には 2 つのレベルの考慮事項があります:
インターフェース データ形式エラー、インターフェース リクエスト タイムアウトなどを含む、非同期インターフェース リクエスト エラー。 ;
同期レンダリング、ソースページのレンダリングエラー。
同期レンダリングの場合、ページ テンプレートと同期されたデータのみが必要です。どちらかにエラーがある場合、オリジン サイトに戻るときに返されるコンテンツは次のとおりです。ステータス コード 5xx のエラー ページ。このエラーは必ずしも開発者が原因であるとは限りません。同期異常またはシステム リンクのサーキット ブレークの問題が考えられます。この問題に対応して、淘宝網ホームページのミラー ページを作成しました。
発信元サイトに異常があると、Nginx はキャッシュ CDN と同じコンピューター ルームにあるホームページ ミラーに移動します。このミラーのコンテンツは、淘宝網ホームページの HTML バックアップ ソース コードです。
2. モニタリングと早期警告メカニズム
モニタリングにも 2 つのレベルがあります:
モジュールレベルのモニタリング、インターフェースリクエストの配置、モジュールのスカイライト検出など。
モジュールレベルの監視には非常に多くの内容が含まれており、監視ポイントが多ければ多いほど、最終的に問題を特定するのがより効率的になります。これらのモニタリングを埋め込みます:
インターフェース要求フォーマットエラー、要求失敗、要求タイムアウト、少なくとも 3 つの隠しポイント
一部の監視では、明らかなエラーも自動的に処理されます。たとえば、http 画像が https ページの下に表示された場合、これらの問題はすぐに自動的に処理されます。
HTML が仕様に準拠しているかどうかを確認します
JavaScript エラーレポートの検出
ページ上のあらゆる小さな点の変更を追跡できるようにするために、私は多くのページモジュールを用意しています。以下の図に示すように、リンクごとに詳細な統計が作成されます。
インターフェイスのリクエストが失敗するか、インターフェイスが災害復旧ロジックを使用するか、モジュールが 5 回以上レンダリングすると、秒後、コンソールに黄色のアラームが表示されます。もちろん、この時点でアラート統計もサーバーに送信されます。
2. インターフェイス ハブ
インターフェイス ハブは、以下の図に示すように、データ リクエストの管理ツールです。 1 つのデータ ソース。操作フィードバック ページのレンダリング データが異常な場合は、ハブを介してデータを直接見つけることができるため、バグの特定効率が向上します。同時に、ハブは環境を切り替えたり、日常環境またはリリース前の環境でインターフェイスからインターフェイスにリクエストを切り替えたりするためにも使用できます。これは、デバッグ用の強力なツールです。
3. クイックチャンネル
ページ スクリプトの実行の前後にクイック操作チャネルを配置します。スタイルの混乱やオーバーフロー、スカイライトを引き起こすインターフェイス エラーなどの緊急のオンライン問題が発生した場合、ページの CSS と JS を直接変更できます。ショートカット チャネル経由で接続すると、2 分以内にオンラインになります。
ただし、このタイプのチャネルは、緊急の問題を修復する場合にのみ適しています。結局のところ、JS コードを自由に挿入するのは非常に危険です。
VI. 概要
文章は少しアンチクライマックスのようであり(コーディングと描画が非常に疲れる)、まだ拡張や拡張されていない部分がたくさんあります。以上でタオバオのホームページの基本を理解していただければ幸いです。