バックエンドの知識体系--完全なHTTP要求

5461 ワード

ここでいうリクエストはバックエンドDevOpsが制御できる範囲内であり,DNS解析,階層的ルーティングなどを含まず,すべてリクエストが我々自身が架設したサーバに到達することから始まる.
1.サーバとの接続
1.1 TCP接続の確立
クライアントの要求がサーバに到達するには,まずTCP接続を確立することである.
  • Clientはまず接続試行を送信し、ACK=0は確認番号が無効であることを示し、SYN=1は接続要求または接続受付メッセージであることを示し、同時にこのデータ新聞がデータを携帯できないことを示し、seq=xはClient自身の初期シーケンス番号(seq=0はこれが0番パケットであることを表す)を示し、このときClientはsyn_に入るsent状態は、クライアントがサーバの返信を待つことを示す
  • サーバは、接続要求メッセージを受信した後、接続の確立に同意した場合、Clientに確認を送信します.TCPメッセージヘッダのSYNとACKはともに1とし,ack=x+1は相手の次のメッセージセグメントを受信することを望む最初のデータバイト番号がx+1であることを示すとともに,xまでのすべてのデータが正しく受信されたことを示す(ack=1は実はack=0+1,つまりクライアントの1番目のパケットであることが望ましい).seq=yはサーバ自身の初期シーケンス番号を表す(seq=0はサーバ側から発行された0番目のパケットを表す).このときサーバはsyn_に入りますrcvdは、サーバがClientの接続要求を受信したことを示し、clientの確認を待っている.
  • Clientは、確認を受信した後、確認を再度送信するとともに、サーバに送信するデータを携帯する必要があります.ACKセット1は、確認番号ack=y+1が有効(サーバを受信したい第1のパケットを表す)であり、Client自身のシーケンス番号seq=x+1(これが私の第1のパケットであり、第0のパケットに対して)であり、Clientの確認を受けると、このTCP接続はEstablished状態になり、httpリクエストを開始することができる.

  • 1.2一般的なTCP接続制限
    1.2.1ユーザープロセスが開くファイル数の制限を変更する
    Linuxプラットフォームでは、クライアント・プログラムを作成してもサービス・エンド・プログラムを作成しても、高同時TCP接続処理を行う場合、最高の同時実行数は、システムがユーザーの単一プロセスに対して同時にファイルを開くことができる数に制限されます(これは、システムがTCP接続ごとにsocketハンドルを作成し、各socketハンドルもファイルハンドルであるためです).ulimitコマンドを使用して、現在のユーザープロセスが開くことができるファイル数の制限を表示できます.windowsでは256、linuxでは1024、このブログのサーバは65535です.
    1.2.2ネットワークカーネルのTCP接続に関する制限を修正する
    Linux上で高同時TCP接続をサポートするクライアント通信処理プログラムを作成すると,ユーザに対するシステムの同時オープンファイル数の制限が解除されているにもかかわらず,同時TCP接続数が一定数に増加した場合,新しいTCP接続の確立に成功しないことが発見されることがある.このような現在の原因は多種ある.1つ目の理由は、Linuxネットワークカーネルがローカルポート番号の範囲に制限があるためかもしれません.このとき、なぜTCP接続が確立できないのかをさらに分析すると、connect()呼び出しの戻りに失敗し、システムエラーメッセージが「Can't assign requestedaddress」であることがわかります.また、この時点でtcpdumpツールでネットワークを監視すると、TCP接続がまったくない場合にクライアントがSYNパケットを送信するネットワークトラフィックが発見される.これらの状況は、ローカルLinuxシステムカーネルに制限があることを示しています.
    実際、問題の根本的な原因はLinuxカーネルのTCP/IPプロトコル実装モジュールがシステム内のすべてのクライアントTCP接続に対応するローカルポート番号の範囲を制限していることにある(例えば、カーネル制限ローカルポート番号の範囲は1024~32768の間である).システム内のある時点で同時にTCPクライアント接続が多すぎる場合、各TCPクライアント接続は一意のローカルポート番号(このエンドスローガンはシステムのローカルポート番号の範囲制限にある)を占有するため、既存のTCPクライアント接続がすべてのローカルエンドスローガンを満たしている場合、新しいTCPクライアント接続にローカルポート番号を割り当てることができなくなり、これにより、connect()呼び出しで失敗が返され、エラーメッセージが「Can't assignrequested address」に設定されます.
    2.HTTPリクエストの開始
    2.1要求フォーマット
    例えばこのようなリクエスト
    Acceptはサーバ側にMIMEタイプを受け入れるように伝えることです
    Accept-Encoding圧縮方式を受け入れているように見えるファイル
    Accept-Laangueは、サーバが送信できる言語を示します.
    Connectionはkeep-aliveプロパティのサポートをサーバに伝える
    CookieはリクエストするたびにCookieを携帯し、サーバ側が同じクライアントであるかどうかを識別するのに便利です.
    ホストは、要求サーバ上の仮想ホストを識別するために使用されます.たとえば、Nginxでは多くの仮想ホストを定義できます.ここでは、その仮想ホストにアクセスすることを識別します.
    User-Agentユーザーエージェントは、一般的にブラウザであり、wget curl検索エンジンのクモなど、他のタイプもあります.
    条件リクエストヘッダ:If-Modified-Sinceは、ブラウザがサーバ側にリソースファイルをいつから変更したかを尋ねると、サーバ側のリソースファイルが更新されることを保証し、キャッシュ内のファイルを使用するのではなく、ブラウザが再びリクエストすることを保証します.
    セキュリティリクエストヘッダ:Authorization:クライアントがサーバに提供する認証情報
    2.2 keep-alive/persitent
    HTTPリクエストのたびにTCP接続を再確立するオーバーヘッドが大きいため、keep-aliveというヘッダが現れ、1回のTCP接続で複数のHTTPメッセージを送信/受信できるようになった.
    しかしkeep−aliveには弊害がある.HTTP 1.0では、クライアント開始要求にkeep-aliveヘッダが付加され、サービス側応答時にもkeep-aliveヘッダが付加されると、その一方がアクティブに切断されるまで、この要求はkeep-aliveとみなされる.正しく切断されなければ、このリソースはずっと占有されます.
    ダミーエージェント問題:ダミーエージェントは単純な転送要求であり、解析処理、永続接続の維持などの他の作業を行うことはできませんが、スマートエージェントは受信したメッセージを解析し、永続接続を維持することができます.
        ,                       ,connection:keep-alive              ,            ,          connection:keep-alive   ,           ,             。            ,              ,     ”   “,        ,           :                           ,      ,     connection:keep-alive              ,               ,              OK                ,                       ,           ,              。                  ,                 ,      ,            (                  )。
    
            ,          connection:keep-alive     。
    

    persistent
    HTTP/1.1の永続接続はデフォルトでオンであり、トランザクションが終了した後に接続を閉じるのはヘッダにconnection:closeが含まれている場合のみです.もちろん、サーバとクライアントは、永続的な接続をいつでも閉じることができます.
    Connection:closeヘッダを送信すると、クライアントはその接続でより多くのリクエストを送信できません.もちろん、永続的な接続の特性に応じて、正しいcontent-lengthを転送する必要があります.
    また、HTTP/1.1の特性に基づいて、HTTP/1.0クライアントと永続的な接続を確立すべきではない.最後に、必ず再送の準備をしなければなりません.
    パイプ接続
    HTTP/1.1は、パイプを永続的な接続で使用することを可能にし、前の要求の応答を待つことなく、パイプ上で2番目の要求を直接送信し、高い遅延で性能を向上させる.
    パイピング接続の制限:
  • は、永続的な接続でなければパイプを使用できません.
  • は、メッセージにラベルがないため、順序が乱れている可能性が高いので、同じ送信順序で応答を返信する必要があります.
  • 永続接続をいつでも閉じることができるので、いつでも再送準備
  • をしなければならない.
  • は、post、反復コミットなどの副作用のある要求をパイプ化して送信するべきではない.

  • 3.負荷等化
    HTTPリクエストを受信すると,ロード・バランシングが登場し,サイトの最先端に位置し,短時間で高いアクセス量を異なるマシンに割り当てて処理する.ロード・バランシング・スキームには、ソフトウェア、ハードウェアの2種類があります.
    F 5 BIG-IPは有名なハードウェア案ですが、ここでは議論しません.
    ソフトウェアの方案はLVS HAProxy Nginxなどがあって、後で補充します
    4.Nginx(WEBサーバ)
    典型的なRailsアプリケーション導入スキームでは、Nginxの役割は2つあります.
  • 静的ファイル要求
  • の処理
  • バックエンドに要求を転送するRailsアプリケーション
  • これは簡単なNginxプロファイルです
    バックエンドのRailsサーバはunix socketを介してNginxと通信し、Nginxサーボpublicフォルダの静的ファイルをユーザーに与える
    5.Rails(アプリケーションサーバ)
    この文章は无敌になって、私は更に书くことができることがなくて、ただ1つの私が使うのがPumaだと言うことしかできません.サーバーはシングルコアなので、マルチスレッドPumaかイベント駆動のThinしか使えないので、後でRails 5 ActionCabelを使うかもしれないと考えて、直接Pumaに乗りましょう.
    6.データベース(データベースサーバ)
    アプリケーション・サーバがデータベースにアクセスするには、データベースに接続する必要があります.Railsはdatabaseを読み込む.ymlの構成で、対応するデータベースにアクセスします.
    重要な構成指標pool:Railsのデータベース接続は完全なスレッドで安全であり、すべてのpoolの値はPumaの最大スレッド数と等しいように構成すると、スレッドがデータベース接続を待つことはありません.
    7.Redis、Memercache(キャッシュサーバ)
    8.メッセージキュー
    9.検索
    参考文献
    完全なHTTPトランザクションはどのようなプロセスですか?
    Linuxでの高同時socket最大接続数には様々な制限があります
    Keep-Alive
    持続的な接続について--HTTP権威ガイド読書心得(五)
    データベース接続プールの動作原理