Skip to content

Instantly share code, notes, and snippets.

@hatajoe
Created October 19, 2018 15:32
Show Gist options
  • Save hatajoe/92ec3bd528c8ec6f5b70a45a4943b2bf to your computer and use it in GitHub Desktop.
Save hatajoe/92ec3bd528c8ec6f5b70a45a4943b2bf to your computer and use it in GitHub Desktop.
Introduction to server development

introduction-to-server-development

Introduction

サーバーアプリケーション開発にあたって必要な知識は幅広く存在します。 これを習得するための情報はWebや書籍に多くありますが、初学者にとって何から学ぶべきかは難しい問題です。 本セッションは、サーバーアプリケーション開発初心者に向けた入門を意識して作成しました。

ネットワークに関係する技術は、IaaS(Infrascructure as a Service)の登場をはじめコンテナ技術の一般化など、近年変革の時を迎えています。 これらの技術が、我々が提供するサービスを通じていかにユーザーの価値に繋がるのかを理解する必要があります。 そのためには、これから紹介するような基本的な知識の習得が必要になります。

プロフェッショナルな仕事を続けるためには、知識や経験の積み重ねが必ず必要になります。 是非、本セッションを受けたあとに自分で調べて、手を動かしてみてください。


本セッションは以下の構成で進めます。

  • ネットワークサーバーについて
  • ネットワークプロトコルについて
  • ネットワークアーキテクチャーについて

ネットワークサーバーについて

ネットワークサーバーとはなにかを説明します。 Linux OSやLinuxカーネル、CPU、メモリ、ディスクストレージなどがどのようなものか、また、IPアドレスやポートなどのネットワークインターフェスについても簡単に紹介します。 Linux OSではプロセスという単位でプログラムが動作します。 プロセスがネットワークサーバー上でどのように管理されているか、またその特徴について紹介します。 VMやコンテナについても簡単に紹介します。

ネットワークプロトコルについて

任意の端末とネットワークサーバー間でデータ通信を行う場合、データをどのように送るかの仕様が必要になります。 その仕様のことをプロトコルと呼びます。 ここでは、代表的なネットワークプロトコルであるICMP、TCP、UDPを紹介し、TCPをベースとして策定されているHTTPについても紹介します。 また、近年一般的に使われているWebSocketについても簡単に紹介します。

ネットワークアーキテクチャーについて

通常、ネットワークサーバーのシステムは複数のサーバーから構成されます。 ネットワークサーバーと言っても役割は様々です。これらをどのように構成するか、LAMPと呼ばれる一般的な例を紹介します。 また、大規模なサービスが抱える問題と、その解決方法の1つであるマイクロサービスについてもお話します。

Table of Contents

  • ネットワークサーバーについて
    • コンピューター
      • CPU
      • メモリ
      • ディスクストレージ
      • ネットワークインターフェース
        • IPアドレス
        • ポート
    • Linux OSとLinuxカーネル
      • システムコール
      • プロセス
      • スレッド
      • OSはプログラムをどのように扱うか
      • スタックメモリとヒープメモリ
      • VMについて
      • コンテナについて
  • ネットワークプロトコルについて
    • 標準入力、標準出力、標準エラー出力
    • ネットワークソケット
    • OSI参照モデル
    • 代表的なネットワークプロトコル
      • ICMP
      • TCP
      • UDP
      • HTTP
    • WebSocketとは
  • ネットワークアーキテクチャーについて
    • LAMP構成
      • ロードバランサー
      • Webサーバー
      • DBサーバー
      • キャッシュサーバー
    • 大規模サービスにおける課題とマイクロサービス

ネットワークサーバーについて

コンピューター

ネットワークサーバーとは、任意の端末に対してデータを送受信出来るシステムのことを指します。 ネットワークサーバーはコンピューターによって実現されており、我々が普段利用しているパーソナルコンピューターと内部的にほとんど違いはありません。

コンピューターは、マザーボードを始めとする様々なハードウェアから構成されます。 ここでは、CPUとメモリ、ディスクストレージについて簡単に説明します。

CPU

CPU は Central Processing Unit の略称です。 コンピューター全体の制御、演算、メモリなどの記憶装置や周辺機器に対するインターフェースなどから構成されます。 CPU にはクロック周波数と呼ばれる単位があります。1クロックで処理出来る内容はCPUの設計によって異なり、1クロックで複数の機械語命令(アセンブリ実行)が可能なものもあるようです。 クロック周波数はGHzの単位で表し、例えば1GHzのCPUは1秒間に10億クロックという意味になります。

[1秒間に10億クロック] 昨今のコンピューターは数GHzのCPUを備えていますが、多くの操作は1クロックでは完結することが不可能なため、現在のところかなり高性能なデスクトップコンピューターであっても毎秒10億回以上の操作は出来ないとされています。 Googleには、検索対象のWebページが85億ほどあるそうです。 もし仮に、検索処理を1操作とした場合最速でも8.5秒かかることになります。これでは使い物になりません。 この例が示唆するのは、コンピューターが高性能になったとしても、プログラミングにおけるデータ構造とアルゴリズムはユーザーの価値に大きく影響するということです。

メモリ

メモリはコンピューターの記憶装置です。 メモリにはCPUがロードしたプログラムや、演算の途中結果その他が保存されます。また、プログラムからも利用することが可能です。 同じ記憶装置であるディスクストレージに比べて、データは電源を落とすと消えてしまいますが、読み出し書き込みの速度が高速であるという特徴があります。 ランダムアクセスの場合、HDDとメモリでは10,000倍、SSDとメモリでも1,000倍程度の差があると言われています。

ディスクストレージ

ディスクストレージはコンピューターの記憶装置です。 ファイルという単位でデータを保存し、電源を落としてもデータは保存されたままという特徴があります。 ディスクストレージにはいくつか種類がありますが、最近のパーソナルコンピューターであればSSDが一般的です。 ネットワークサーバーにおいては、コストが安いためHDDを使用することもあります。

ネットワークインターフェース

ネットワークインターフェースとは、コンピューターを構成するハードウェアの1つで、NICと略されます。 1つのコンピューターに1つ以上組み込まれることもあります。 コンピューターはNICを通じてネットワークから届いたデータを受け取ります。自宅のポストをイメージするとわかりやすいかもしれません。 NICにはIPアドレスと呼ばれる住所のようなものが設定されます。また、IPアドレスとは別に1つのアドレスで複数のプロトコルによる通信を実現するためにポートという概念があります。

IPアドレス

NICごとに1つ設定される住所をIPアドレスと呼びます。 現在、IPアドレスにはIPv4とIPv6という2つのバージョンが存在します。IPv6については詳しくないので割愛します。 IPv4のIPアドレスは、0〜255の数字4つの組み合わせで構成されます。(例: 192.168.11.240)

IPアドレスにはパブリックIPとプライベートIPの2種類が存在します。 パブリックIPは、IaaSなどからお金を支払うことで利用可能なグローバルユニークなIPアドレスです。 取得したパブリックIPは、お名前.com などで販売されているドメインに紐づけて利用するのが一般的です。 プライベートIPは、プライベートなネットワーク空間内で利用するIPアドレスです。 先程も言った通り、IPアドレスは0〜255の数字4つの組み合わせであることから、発行出来る数に制限があります。 しかし、昨今は我々が所有するスマートフォンを含めて大量の端末がネットワークに接続出来る必要があります。 そのため、ネットワーク空間をツリー状に構成することでプライベートなネットワーク空間を作り出し、その内部でのみ利用可能なIPアドレスを定義することが出来ます。 社内ネットワークなどが最たる例です。

ポート

NICには1のIPアドレスしか設定が出来ません。 このままでは、1つのNICで1つの通信形式でしか通信が出来ないことになります。 そのために、NICにはポートという概念があります。ポートは1〜65535まであります。 ポートには well known port と呼ばれる予約番号があり、1〜1024までは使うことが出来ません。 また、一般的に広く使われているソフトウェアが利用するポートを知っておくことも大事です。 例えば、HTTPは80、HTTPSは443、MySQLは3306、Memcachedは11211などです。 自作のサーバーがこれらのポート番号と重複しないように実装しておくとトラブルが少ないでしょう。

Linux OSとLinuxカーネル

ネットワークサーバーとして広く使われているOSにLinuxがあります。 OSにはカーネルと呼ばれるOSとハードウェアドライバーのインターフェース層があります。 OSからカーネルの機能を呼び出すことをシステムコールと呼びます。 OSはプログラムをプロセスという単位で管理しています。 これらについて簡単に説明します。

システムコール

OSからカーネルの機能を呼び出すことをシステムコールと呼びます。 システムコールには300以上の種類があります。 例えばファイル関連ではopen、read、writeなどがあります。他にも、プロセスを生成するforkやexecなどがあります。 通常、システムコールはハードウェア関係の操作が多いため遅いとされています。

プロセス

プロセスとは、簡単に言うと起動中のプログラムのことです。 1つのプロセスは複数の子プロセスを生成する場合があります。 これは、内部的にはプログラム内でforkシステムコールを呼び出すことと同義です。 OSは、スケジューラーと呼ばれる制御システムを利用して複数のプロセスを並列に実行・管理しています。

[並列と並行] 並列(concurrent)と並行(parallel)には違いがあります。 並列とは1人が複数の仕事をこなす状態で、平行とは2人が複数の仕事をこなす状態です。 OSは都度処理を行うプロセスを切り替えて擬似的に同時並行を実現しています。 このプロセスを切り替える操作のことをコンテキストスイッチと呼びます。

スレッド

スレッドとはCPU利用の単位です。プロセスには最低1つのスレッドがあります。 スレッドにはユーザースレッドとカーネルスレッドの2つの種類があります。 基本的には1つのCPUがある瞬間に実行しているのは割り込み処理なども含めて1プロセス1スレッドです。

ユーザースレッドは、その切替をプロセス内でライブラリによるスケジューラーが行います。 複数のユーザースレッドは互いにメモリ空間を共有しています。そのため、メモリ効率が良く切り替えも速いという特徴があります。 ただし、あくまでプロセス内でのスレッディング処理となるのでマルチプロセッサによる並行処理の恩恵が受けられません。 また、1つのスレッドがシステムコール実行中は他の全スレッドも待ち状態になります。 なので、ユーザースレッドはプログラミング手法の1つとして有効なだけでパフォーマンスに寄与するものではありません。

カーネルスレッドは、その切替をカーネルが行います。そのため、マルチプロセッサによる並行処理が可能なスレッドです。 しかし、カーネルスレッドの切り替えはプロセスのそれと違いがあまりないため、切り替えコストはプロセス並みとなるようです。 カーネルスレッドもユーザースレッド同様に互いにプロセス内のメモリを共有していてますが、マルチプロセッサによる並行処理を意識する必要があるため、メモリアクセスを適切に排他制御する必要があります。

スレッドにはコルーチンと呼ばれる軽量スレッドなど他にもいくつか種類がありますが割愛します。

OSはプログラムをどのように扱うか

OSは、我々が書いたプログラムをそのまま実行することが出来ません。 我々が書いたプログラムは、OSが実行出来る形式へ変換する必要があります。 例えばC言語は、コンパイラとリンカと呼ばれるツールを使用してOSが実行出来る形式に変換出来る言語です。 プログラムをOSが直接実行出来る形式に変換出来る言語を「ネイティブで動作する言語」と言ったりします。 一方、JavaはコンパイルこそするもののOSが直接実行出来る形式に変換されるわけではありません。今回はネイティブで動作するプログラムに関しての話になります。

OSはプログラムを起動するとプロセスを作成します。 プロセスには規定のサイズのメモリが割り当てられます。 起動されたプロセスはOSのスケジューラーに管理され、プログラムが終了するまで常駐します。

スタックメモリとヒープメモリ

プロセスが起動時に割り当てれられるメモリをスタックメモリと呼びます。 そのサイズは環境によって様々ですが、4KB〜8KBが多いようです。これは ulimit -s というコマンドで確認が出来ます。 スタックメモリはそのプロセス専用のメモリ空間であり、既に確保済みの状態なので読み書きが速いという特徴があります。 また、プログラム終了時に自動的にOSによって解放されるためリークの心配もありません。 スタックメモリはプロセス専用と書きましたが、親プロセスのスタックメモリは子プロセスに共有されます。 反対に、子プロセスのスタックメモリは親プロセスに共有されません。 スタックメモリは、関数コール(コールスタック)やローカル変数などの保存に利用されます。 スタックメモリが枯渇することをスタックオーバーフローと呼びます。スタックオーバーフローが発生すると、プロセスはSEGVシグナルを受け取り強制的に終了します。 再帰関数を無限に呼び出すなどすると簡単に再現させることが出来ます。

ヒープメモリはプログラムが動的に確保したメモリ領域のことです。 ヒープメモリは、元々プロセスに割り当てられていないメモリ領域から確保するのでスタックメモリに比べて非常に遅いという特徴があります。 理由は、OSは複数のプロセスを管理しているので、プロセスが共有メモリを確保するためには高度な排他制御が必要になるからです。 また、プログラムが確保したメモリはプロセスが終了しても解放されません。プログラムの実装者が明示的に解放処理を実装しないとメモリリークが発生します。

VMについて

VMは Virtual Machine の略です。 VMとは、OSのプロセスとして仮想的に別のOSを動かす技術です。OSエミュレーターといえばイメージしやすいかもしれません。 VMを起動するOSをホストOS、VMとして起動したOSをゲストOSと呼びます。 WindowsやMacでLinuxを動作させることが可能で、本番環境に近い動作環境をローカルに構築出来るといったメリットや、VMを停止することなくCPUやメモリの増減を行うことが可能なため、ハイスペックなコンピューター上のOSに複数のVMを起動してシステムを構築することが可能になったりします。 ただし、VMはCPUやメモリなどのハードウェアをエミュレートするためオーバーヘッドは大きくなります。起動も遅いです。

コンテナについて

コンテナはLinuxプロセスをOS上で隔離し、OSの機能を共有しつつ独立した空間を仮想的に実現する技術です。 様々なコンテナ実装がありますが、最も有名なのは Docker でしょう。 ホストOSがLinuxでコンテナもLinuxである場合はネイティブに動作するので起動も高速でマシンリソースを効率良く使う事ができます。 ホストOSとコンテナが違う場合はハイパーバイザーという仮想化技術によってその差分を吸収しているようです。 コンテナは起動が速いため、負荷に応じて動的にスケールアップ、スケールアウトさせるような用途や、プログラムの実行環境そのものをパッケージング出来る上に軽量、どの環境についても同じように動作しポータブルであるという点が特徴です。

ネットワークプロトコルについて

ネットワークプロトコルとは通信の仕様です。 メッセージがどのようなデータ型なのか、また、どのようなステップで端末同士を接続するのかなど、通信には仕様がないとやりとりが出来ません。 まず、Linuxのデータの入出力について紹介します。 次に、ネットワークインターフェースに対するアプリケーション側のインターフェースであるソケットについて紹介します。 最後に、代表的なネットワークプロトコルを紹介します。

標準入力、標準出力、標準エラー出力

Linux OS上で動作するプログラムはプロセスという単位で管理されます。 プロセスには、外部のプロセスやインターフェースとデータをやりとりするために、標準入力、標準出力、標準エラー出力という3つの機構があります。 プロセスはメモリ空間が独立しているため、他のプロセスに割り当てられているメモリにアクセスすることは出来ません。そのため、これら3つの機構を使ってデータをやりとりします。 プロセスにデータを渡すには、対象のプロセスの標準入力に対してデータを書き込みます。 プロセスからデータを出力するには、標準出力へ書き込みます。プロセス内で発生したエラーを出力するためには、標準エラー出力へと書き込みます。 以下の例を見ながら体感してみましょう。

まずターミナルを開きます。ターミナルもOSから見たら1つのプロセスです。 ターミナルを起動すると、コマンド入力待ちの状態になっているはずです。これは、ターミナルが標準入力にデータが入力され終わるまで待つとプログラミングされているからです。 それでは、以下のコマンドをタイプしreturnキーを入力してみましょう。

% ps aux

psコマンドは現在実行中のプロセス一覧を標準出力に書き込むというコマンドです。 実行すると、画面に実行中のプロセス一覧が表示されたはずです。これは、psコマンドによるプロセスが起動し実行中のプロセス一覧を取得して標準出力に書き込んでいるということです。 ターミナルは、標準入力で受け取ったコマンド(ps)を実行し、その標準出力を画面に出力するというアプリケーションです。つまりこれがプロセス間通信ということになります。 もう少し複雑な例でプロセス間通信を体感してみましょう。

% ps aux | grep nginx

| はパイプと呼ばれ、左辺のコマンドの標準出力を右辺のコマンドの標準入力へ繋ぐというコマンドです。 上記を実行すると、プロセス一覧から nginx という文字列が含まれる行のみがターミナルに表示されます。 grepコマンドは、標準入力に書き込まれた文字列から引数に渡された文字列とマッチする行を標準出力に書き込むというコマンドです。

また、LinuxOSにはリダイレクトという便利なコマンドがあります。 以下のコマンドを実行してみてください。

% ps aux | grep nginx > file

> はリダイレクトと呼ばれ、左辺の標準出力を右辺のファイルに書き込むというコマンドです。 psコマンドの標準出力からnginxという文字列が含まれる行がfileファイルに保存されているはずです。

実は、これはネットワークを介した場合においても同じ仕組みで動作します。 サーバーアプリケーションは、ソケットインターフェースを介してネットワーク上の別の端末と通信を行います。

ネットワークソケット

LinuxOSにおけるネットワークソケットの実体はただのファイルです。 ネットワークインターフェースは、データを受信するとカーネルの機能を呼び出します。カーネルはデータをソケットファイルに書き込みイベントを発火します。 イベントはlistenシステムコールによってアプリケーション側で購読することが可能です。 イベントが発火したら、recvシステムコールによってソケットファイルからデータを読み出すことが出来ます。 そして、sendシステムコールによってソケットファイルに書き込まれsendイベントを購読しているカーネルによってネットワークインターフェースを介してデータが送られます。

OSI参照モデル

ネットワーク通信の仕組みを説明しました。 通信機能は7つのレイヤーにわかれており、それをOSI参照モデルと呼びます。 OSI参照モデルには以下のレイヤーがあります。

  • 7層: アプリケーション層
  • 6層: プレゼンテーション層
  • 5層: セッション層
  • 4層: トランスポート層
  • 3層: ネットワーク層
  • 2層: データリンク層
  • 1層: 物理層

ネットワークソケットは4層のトランスポート層の話になります。 これから紹介する代表的なネットワークプロトコルは3層、4層、5〜7層の話です。

代表的なネットワークプロトコル

ネットワークプロトコルには様々な種類が存在します。 本セッションでは、ICMP、TCP、UDP、HTTPの4つを紹介します。

ICMP

ICMPとは、OSI参照モデル3層で解決されるプロトコルです。 主にネットワークの疎通確認のために使用されます。 pingコマンドを実行することで、指定のサーバーに対してICMPプロトコルによる通信を行うことが出来ます。

TCP

TCPとは、OSI参照モデル4層で解決されるプロトコルです。 トランスポート層は、通信するデータの形式は問わず端末間の接続に関する仕様が解決されるレイヤーです。 TCPは、接続が確立した場合に接続が維持されている間データの到達保証を実現するステートフルなプロトコルです。 ステートフルというのは、接続に状態があることを指します。TCPは、3WAYハンドシェイクと呼ばれる規定のプロセスを踏んで端末間の接続を確立します。 接続確立後は、端末間で自由にデータを送受信することが出来、その到達を保証します。

UDP

UDPとは、OSI参照モデル4層で解決されるプロトコルです。 UDPは、TCPとは対象的に到達保証の無いステートレスな通信プロトコルです。 ステートレスなので、接続確認のステップは無くデータを一方的に送信することが出来ます。 ただし、接続を確立しないので、送信先にちゃんとデータが届いたかどうかを送信元が知ることが出来ません。 一見、使い物にならないような気がしますが、TCPに比べて通信速度が速いというメリットがあり、一部のデータ欠損してもサービス提供には支障がないような動画や音声などのストリーミング再生に利用されることがあります。

HTTP

HTTPとは、OSI参照モデル5〜7層でかいけつされるプロトコルです。 一般的なWebサービスのサーバーを開発する場合、ICMPやTCP、UDPを意識することがありませんが、HTTPは意識する必要があります。 HTTPは、TCPの上に実装されているプロトコルで、通信するデータ型が定義されています。 また、HTTPのクライアントアプリケーションとしてWebブラウザが広く知られています。

HTTPはステートレスな通信仕様となっており、リクエストとレスポンスが必ず1:1である必要があります。 通信の順番として、サーバーからクライアントにデータを送り始めることは出来ません。通信は必ずクライアントからになります。

WebSocketとは

WebSocketとはHTTPを使って接続を確立し、以降の通信をTCPで行う通信プロトコルです。 WebSocketを使用すれば、サーバーとクライアント間で任意の順番でデータを送受信することが可能になります。 元々、HTML5の仕様として策定が始められ、現在では独立したプロトコル仕様になりました。 サーバーからクライアントに対してもデータをPushすることが可能なため、ブラウザを使ってリアルタイム通信を実現することが出来ます。

ネットワークアーキテクチャーについて

これまでに、コンピューターやネットワークの基本的な知識を紹介しました。 通常、ネットワークサーバーのシステムは複数のコンピューターが協調して動作します。 ここでは、よくあるネットワークアーキテクチャーについて紹介します。

LAMP構成

LAMP構成とは、最も一般的なWebサービスのネットワークアーキテクチャーです。 LAMPの4文字はそれぞれOSやミドルウェアの頭文字を表しています。

  • L: Linux
  • A: Apache
  • M: MySQL
  • P: PHP

一般的にLAMP構成と言うと、以下のようなサーバー構成のことを指します。

  • ロードバランサー
  • Webサーバー
  • DBサーバー
  • キャッシュサーバー

それぞれどのような役割があるのかを説明します。

ロードバランサー

ロードバランサーとは、Webサービスのネットワークシステムの入り口を担当するサーバーです。 Webサービスは利用者の数に応じてWebサーバーの数が増減します。しかし、1つのパブリックIPを複数のサーバーで共有することは出来ません。 そのため、ロードバランサーに1つのパブリックIPを設定し、ロードバランサーを中心としたプライベートネットワークを構成します。 Webサーバーは、プライベートネットワーク内でプライベートIPを割り振り、ロードバランサーに登録しておきます。 こうすることで、ロードバランサーが受け取ったリクエストをWebサーバーへと転送します。 ロードバランサーには、転送を行うWebサーバを選別するためのいくつかのアルゴリズムがあります。 リクエストを順番に配下のWebサーバーに転送するラウンドロビンと呼ばれるアルゴリズムが一般的です。 他にも、Webサーバーの負荷を監視することで振り分けるアルゴリズムなどがあります。

Webサーバー

アプリケーションサーバーとも呼ばれます。 開発したサーバーアプリケーションが動作するサーバーです。 一般的には、URLに応じたロジックが起動し、結果を返すというアプリケーションになるでしょう。 Webサーバーは、利用者の数に応じて台数を増やせば負荷分散可能な実装にすることが重要です。 つまり、1つのWebサーバー内にしか必要なデータが無い状態を避けなければいけません。それを解決するためにDBサーバーがあります。

DBサーバー

DBはDataBaseの略です。 DBサーバーは、アプリケーションに必要なデータを保存するためのサーバーです。 Webサーバーはリクエストを受け取り、必要なデータをDBサーバーから検索し、処理を実行し、必要であればDBサーバーへ保存します。 DBにはRDBMSやNoSQLなど用途に応じて様々な種類があります。 RDBMSの実装で有名なものにMySQLやPostgressSQLがあります。また、NoSQLの実装にMongoDBやCassandraなどがあります。

通常、データベースはコンピューターの電源が落ちてもデータを保持する必要があるため、データをストレージに保存します。 ストレージは読み書きの速度が遅いため、多くのデータベースアプリケーションがメモリ上でデータを扱えるよう工夫を凝らしています。 それでもストレージアクセスが避けられない場合があります。それを解決するためにキャッシュサーバーがあります。

キャッシュサーバー

キャッシュサーバーとは、DBサーバーから読み取ったデータをメモリ上に一時的に保存しておくサーバーです。 メモリであるため読み書きが高速であるという利点があります。 データベースはその性質上サーバーを分散することが難しいため、なるべくアクセスしないよう設計するためにこのようなテクニックが用いられます。 代表的なキャッシュサーバーにMemcachedやRedisがあります。

大規模サービスにおける課題とマイクロサービス

多くのサービスがLAMPをベースに構成されたネットワークで稼働していましたが、近年とくに大規模なサービスにおいては問題が起こるようになりました。 例えば、

  • 管理するサーバーの台数が4桁以上になる
  • コードが肥大化しメンテナンスにコストがかかる
  • エンジニアの数が増え統制が取れなくなる

これらの問題を解決するためにマイクロサービスアーキテクチャーというアプローチに注目が集まっています。 マイクロサービスアーキテクチャーの対義語としてモノリシックアーキテクチャーがあります。 モノリシックアーキテクチャーは、サービスの全てが同じコードベースで表現されている状態です。 少人数開発やそれほど大きくないサービス規模である場合はシンプルで問題にはならないアーキテクチャーですが、大人数開発や規模の大きいサービスになるとコードの依存関係や変更による依存関係、テストのスピード低下など支障をきたす場合があります。 マイクロサービスアーキテクチャーは、アプリケーションを小さな独立したアプリケーションの集合によって構成するアーキテクチャーです。 1つ1つの小さなアプリケーションは完全に独立して動作するため、コードベースを小さく保つことができ、マイクロサービスごとに開発チームを作るなど大人数による開発についても問題も解決します。

しかし、マイクロサービスアーキテクチャーはその管理が難しく、サービスの監視や負荷分散、アプリケーションのデプロイなど考えなければいけないことは多岐に渡ります。 そこで登場したのが、Googleが開発しているOSSであるkubernetesです。 kubernetesは、コンテナの集合を管理するためのミドルウェアです。マイクロサービスをコンテナとしてパッケージングし、kubernetesを使って自動でスケーリングやリカバリングを行います。 Googleは、少し前にGCP(Google Cloud Platform)にてGKE(Google Kubernetes Engine)をリリースしました。 GKEを利用することで、利用者は簡単にkubernetesの恩恵を受けることができ、マイクロサービス開発者にとっては唯一の選択肢とまでなる勢いです。


おわりに

今回紹介した知識は、ネットワーク開発におけるほんの一部です。 是非自らの手を動かし、新旧別け隔てなく幅広く知識を習得して欲しいと思います。 今回、これをまとめるにあたり僕自身も再度勉強しなおしましたが、まだまだ新しい発見がたくさんあります。 なるべく気をつけて書いたつもりですが、間違っている部分もあるかもしれません。是非指摘して頂ければと思います。

今回は、アプリケーションアーキテクチャーについては触れていません。 アプリケーションアーキテクチャーには、MVCやクリーンアーキテクチャーなど多くの考え方があります。 こちらも機会があればまた紹介したいと思います。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment