はじめに
最近「ネットワークはなぜつながるのか」を読みました。
しかし、ただ読んだだけでは学習の理解度が高まらないので、ラーニングピラミッドに則ってアウトプットとして解説を書きます
もし正しくないところなどあればコメントください!
学習の動機
私は普段webエンジニアとして働いています。
しかし、エンジニアとしての働き始めてから1年程度で、まだまだ知らないことがたくさんあります。
そのため、業務に役立つキャッチアップをしなければいけないと感じていて、特にwebページが表示される仕組みについてあまり詳しく知りませんでした。
自分がurlを入力してからwebページが表示されるまでに何が起こっているのか?
HTTP,TCP/IPなど、なんとなくどういうものかは知っているが、詳しい仕組みはわかっていませんでした。
今回はしっかりと学び直し、根本的な部分の理解を深めることで、日々の業務への貢献度が高まるなと感じました。
また、よく企業面接で「URLを入力してからwebページが表示されるまでの仕組みを解説してください」というの質問が出されます。
その際に適切に回答できたらかっこいいなと思ったから勉強しようと決意しました。
データの流れ
まず、あなたがhttps://client.example.comをブラウザに入力してEnterしたとします。
そうするとまず、ブラウザはURLを解析し、DNSサーバーに問い合わせを行い、URLからIPアドレスを特定します。
DNSサーバーからこのURLに対応するIPアドレスは"168.152.1.1だよ"とレスポンスが返ってくるので、そのIPアドレスをもとにwebサーバーにHTTPリクエストを送信します。
webサーバーはHTTPリクエストからHTTPレスポンスを返します。
ここにhtmlやjavascript,cssがあります。
webブラウザはwebサーバーから返却されたhtmlなどをレンダリングして、実際に表示するという流れです。
この流れを詳しく解説していきます。
webブラウザ
URLの解析
ブラウザはまずURLを解読します。
HTTPとはプロトコル、つまり約束事です。
HTTPについて
webサーバーにリクエストを送る際に、webサーバーに何をして欲しいのか伝える必要がありますが、そのフォーマットのことです。
HTTPのメソッドはたくさんありますが、実際に使われているのはほぼGETとPOSTです。
GETの場合はメッセージボディが空になります。なぜならデータの取得だけで送信は行わないから。
POSTの場合はメッセージボディに送信したいテキストが入ります。
ヘッダーフィールドはたくさん種類があります。
私が実際にこれを勉強した時はCORSエラーになった際にヘッダーの設定をしました。
ここではCORSエラーについては詳しく解説しませんが、フロントエンド開発時にAPIサーバーを利用する時など頻繁に遭遇すると思われるので、興味がある方は詳しく調べてみてください。
HTTPリクエストを送信したら、サーバーからはレスポンスが帰ってきます。
その結果には一行目にHTTPのステータスコードが返されます。
成功の場合は200~
リダイレクトは300~
クライアントエラーは400~
サーバーエラーは500~
つまりよく目にする404 not foundはクライアント側のエラーで、該当アドレスのページがないことなどが主な原因です。
このようにエラーの原因をある程度特定できるので、ステータスコードは非常に重要です。
ちなみにこのHTTPリクエストとレスポンスはchromeのデベロッパーツールから実際のデータを確認することもできます。
これを見るとqiitaのページを表示するためにGETメソッドを用いて、ステータスは200で成功していることがわかりますね。
Responseタブを開くと、返却されているhtmlも確認できます。
これがAPIサーバーとの通信になると、responseがjsonになったりします。
IPアドレス
ブラウザはURLを解読したり、HTTPメッセージを作ることはできますが、そのメッセージをネットワークに送ることはできません。
そのためOSに依頼して送信します。
その際にどのOSに送信するか判別するためにIPアドレスが必要になります。
IPアドレスを探す機能はSocketライブラリが提供しています。
Socketライブラリのリゾルバというものを利用します。
DNSサーバー
DNSサーバーは名前、クラス、タイプが一致するものを返します。
名前=www.examle.com
クラス=IN
タイプ=A
返答192.152.168
のような形ですね。
これは実際にドメインを登録したことがある人なら理解しやすいかと思います。
お名前.comなどにもこのような登録する項目が存在します。
ドメインの階層構造
ドメインは階層構造になっています。
実はurlはwww.examle.com.のように最後に.がついていて、この.がルートドメインに当たります。
ルートドメイン.→.com→expamle→wwwと降っていき、www.examle.comのwebサーバーを探します。
ちなみに、DNSサーバーは一度検索した結果を一定期間キャッシュに保存します。
そのため、一度接続したドメインには素早く接続することが可能です。
プロトコルスタック
上記にも記載したようにブラウザは実際にメッセージを送信する機能を持っていないので、メッセージ送信はOS内部のプロトコルスタックが行います。
サーバーとクライアント間でソケットを繋いでデータを送受信します。
このソケット同士を接続する際に、ソケットを識別するために使用するのがディスクリプタというものになります
TCP/IP
データを送信する際にソケットは
作成
接続→connect
送受信→read,write
切断→close
抹消
という工程があります。
TCPプロトコル
データの送受信にはTCPとUDPという二つのプロトコルがあります。
TCPはデータが正しく相手側に送信されたかACK番号によって確認します。
そのためTCPではデータの送信に信頼性がありますが、転送速度は低速になってしまいます。
パケット
データは小さい小包のような形としてパケットという単位に分けて送信されます。
パケットの中身はヘッダーとデータです。
ヘッダーにはどこにパケットが送られるかという情報があり、データ部分には実際に送信されるデータがあります。
UDPプロトコル
UDPでは接続のフェーズがありません。
パケットは送信のみで、TCPのように送ったパケットの状態を監視することはないので、データが抜け落ちる可能性があります。
UDPでは高速なデータの送信ができるので、音声や動画データの送信に向いています。
ハブ、ルーターの章は今回省略
アクセス回線
アクセス回線というのはインターネットと家庭や会社のLANを結ぶ通信回線のこと。
インターネットも家庭のLANと同じ仕組みです。
単純に規模が大きくなっただけ
アクセス回線にはADSL,FTTH,CATV,電話回線などがある
ADSL
ADSLモデムがパケットをセルに分割し、電気信号に変えて送信します。
この信号は電話回線を使って渡されます。
電話からの電気信号なのか、ADSLの電気信号なのかはスプリッタが判断して分けます。
そうして信号が電話局に送られます。
光ファイバ(FTTH)
光ファイバでは電気信号ではなく、光の信号を流してデジタルデータを伝えます。
電気と光の速度はほとんど変わりませんが、電気信号は周波数が高くなるほど、伝送損失が大きくなります。
しかし、光信号では伝送損失が少ないため、高速で安定したデータの送信が可能になります。
webサーバー
webサーバーにはパケットを送信しますが、その前にファイアウォールを通過する必要があります。
ファイアウォールは特定のパケットのみをwebサーバーに通します。
その方式はパケット・フィルタリング型が主流です。
パケットフィルタリングでは、パケットのヘッダー情報を使って判断します。
しかし、ファイアウォールではパケットの中身までは見れないので、パケットに有害なデータが含まれていた場合攻撃されてしまいます。
負荷分散
・DNSサーバーに複数のサーバーを対応づけるラウンドロビン方式
例えば
というサーバー名に対して
192.0.2.60
192.0.2.70
192.0.2.80
という3つのIPアドレスを対応づけると、最初の問い合わせには
192.0.2.60 192.0.2.70 192.0.2.80
と3つ並べて回答し、次の回答には
192.0.2.70 192.0.2.80 192.0.2.60
と並び替えて回答していくので、複数サーバーにアクセスを分散されることが可能です。
欠点
・webサーバーが故障していてもそのwebサーバーに振り分けてしまう
・複数のページにまたがってやり取りする場合、やり取り履歴が消えてしまう。
ロードバランサー
上記の不具合を解決するために、ロードバランサーがある。
まず、ロードバランサーをwebサーバーの代わりにDNSサーバーに登録します。
そうするとクライアントはロードバランサーにリクエストを送り、ロードバランサーが適切なwebサーバーにリクエストを送信します。
これにより、複数ページに跨った場合も同じwebサーバーとやり取りでき、安定したデータの送受信が可能になります。
キャッシュサーバー
webサーバーを複数台並べるのではなく。データベースサーバーとwebサーバーというふうに役割に応じてサーバーを分ける方法のこと。
キャッシュサーバーはプロキシという仕組みを使って、データをキャッシュするサーバー。
プロキシとはwebサーバーとクライアントの間に入ってWebサーバーへのアクセス動作を仲介する役割を持ったもの。
また、Webサーバーから受け取ったデータをディスクに保存しておき、そのデータをWebサーバーに変わってクライアントに送り返す機能を持っています。
これをキャッシュと呼び、キャッシュサーバーはこの機能を利用します。
キャッシュサーバーはWebサーバーから受け取って保存しておいたデータを読み出してクライアントに送信するだけなので、Webサーバーより素早くデータを送信することができる。
クライアント側にキャッシュサーバーを置く方法もある。
→インターネットへのトラフィックを減らせるので効率はいいが設定が大変。
そうして生まれたのがCDNです。
CDN(コンテンツ配信サービス)
インターネット全体にキャッシューサーバを配置し、クライアント側に近い場所のキャッシュサーバーにアクセスさせるサービスのこと。
これを使えば、トラフィックを減らしつつwebサーバー側がキャッシュサーバーをコントロールできる。
CDNを使う場合、インターネット全体に設置されたキャッシュサーバーから最寄りのキャッシュサーバーを見つける必要があります。
その方法の一つがHTTPヘッダーのLocationを使用する方法です。
Locationが近いキャッシュサーバーにリダイレクトさせることで、最寄りのキャッシュサーバーを設定できる
webサーバー
webサーバーはクライアント側から複数のリクエストが送られてくるため、1対多の対応が必要です。
そのため、クライアントとの接続を待ち受ける部分とやり取りする部分に分かれています。
また、それぞれのクライアントごとに1対1の対応をするためにはマルチスレッドと呼ばれる機能により、多数のプログラムを同時並列実行できます。
webサーバーはクライアント側から送られたHTTPリクエストに則ってHTTPレスポンスを返します。
ブラウザがHTTPレスポンスを受け取る
まず、レスポンスメッセージのヘッダーフィールドにあるContet-Typeでデータの種類を判断します。
例
ContentType:text/html; charset=utf-8
ちなみにHTTPレスポンスはタイプごとに送信するので、text.html以外にも
image, video, messageなど様々存在します。
最後にブラウザが受け取ったデータを表示して終了です。
まとめと感想
再度流れをまとめると
1.urlをDNSサーバーに問い合わせ、IPアドレスを取得する
2.IPアドレスからwebサーバーを特定し、HTTPリクエストを送信する
3.webサーバーはHTTPリクエストを読み取り、HTTPレスポンスを返す
4.ブラウザが受け取ったHTTPレスポンスから画面を表示する
この間にロードバランサーがあったり、キャッシュサーバーになったりと色々細かい部分がありますが、基本的な流れは上記になると理解しています。
根本的な仕組みを理解することで、どこでエラーが発生しているのか?
パフォーマンスの最適化などが可能になると感じました。
CDNを使うとなぜ画像の表示が早くなるのか、キャッシュサーバーとは?プロキシとは?など、自分の理解が浅かった部分がしっかり理解できたので、本書はすごく役に立つものだなと感じます。
また、学習は反復することで身に付くのでこれからもちょくちょく見返して理解を深めようと思います。
もし参考になったらいいねやストックしていただけると嬉しいです。
twitterでwebのフロントエンドについて主に発信しているので、よかったらフォローしてください!
一緒に勉強していきましょう
twitter
https://twitter.com/js_manabitai
参考