Nginxメモ
目次
Nginx概要
アーキテクチャの種類
-
サーバにはfork型(プロセス駆動型)とselect型(イベント駆動型)がある
-
fork型はクライアントとの一対一を想定したサーバを増殖(fork)させることで多数のクライアントに対応する
-
select型は元からクライアントとの一対多を想定したサーバを用意し、多数のクライアントを順にさばいていく
-
前者のfork型では分身(リソース)の制限からあまりにも多数のクライアントには対応できないが、nginxはselect型であるためそれを解決する
-
select型とはいえnginxも全く分身を作らないわけでは無く、ワーカーという分身をコア数程度は作る
思想の違い
-
nginxの設定ファイルはURLに対応するような記述をする
-
URLは
Request URL: https://www.kyoto-u.ac.jp/ja
のように
https
(スキーム名)、www.kyoto-u.ac.jp
(ホスト・ドメイン)、/ja
(サブディレクトリ)等からなる、上位→下位の入れ子構造をしている -
URLに対応するよう作られたnginxの設定も、同様にHTTP,server,locationを入れ子にしている
基本構文
ディレクティブ・コンテキスト
-
設定ファイルはnginx.conf
-
設定ファイルの中身はディレクティブと呼ばれる設定項目の集合。書式は
ディレクティブ名 値;
-
適用範囲を明確にするため、複数のディレクティブをブロック
{}
で囲むことがある(当然ブロックが入れ子状になることもある)
上位のブロックで適用された設定は下位のブロックにも受け継がれる(継承)。こうしたブロックをコンテキストと呼ぶ -
ディレクティブの末尾はセミコロン
;
コンテキストの例
server { #serverコンテキスト
listen 80; #listenディレクティブ
server_name test.matsue-ct.ac.jp; #server_nameディレクティブ
}
-
コンテキストと呼ばれるものには何種類かあるが
良く目にするのは
-
グローバルコンテキスト
-
eventコンテキスト
-
Http
- Server
- Location
- Nested Location (入れ子になったLocation)
- If in location (Location内のIf)
- limit_except
- Location
- Server
-
If
-
グローバルコンテキストだけは
{}
で囲まない特別なコンテキストで、userディレクティブ、worker_prosessディレクティブ、error_logディレクティブ等を内包する。そして設定ファイルの最上部に書く -
eventコンテキストは設定ファイルに必ず必要で、1つの設定ファイルに1つのeventコンテキストと決まっている(中身が空でも置く)
変数・文字列・正規表現
-
nginxには組み込み変数として様々な変数が用意されている。
$変数名
とすることで任意の変数にアクセスできる -
nginxで文字列を表す際、そのまま書いても、ダブルクオテーション・シングルクオテーションで囲っても認識される。
後者はセミコロンや空白などを文字列として表したいときに有用 -
正規表現(PCRE)についてはこっちで
基本的な設定
ケーススタディ的に見ていく
基本
worker_processes 1;
events {}
http {
include mime.types;
access_log /var/log/nginx_access.log;
error_log /var/log/nginx_error.log info;
server {
listen 80;
server_name net-0.matsue-ct.ac.jp;
index index.html index.htm;
location / {
root /usr/local/www/nginx;
}
}
}
-
error_log
- エラーログの出力先を指定
-
access_log
- アクセスログの出力先を指定
http, server, location, If in location, limit_except などの コンテキストで指定できる.
コンテキスト毎に異なるファイルに出力可能
- アクセスログの出力先を指定
-
include
- 指定したファイルを該当箇所に挿入する。
ただしパスはconfファイルからの相対パス。
可読性を上げたり、設定の再利用を容易にする
- 指定したファイルを該当箇所に挿入する。
-
listen
- 受信するアドレスとポート番号の指定
-
server_name
-
server_name サーバ名 [サーバ名2] [サーバ名3]...
HTTPリクエストヘッダ内中のHostパラメータにある名前と、ここに列挙したいずれかの 名前にヒットした場合、
このディレクティブが置かれた server コンテキストが 適用される。 -
仮想ホストを建てる際に必須のディレクトリ
-
-
index
-
インデックス――――ファイル名を指定せずにディレクトリだけ指定されてアクセスされた時に返す用のファイルを指定する
-
server_nameディレクティブのように複数指定が可能。先頭から順に検索される
-
-
location
-
プロトコルレベル(httpコンテキスト)、サーバレベル(serverコンテキスト)ときて、ファイルの場所を指定するサブディレクトリレベルでの振り分けを行うコンテキスト
-
location [修飾子] サブディレクトリ
で指定したサブディレクトリに一致したアクセスが来ると、コンテキスト中の処理を行う -
サブディレクトリとの一致については優先規則がある
-
修飾子によってURIをlocationにマッチさせる方法が変わる
= 完全一致
~ 対正規表現 (大文字小文字を区別)
~* 対正規表現 (大文字小文字を区別しない)
^~ 先頭一致 (マッチした時点で終了)
(修飾子なし) 先頭一致 (後方参照あり) -
-
root
-
ドキュメントルートのパスを指定
-
あるルーティング設定をファイルサーバとして割り振りたい時活躍する
-
サーバ全体にファイルサーバの役割を任せるなら
次のようにserverコンテキストに置いて下位に継承させるのが良い
-
http {
server {
server_name example.com;
root /home/test/webapp/public/;
location /icons/ { }
location /musics/ { }
}
}
仮想ホスト
serverコンテキストを並列にすることで実現できる
例えば次のようになる
server {
listen 80;
server_name www.hoge.jp w3.hoge.jp;
...
}
server {
listen 80;
server_name www2.hoge.jp;
...
}
-
HTTPリクエストのHOSTパラメータとserver_nameをマッチさせるが、もしそのパラメータが存在しない場合空白
""
とみなされる -
もしこれらの server_name と一致 しなかった場合には、デフォルトのサーバでリクエストは処理される。 デフォルトのサーバは、最初に定義されているサーバ、
www.hoge.jp
となる -
もし、デフォルトサーバを一番目のサーバではなく、指定したサーバで 処理させたい場合には、default_server パラメータを listen ディレクティブ に用いることが出来る。
server {
listen 80 default_server;
server_name www2.hoge.jp;
...
リバースプロキシ
http_proxy_moduleに備わっているディレクティブを活用する。rewriteモジュールも関係するらしいがここでは触れない
-
proxy-pass
-
リバースプロキシを実現するには欠かせないディレクティブ
-
/back/
へのアクセスをhttp://backend/back
として backendサーバに中継する場合
location /back/ { proxy_pass http://backend; ... }
-
プロトコル、サーバ名で指定した場合には、もともとのサブディレクトリを含んだURLが 引き渡されている
-
プログラムを状態稼働させておいてlisten状態にし、リクエストを転送するという使い方もある。
その場合proxy_passにはhttp://127.0.0.1:8080;
を指定することも多い -
reverse_passがサブディレクトリまで含んだURIを指定していた場合どうなるか
location /back/ { proxy_pass http://backend/home/; ... }
-
/back/
へのURI は、proxy_pass ディレクティブで指定したhttp://backend/home/
に置き換わる。 -
proxy_passに与えるURLにトレイリングスラッシュが存在するかどうかで挙動が違うらしいので注意
正直この辺りは文献によって違っている気がする。一対一の対応にしたいのであればlocationディレクティブに関してもproxy-passディレクティブに関しても、指定するURIにはトレイリングスラッシュをつけるのが無難か -
公式ドキュメントに
When location is specified using a regular expression, and also inside named locations.In these cases, should be specified without a URI.
とある通り、正規表現で指定したlocationの場合、直前の例で見たサブディレクトリを含んだ指定方法は推奨されていない
-
-
proxy_set_header
-
プロキシサーバに送られるリクエストヘッダのフィールドを再定義、あるいは追加する
-
書式は
proxy_set_header フィールド名 値;
-
デフォルトで以下の2つが定義済み
proxy_set_header Host $proxy_host; proxy_set_header Connection close; #$proxy_host #プロキシサーバ名
-
proxy_set_header Host $host;
のように追加すると、プロキシするサーバが仮想サーバである場合にサーバ名を利用できたりして便利
-
-
upstream
-
サーバグループを定義する。負荷を分散させたいとき等プロキシサーバを複数用意したいときに使う
-
書式は
upstream グループ名 { server サーバ名 サーバのドメイン [パラメータ] ... }
- 例としては次のようになる
upstream ourserver { server net-1.cc.matsue-ct.ac.jp weight=3; #weightパラメータは優先度の重み付けを決定する server net-2.cc.matsue-ct.ac.jp weight=2; server net-3.cc.matsue-ct.ac.jp; server net-4.cc.matsue-ct.ac.jp backup; #backupパラメータは他の全てのサーバがdownしているときのみ該当サーバが動くよう設定する } server { location / { proxy_pass http://ourserver; } }
参考
Nginx入門
基本的な正規表現一覧
バーチャルホスト(仮想ホスト)とは - IT用語辞典 e-Words
ディレクトリインデックス(DirectoryIndex)
Nginxのlocationとproxy_passの末尾スラッシュによる挙動の違いを理解する
Module ngx_http_proxy_module -