バックエンドエンジニアのためのネットワーキング
バックエンドエンジニアが、信頼性の高いサービス間通信とトラブルシューティングのために必要な、基本的なネットワーク概念を理解する。
バックエンドエンジニアにとってネットワーキングが重要な理由
バックエンドシステムは単独で動作するわけではありません。ほとんどのバックエンド機能は、ネットワークを介してマシン同士が通信することに依存しています。
- バックエンドサービスは、ネットワークを通じて他のシステムとデータをやり取りします。
- すべての API リクエストには、マシン間の通信が含まれます。
- ネットワークの状態は、システムのパフォーマンスや信頼性に影響することがよくあります。
詳細
バックエンドシステムは、リクエストを受け取り、ロジックを実行し、レスポンスを返すように設計されています。実際には、それらのリクエストは通常、バックエンドが動作している同じコンピュータではなく、別のマシンから送られてきます。
ユーザーが Web アプリやモバイルアプリを操作すると、そのデバイスはインターネットを通じてリモートサーバーにリクエストを送信します。そのリクエストは、バックエンドアプリケーションに届くまでに複数のネットワークコンポーネントを通過します。
バックエンドシステムは内部でも通信します。あるサービスが別のサービスを呼び出したり、データベースサーバーに問い合わせたり、外部 API にリクエストを送信したりします。これらのやり取りはすべてネットワーク越しに行われます。
そのため、多くのシステム問題はアプリケーションコードではなく、ネットワークの挙動に起因します。API 呼び出しが遅いのはネットワーク遅延が原因かもしれませんし、接続が切れるとリクエストが中断されることがあります。また、レスポンスが時間内に届かない場合には再試行が発生することもよくあります。
マシンがネットワークを介してどのように通信するかを理解すると、エンジニアは分散システムにおけるパフォーマンス、信頼性、障害シナリオをより適切に判断できるようになります。
リクエストがサーバーに届くまで
バックエンドコードがリクエストを処理する前に、クライアントはサーバーを見つけ、ネットワーク接続を確立し、複数のインフラ層を通してリクエストを送信する必要があります。
- クライアントはまず DNS を使ってドメイン名をサーバーの IP アドレスに解決します。
- TCP 接続は、マシン間に信頼性の高い通信チャネルを確立します。
- ロードバランサーなどのインフラが、リクエストをバックエンドサーバーへルーティングします。
詳細
クライアントアプリケーションがバックエンドシステムにリクエストを送信すると、バックエンドコードが実行を開始する前に、いくつかのネットワーク手順が発生します。
このプロセスは通常、api.example.com のようなドメイン名から始まります。コンピューターはドメイン名を使って直接通信できないため、クライアントはまず DNS ルックアップを実行して、対象サーバーの IP アドレスを特定します。
IP アドレスが分かると、クライアントはそのマシンとの TCP 接続を確立します。この接続によって、クライアントとサーバーの間でデータを送信するための信頼性の高いチャネルが作られます。
接続が確立されると、クライアントは HTTP リクエストを送信します。このリクエストには、メソッド、ヘッダー、そしてバックエンドシステムに必要なデータが含まれます。
現代のアーキテクチャでは、リクエストはアプリケーションサーバーに届く前にロードバランサーを通過することがよくあります。ロードバランサーは、どのバックエンドマシンがリクエストを処理するかを決定し、複数のサーバーにトラフィックを分散するのに役立ちます。
最後に、リクエストはアプリケーションサーバーに到達し、そこでバックエンドアプリケーションがそれを処理し、ビジネスロジックを実行し、クライアントへ戻るレスポンスを生成します。
DNS(ドメインネームシステム)
DNS は、人間が読めるドメイン名を IP アドレスに変換し、コンピュータがネットワーク上のサーバーを見つけられるようにします。
DNSは名前をIPに解決します。キャッシュ(ループ2で表示)はこれを大幅に高速化します。
- ドメイン名は、サービスを識別するための人間にとってわかりやすい方法を提供します。
- DNS は、ドメイン名をサーバーの IP アドレスに解決します。
- キャッシュは、以前に解決した結果を保存することで検索時間を短縮します。
詳細
コンピュータは、142.250.72.14 のような数値の IP アドレスを使って互いに通信します。しかし、人間は api.example.com のようなドメイン名のほうが覚えやすいため、サービスとのやり取りにはドメイン名を使います。
Domain Name System (DNS) は、これらのドメイン名を対応する IP アドレスに対応付ける分散ディレクトリとして機能します。クライアントがドメイン名を使ってサーバーに接続したいとき、正しい IP アドレスを特定するために DNS クエリを送信します。
この検索処理では、複数の DNS サーバーが連携することがあります。最終的にシステムは、要求されたドメインに関連付けられた IP アドレスを返し、クライアントはリクエストの送信先を知ることができます。
効率を向上させるために、DNS の応答はオペレーティングシステム、ブラウザ、中間サーバーによってキャッシュされることがよくあります。最近の検索結果がすでにキャッシュにあれば、システムは新しい DNS クエリを実行する代わりに、保存された IP アドレスを再利用できます。
DNS はインターネットインフラの基盤となるコンポーネントです。DNS がなければ、ユーザーやアプリケーションは、やり取りするすべてのサービスについて数値の IP アドレスを覚え、手動で管理しなければなりません。
ポートとネットワークエンドポイント
IPアドレスはネットワーク上のマシンを識別し、ポートはそのマシン上で動作している特定のサービスを識別します。
- IPアドレスは、どのマシンがリクエストを受け取るべきかをネットワークに伝えます。
- ポートは、リクエストをそのマシン上の正しいサービスへ振り分けます。
- 複数のサービスを、異なるポートを使って1台のホスト上で同時に実行できます。
詳細
クライアントがサーバーのIPアドレスを知っていても、そのサーバー上のどのアプリケーションがリクエストを処理するのかを判断する必要があります。ここでポートが使われます。
ポートは、マシン上の論理的な通信エンドポイントです。IPアドレスがホスト自体を識別するのに対し、ポートは着信接続を待ち受ける特定のサービスを識別します。
たとえば、Webサーバーは通常、HTTPトラフィックにはポート 80、HTTPSトラフィックにはポート 443 で待ち受けます。データベースやその他のサービスにも、よく知られたポートがあります。PostgreSQL は一般的にポート 5432 で待ち受け、Redis はよくポート 6379 で動作します。
ポートによってサービスが分かれるため、1台のマシンで多くの異なるアプリケーションを同時に実行できます。バックエンドサーバーは、HTTP API、データベース、キャッシュサービスを同時にホストでき、それぞれが別のポートに割り当てられます。
IPアドレスとポート番号を組み合わせることで、ネットワークエンドポイントが定義されます。このエンドポイントによって、リクエストをどこへ届けるべきかが一意に決まります。
TCP接続
TCPは、マシン間でデータを信頼性高く、順序どおりに配信することを保証する、接続ベースのプロトコルです。
- TCPは、データを送信する前に2台のマシン間で接続を確立します。
- このプロトコルは、送信されたパケットの信頼性の高い配信を保証します。
- パケットが順不同で到着した場合は、正しい順序に並べ替えられます。
詳細
Transmission Control Protocol (TCP) は、インターネットで使われる中核的な通信プロトコルの1つです。2台のマシン間で信頼性の高い通信を提供するように設計されています。
データを送信する前に、TCPは three-way handshake と呼ばれるプロセスを通じて接続を確立します。クライアントはまず SYN メッセージをサーバーに送信します。サーバーは要求を確認し、準備ができていることを示すために SYN-ACK で応答します。その後、クライアントは接続を確認する ACK メッセージを送信します。このやり取りの後、両方のマシンがデータの送信を開始できます。
TCPはデータを packet と呼ばれる小さな単位に分割し、ネットワーク上で送信します。ネットワークではパケットが失われたり順序が入れ替わったりすることがあるため、TCPには不足しているデータを検出し、必要に応じてパケットを再送信する仕組みが含まれています。
TCPのもう1つの重要な機能は、パケットの順序制御です。パケットが送信時とは異なる順序で到着しても、TCPはアプリケーションにデータを渡す前に正しく再構成します。
これらの仕組みにより、TCPはWebリクエスト、データベース通信、ほとんどのAPIのやり取りなど、正確なデータ転送を必要とするアプリケーションに対して信頼性を提供します。
TCP と UDP
TCP は信頼性と順序を優先し、UDP は速度と最小限のオーバーヘッドを優先します。
- TCP は、マシン間で信頼性の高い順序付き通信を提供します。
- UDP は、接続を確立せずにメッセージをすばやく送信します。
- どちらを選ぶかは、信頼性と速度のどちらがより重要かによって決まります。
詳細
TCP と UDP は、マシン間の通信に使われる 2 つの主要なトランスポートプロトコルですが、解決する問題は異なります。
TCP (Transmission Control Protocol) は信頼性のために設計されています。2 台のマシン間で接続を確立し、パケットが正常に到着することを保証し、失われたデータを再送し、パケットが正しい順序で配信されることを保証します。これらの保証があるため、TCP は正確性が重要なアプリケーションで使用されます。
多くのバックエンドシステムは TCP に依存しています。HTTP のような Web プロトコルは TCP の上で動作し、データの整合性が重要であるため、データベース接続も通常 TCP を使用します。
UDP (User Datagram Protocol) は別のアプローチを取ります。接続を確立せず、配信や順序も保証しません。その代わり、できるだけ速く宛先へパケットを送信するだけです。
UDP は信頼性のためのオーバーヘッドを取り除くため、より高速で軽量です。そのため、リアルタイム動画配信、オンラインゲーム、多くの DNS クエリのように、たまにパケットが失われても許容できるアプリケーションに適しています。
TCP と UDP のトレードオフは、本質的には信頼性と速度のどちらを優先するかという点にあります。システムは、アプリケーションの要件に最も合うプロトコルを選択します。
HTTP — アプリケーションプロトコル
HTTP は、クライアントとサーバーが Web 上で通信するときに、リクエストとレスポンスをどのように構成するかを定義します。
- HTTP はリクエスト・レスポンスの通信モデルに従います。
- リクエストは、GET や POST などの HTTP メソッドを使ってアクションを指定します。
- レスポンスは、ステータスコード、ヘッダー、データをクライアントに返します。
詳細
HTTP (Hypertext Transfer Protocol) は、多くの Web システムで使われるアプリケーション層のプロトコルです。クライアントとサーバーの間でやり取りされるメッセージの構造を定義します。
通信はリクエスト・レスポンスモデルに従います。クライアントは、何をしたいかを示す HTTP リクエストを送信し、サーバーはそのリクエストを処理して HTTP レスポンスを返します。
リクエストにはいくつかの要素があります。HTTP メソッドは、データの取得を表す GET や、新しいデータの送信を表す POST など、意図するアクションを示します。リクエストには、認証トークン、コンテンツタイプ、キャッシュ指示などのメタデータを運ぶヘッダーも含まれます。
サーバーはリクエストを処理した後、レスポンスを返します。レスポンスには、処理結果を示すステータスコードが含まれます。たとえば、200 OK は成功を示し、404 や 500 のようなコードはエラーを示します。
HTTP は、ブラウザー、モバイルアプリ、バックエンドサービスがインターネット上で一貫して通信できるようにする標準化された言語を提供します。
分散システムにおけるレイテンシ
ネットワーク要求には時間がかかります。データがマシン間を移動し、複数のシステムがその要求を処理する必要があるためです。
- データはマシン間でネットワークを通って物理的に移動しなければなりません。
- サーバーは要求を処理し、レスポンスを生成するのに時間が必要です。
- データベースなどの追加の依存関係によって、応答時間が長くなることがあります。
詳細
レイテンシとは、要求がクライアントからサーバーへ移動し、レスポンスが戻ってくるまでにかかる時間を指します。分散システムでは、単純な操作であっても、遅延に寄与する複数のステップが含まれます。
まず、要求はネットワークを通って移動しなければなりません。データはルーターやスイッチを経由し、場合によっては複数のデータセンターを通って目的のサーバーに到達します。地理的な距離だけでも、信号が長距離を伝わるのに時間がかかるため、目に見える遅延が発生することがあります。
要求がサーバーに到達すると、バックエンドシステムがそれを処理する必要があります。これには、アプリケーションロジックの実行、バリデーションの実施、その他の内部処理の実行が含まれる場合があります。
多くの要求は、データベース、キャッシュ、外部APIなどの他のシステムにも依存しています。依存関係が1つ増えるごとに、それぞれの処理時間とネットワークレイテンシが追加されます。
ネットワークの混雑やサービスの過負荷などの他の要因によっても、レイテンシはさらに増加することがあります。分散システムは多くの相互接続されたコンポーネントに依存しているため、複数の場所で発生する小さな遅延が積み重なって、目立つ応答時間になることがあります。
タイムアウトとネットワーク障害
分散システムは、タイムアウトと障害処理の仕組みを使って、遅いネットワーク要求や失敗したネットワーク要求から自分自身を守る必要があります。
- タイムアウトは、システムが応答を無期限に待ち続けるのを防ぎます。
- リトライにより、失敗後にシステムが再度リクエストを試行できます。
- 制御されていない障害はサービス間で伝播し、連鎖的な障害を引き起こす可能性があります。
詳細
ネットワーク通信は本質的に信頼できません。リクエストが遅延したり、接続が切断されたり、サービスが応答しなくなったりすることがあります。そのため、バックエンドシステムは遅いネットワーク呼び出しや失敗したネットワーク呼び出しを安全に処理できるように設計する必要があります。
一般的な保護手段の1つがタイムアウトです。タイムアウトは、システムが応答を待つ最大時間を定義します。その時間内に応答が届かなければ、リクエストは中止され、システムは次へ進みます。
リトライもよく使われる戦略です。ネットワークの一時的な問題でリクエストが失敗した場合、システムは少し待ってから再度リクエストを試みることがあります。これにより、短時間のネットワーク障害などの一時的な失敗から回復しやすくなります。
ただし、リトライは慎重に制御する必要があります。多くのサービスが失敗したリクエストを繰り返しリトライすると、下流のシステムに負荷をかけすぎて、1つの遅いサービスが広範囲の障害を引き起こすような連鎖的障害につながる可能性があります。
このため、現代のバックエンドシステムでは、ネットワークの一部が予測不能に動作しても信頼性を維持できるように、タイムアウト、リトライ、障害処理戦略を慎重に設定します。
ロードバランシング
ロードバランシングは、受信トラフィックを複数のサーバーに分散し、システムがより高い需要に対応できるようにし、信頼性を維持できるようにします。
バランサー
- ロードバランサーは複数のバックエンドサーバーの前に配置されます。
- 受信リクエストは利用可能なサーバー全体に分散されます。
- これによりスケーラビリティが向上し、サーバー障害が発生してもシステムの可用性を維持しやすくなります。
詳細
アプリケーションが成長すると、1台のサーバーではすべての受信トラフィックを処理できなくなることがよくあります。より多くのユーザーをサポートし、パフォーマンスを維持するために、システムは同じ機能を提供する複数のバックエンドサーバーを稼働させます。
ロードバランサーは、受信リクエストの入口として機能します。クライアントが個々のサーバーに直接接続する代わりに、ロードバランサーにリクエストを送信します。ロードバランサーは、その後、どのバックエンドサーバーが各リクエストを処理するかを決定します。
この分散によってトラフィックがサーバー全体に広がり、1台のマシンに負荷が集中するのを防ぎます。ラウンドロビン分散、最小接続数ルーティング、レイテンシーベースルーティングなど、さまざまなアルゴリズムが使用されることがあります。
ロードバランシングはフォールトトレランスも向上させます。1台のサーバーが利用できなくなっても、ロードバランサーは他の正常なサーバーにトラフィックを振り分けることができるため、システムは動作を継続できます。
このアプローチにより、水平スケーリングが可能になります。水平スケーリングでは、1台のサーバーをアップグレードするのではなく、マシンを追加することでシステムの容量を増やします。水平スケーリングは、大規模で信頼性の高いバックエンドシステムを構築するための基本的な戦略です。
質問セクション
1 / 5
このレッスンはプレミアムコンテンツです
プレミアムにアップグレードしてぼかしを解除し、全文を読めるようにしましょう。