初めてApache触ったからNginxも勉強してみた

この記事はうるる[Advent Calendar 2022の22日目](https://qiita.com/advent-calendar/2022/uluru)の記事です。

## はじめに
今回は社内のサーバーを調査する中で初めてがっつりApacheを触ったので、諸々サーバー知識の備忘録とNginxとの比較をアウトプットしようと思います。
タイトルにそぐわず比較以外の内容が多いのはご容赦ください。

職種としては学生時代にフロントエンド、社会人になりバックエンドをやってきたので、サーバーサイドの知識は皆無の状態です。なので、そもそもApacheとは？とか、httpdは？とか初歩的な知識が多いかと思いますが、温かい目で見守っていただければと思います。

※間違っている内容があればご指摘いただけると幸いです。

## 今回の調査で調べた知識
### 調べた内容一覧
- [anacron](https://qiita.com/drafts/5fcd79f8bb4f4f95f0de#anacron)
- [logrotate](https://qiita.com/drafts/5fcd79f8bb4f4f95f0de#logrotate)
- [ApacheのMPM（Multi Processing Module）](https://qiita.com/drafts/5fcd79f8bb4f4f95f0de#apache%E3%81%AEmpmmulti-processing-module)
- [RSS Memory](https://qiita.com/drafts/5fcd79f8bb4f4f95f0de#rss-memory)
- [file descriptor](https://qiita.com/drafts/5fcd79f8bb4f4f95f0de#file-descriptor)
- [init.d](https://qiita.com/drafts/5fcd79f8bb4f4f95f0de#initd)

### anacron
anacronは基本的はcronと同じく指定した時間に定期実行してくれるプログラムです。

<b>anacronでできて、cronでできないこと</b>
サーバーが落ちた際に、復旧後もう一度落ちていた期間のプログラムを実行してくれる。

<b>anacronでできなくて、cronでできること</b>
時分単位での指定。anacronでは1日単位の周期で指定ができるが、時間単位では指定できない。

まとめると、anacronはアクターフォローがしっかりしているが、細かいことは苦手。といった感じです。


### logrotate（log rotation）
log rotationまたはlog rotateはログファイルが際限なく増えることを防ぐ機能です。Linuxではloglotateという名称のツールが有名です。ログファイルをどういった周期で作り直し、いくつまで残しておくのか、処理の実行前後に何か実行するかなどをしていてできます。

社内の旧システムでは毎日ログファイルを別にするために設定がされていました。また、通常のやり方ではなさそうですが、logrotateの中で処理の終わりに、postrotateを用いてApacheの再起動をするプログラムを書かれているなどもされていました。なので、繰り返し処理の調査の際は見てみるのも良さそうです。
書き方については[こちら](https://milestone-of-se.nesuke.com/sv-basic/linux-basic/logrotate/)の記事が参考になります。


### ApacheのMPM（Multi Processing Module）
Apacheにはプロセスを複数生成し同時リクエストを可能にするモジュールがあります。これをMulti Processing Moduleと言います。MPMには三つの方式があり、prefork / worker / event drivenの三種類があります。

- prefork
prefork方式では1プロセスにつき1スレッドを持ちます。スレッドとはCPUのコアへ対して命令を渡す単位です。
1つのhttpdは1つのCPUコアを使って処理を行います。このようなプロセスを<b>シングルスレッドプロセス</b>と呼びます。
![prefork.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312923/939ff625-0465-8828-327a-a7ab4c62f831.png)



- worker
worker方式では1つのプロセスが複数スレッド持ちます。1つのhttpdプロセスが複数リクエストを処理できるようになるので、プロセスが少なてすみます。このようなプロセスを<b>マルチスレッドプロセス</b>と呼びます。
![worker.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312923/f8b1896a-4c69-9ed8-31e2-d82a351926c8.png)



- event driven
event driven（イベント駆動）方式は基本的にworker方式と同様です。
違いとしては、プロセスが不足した際にそのイベントをトリガーとしてプロセスを増やすことができます。



### RSS Memory
Resident set sizeの略称です。プロセスが実際に使用しているRAMの総メモリ量です。つまり、Datadogなどでhttpdに表示されるRSSはhttpdのプロセスの物理メモリ使用量ということになります。
複数仮想メモリを使用している場合には共通のメモリを利用していた場合は両方へ加算されるため注意が必要です。
その他VSS,PSS,USSなどとの比較については今回は触れないですが、[こちら](https://www.lineo.co.jp/blog/linux/sol01-processmemory.html)の記事がとても参考になります。



### file descriptor
プロセスは全てfile descriptor（以降fd）というファイル書き込み用の通信チャネルを持ちます。fdは番号で書き込みファイルを識別しいます。その中にはfd:0,fd1,fd2の三つがプロセス生成時に必ず生成させます。

fd:0は標準入力、fd1は標準出力、fd2は標準エラー出力です。fd自体は概念なので実体は捉えられませんが、下記コマンドでプロセスの出力先を確認することができます。
```
$ ls -l /proc/[プロセスのpid]/fd/
```
ちなみに、fdの入力や出力などはファイルに限らず、キーボードやモニターなどの入出力も含んでいます。

### init.d
システムはシステム起動時やランレベル実行時に、initプロセスがrcスクリプトを実行することで起動すべきサービスが開始され、停止するサービスを停止する仕組みになっています。サーバーで常時起動しているデーモンは /etc/init.dディレクトリ配下にファイルが存在しており、そこから起動スクプリとが呼ばれます。

rcN.dファイルがinit.dのファイルのシンボリックリンクとなっており、それぞれの役割に応じてrcN.dへ配置されます。また、役割によってファイル名の命名規則も存在するので注意が必要です。
rcN.dのNは0~6とSが存在しそれぞれ役割が違います。それぞれの役割については[こちら](https://docs.oracle.com/cd/E19683-01/817-3491/6mj34vkro/index.html)の記事が参考になります。


## ApacheとNginxの比較
DBサーバーにMySQLやPostgreSQLなどがあるようにWebサーバーにもApache HTTP ServerやIIS,Nginxなどがあります。
社内では旧システムでApache、新システムでNginxを利用しているのでその比較を行なっていこうと思います。

### Apache
- OSS
- マルチプロセス方式
    - リクエストが多いとメモリの枯渇につながる可能性あり
    - 上記を<b>C10K問題</b>という
- モジュールによる拡張が可能
    - 一応イベント駆動方式を使うことも可能
- CMSを利用する際に比較的簡単な設定で利用可能
- 長年利用されバージョンアップも繰り返しているので、信頼性が高い

### Nginx
- OSS
- C10K問題など同時接続時の処理速度や高負荷に耐えうるように設計されている
- <b>ノンブロッキングI/Oと非同期のイベント駆動</b>アーキテクチャを採用
- リバースプロキシやロードバランサの機能が標準である
- CPUを利用する処理が苦手
    - PHPやPerl、CGIなどのCPUを使用するコンテンツの処理は苦手
    - 具体的には動画コンテンツを扱うシステムには向かない
- APサーバーの役割は担えない
- 機能の拡張がしにくい

### 比較
Nginxではリバースプロキシやロードバランサが使えるなど違いはいくつかありますが、一番の違いはプロセスの処理方式です。

Apacheは「マルチプロセス方式」、Nginxは「イベント駆動」です。Apacheでもモジュールを利用することでイベント駆動は可能ですが、Nginxには及ばないそうです。

### 利用ケース
<b>Apache</b>
- 同時接続数が少なく、リクエストが多いシステム
- 短期間での構築をしなければならないシステム（構築の容易さ）

<b>Nginx</b>
- 同時接続が多く、スケーラビリティが必要なシステム
- 静的コンテンツへの多量の同時接続が想定されるシステム

それぞれのプロセス処理の具体的な動きについては省略しますが、[こちら](https://qiita.com/hiroaki-u/items/f2455d62f8a4017663cb)の記事が参考になります。


## 最後に
若干釣りなタイトルかつ初歩的な内容にはなっていますが、最近学んだことのアウトプットに記事を書かせていただきました。最後まで読んでいただきありがとうございました！

学生時代ぶりのアウトプット記事となり拙い記事でしたが、機会があればまたアウトプット記事を書いていこうと思います。


明日は@yafan_chuangさんの記事です！
お楽しみに！