Web架構之Nginx基礎配置

  • 2020 年 3 月 14 日
  • 筆記

1、Nginx 虛擬主機

所謂的虛擬主機,在Web服務里就是一個獨立的網站站點,這個站點對應獨立的域名(也可能是IP或埠),具有獨立的程式及資源目錄,可以獨立地對外提供服務供用戶訪問。
在Nginx中則使用一個server{} 標籤來標識一個虛擬主機,一個Web服務里可以有多個虛擬主機標籤對。

虛擬主機類型

1)基於域名的虛擬主機  通過不同的域名區分不同的虛擬主機  應用:外部網站    2)基於埠的虛擬主機  通過不同的埠區分不同的虛擬主機  應用:公司內部網站,網站的後台    3)基於IP的虛擬主機  通過不同的IP區分不同的虛擬主機  應用:幾乎不用

1.1、基於域名的虛擬主機

域名1:www.hhjy.com

域名2:bbs.hhjy.org

1.修改nginx配置文件,創建兩個虛擬主機

$ cat /etc/nginx/nginx.conf  user  nginx;  worker_processes  1;  error_log  /var/log/nginx/error.log warn;  pid        /var/run/nginx.pid;  events {      worker_connections  1024;  }  http {      include       /etc/nginx/mime.types;      default_type  application/octet-stream;      log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '                        '$status $body_bytes_sent "$http_referer" '                        '"$http_user_agent" "$http_x_forwarded_for"';      access_log  /var/log/nginx/access.log  main;      sendfile        on;      keepalive_timeout  65;      include /etc/nginx/conf.d/*.conf;        server {          listen 80;                              # 監聽埠          server_name www.hhjy.com; # 域名:www.hhjy.com          location / {                            # 匹配url請求為根目錄              root /data/www;       # 匹配到url請求後會在該站點目錄下查找對應的文件              index index.html index.htm; # 默認主頁文件名          }      }      server {          listen 80;          server_name bbs.hhjy.com; # 域名:bbs.hhjy.com          location / {              root /data/bbs;              index index.html index.htm;          }      }  }

2.為各自站點創建目錄,並各自創建index.html

$ mkdir -p /data/{www,bbs}  $ echo "domain from in www" >/data/www/index.html  $ echo "domain from in bbs" >/data/bbs/index.html

3.校驗nginx配置文件語法並平滑重啟

$ nginx -t  nginx: the configuration file /etc/nginx/nginx.conf syntax is ok  nginx: configuration file /etc/nginx/nginx.conf test is successful  $ nginx -s reload

4.客戶端添加hosts(因為域名只在測試環境使用,並沒有備案,那就直接修改hosts文件)

$ vim /etc/hosts  10.4.7.7 www.hhjy.com bbs.hhjy.com

5.訪問兩個虛擬主機/域名

$ curl www.hhjy.com  domain from in www    $ curl bbs.hhjy.com  domain from in bbs

注意事項:

1、當伺服器存在多個虛擬主機,客戶端用IP地址訪問網站的時候,因為HTTP請求頭沒有攜帶host欄位,所以伺服器只會用nginx.conf中的第一個server的location回應
2、當伺服器存在多個虛擬主機,客戶端用域名訪問網站的時候,因為HTTP請求頭有攜帶host欄位,所以伺服器會根據host里的域名查找nginx.conf中對應的location回應

1.2、基於埠的虛擬主機

域名:www.hhjy.com ,埠:81

域名:bbs.hhjy.com ,埠:82

1.修改nginx配置文件,添加基於埠虛擬主機配置

$ cat /etc/nginx/nginx.conf  user  nginx;  worker_processes  1;  error_log  /var/log/nginx/error.log warn;  pid        /var/run/nginx.pid;  events {      worker_connections  1024;  }  http {      include       /etc/nginx/mime.types;      default_type  application/octet-stream;      log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '                        '$status $body_bytes_sent "$http_referer" '                        '"$http_user_agent" "$http_x_forwarded_for"';      access_log  /var/log/nginx/access.log  main;      sendfile        on;      keepalive_timeout  65;      include /etc/nginx/conf.d/*.conf;        server {          listen 81;          server_name www.hhjy.com;          location / {              root /data/www;              index index.html index.htm;          }      }      server {          listen 82;          server_name bbs.hhjy.com;          location / {              root /data/bbs;              index index.html index.htm;          }      }  }

2.修改各站點目錄下index.html的內容

$ echo "port from in www" >/data/www/index.html  $ echo "port from in bbs" >/data/bbs/index.html

3.校驗nginx配置文件語法並平滑重啟

$ nginx -t  nginx: the configuration file /etc/nginx/nginx.conf syntax is ok  nginx: configuration file /etc/nginx/nginx.conf test is successful  $ nginx -s reload

4.檢查nginx埠發現多了81、82埠

$ netstat -lntup | grep  -E "81|82"  tcp        0      0 0.0.0.0:81              0.0.0.0:*               LISTEN      1573/nginx: master  tcp        0      0 0.0.0.0:82              0.0.0.0:*               LISTEN      1573/nginx: master

5.訪問nginx,以不同埠方式訪問(前面已經做hosts域名綁定IP)

$ curl www.hhjy.com:81  port from in www    $ curl bbs.hhjy.com:82  port from in bbs

1.3、基於IP的虛擬主機

我們在上面都是使用域名或者域名+埠方式訪問,但是它們都是指向監聽一個IP地址,下面我們讓nginx監聽多個IP來實現虛擬主機

1.修改nginx配置文件,添加基於埠虛擬主機配置

$ cat /etc/nginx/nginx.conf  user  nginx;  worker_processes  1;  error_log  /var/log/nginx/error.log warn;  pid        /var/run/nginx.pid;  events {      worker_connections  1024;  }  http {      include       /etc/nginx/mime.types;      default_type  application/octet-stream;      log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '                        '$status $body_bytes_sent "$http_referer" '                        '"$http_user_agent" "$http_x_forwarded_for"';      access_log  /var/log/nginx/access.log  main;      sendfile        on;      keepalive_timeout  65;      include /etc/nginx/conf.d/*.conf;        server {          listen 10.4.7.101:80;          server_name www.hhjy.com;          location / {              root /data/www;              index index.html index.htm;          }      }      server {          listen 10.4.7.102:80;          server_name bbs.hhjy.com;          location / {              root /data/bbs;              index index.html index.htm;          }      }  }

2.修改各站點目錄下index.html的內容

$ echo "ip from in www" >/data/www/index.html  $ echo "ip from in bbs" >/data/bbs/index.html

3.配置兩個輔助IP 10.4.7.101和10.4.7.102

$ ip addr add 10.4.7.101/24 dev eth0 label eth0:1  $ ip addr add 10.4.7.102/24 dev eth0 label eth0:2    // 檢查是否配置成功  $ ip add | grep -E "101|102"      inet 10.4.7.101/24 scope global secondary eth0:1      inet 10.4.7.102/24 scope global secondary eth0:2

4.先停止nginx(reload可能會不生效),在啟動

$ nginx -s stop  $ nginx -t  nginx: the configuration file /etc/nginx/nginx.conf syntax is ok  nginx: configuration file /etc/nginx/nginx.conf test is successful    $ nginx

提示:nginx服務中只要涉及到IP地址的修改,都需要重啟nginx服務,而不能採用平滑重啟

5.訪問nginx,以不同IP方式訪問

$ curl 10.4.7.101  ip from in www    $ curl 10.4.7.102  ip from in bbs

2、Nginx include

有時候,虛擬主機配置特別多,總不可能把所有配置都塞到nginx主配置文件中,而是將每個虛擬主機放到一個nginx配置文件中,然後統一存放在一個目錄下,但是nginx主進程如何載入這些目錄下的nginx配置文件,這就要用到include參數,只需要指定某個目錄下的*即可,使用方法如下:

直接在nginx主配置文件下http區塊中使用:

include 文件目錄/*;       # 匹配所有文件  include 文件目錄/*.conf;  # 匹配以.conf結尾的文件  include 文件目錄/*.proxy; # 匹配以.proxy結尾的文件

現在版本的nginx的主配置文件都默認添加了include /etc/nginx/conf.d/*.conf; 參數

3、Nginx 日誌配置

3.1、訪問日誌

Nginx會把每個訪問到虛擬主機的用戶資訊記錄到指定的日誌文件中,供運維/開發分析用戶瀏覽行為、流量等

此功能由ngx_http_log_module模組負責

訪問日誌參數(http/server區塊):

log_format # 用來定義記錄日誌的格式(可以定義多種日誌格式,取不同名字即可)  access_log # 用來制定日誌文件的路徑及使用的何種日誌格式記錄日誌

Nginx訪問日誌默認格式配置如下:

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '                    '$status $body_bytes_sent "$http_referer" '                    '"$http_user_agent" "$http_x_forwarded_for"';

其實訪問日誌記錄格式就是從http請求頭部獲取到指定變數名的值而已

Nginx訪問日誌格式引用配置如下:

access_log  /var/log/nginx/access.log  main;

Nginx 日誌變數說明:

$remote_addr:記錄訪問網站的客戶端源地址資訊  $remote_user:訪問客戶端認證用戶資訊  $time_local:記錄訪問時間與時區  $request:用戶的http請求行資訊  $status:http狀態碼,記錄請求返回的狀態碼,例如:200、301、404等  $http_referer:記錄此次請求是從哪個連接訪問過來的,可以根據該參數進行防盜鏈設置。  $body_bytes_sent:伺服器發送給客戶端的響應body位元組數  $http_user_agent:記錄客戶端訪問資訊,例如:瀏覽器、手機客戶端等  $http_x_forwarded_for:當前端有代理伺服器時,設置web節點記錄客戶端地址的配置,此參數生效的前提是代理伺服器也要進行相關的x_forwarded_for設置

3.2、錯誤日誌

Nginx會將自身運行時的故障資訊以及用戶訪問時產生的錯誤資訊都記錄到指定日誌文件里,配置記錄nginx錯誤日誌資訊是調試nginx的重要手段,屬於核心功能模組http_core_module的參數,該參數名為error_log,可以放在Main區塊中全局配置,也可以放置在Server區塊中單獨記錄虛擬主機的錯誤資訊。

nginx錯誤日誌記錄級別:

日誌記錄級別:debug, info, notice, warn, error, crit

Nginx錯誤日誌定義語法:

Syntax: error_log file [level];  Default:    error_log  /var/log/nginx/error.log warn;  Context:    main, http, mail, stream, server, location

關鍵字不能變,日誌文件可以指定任意存放日誌的目錄,錯誤日誌級別越高記錄的資訊越少,一般只記錄error,不要配置info等較低的級別,會帶來巨大磁碟I/O消耗。

3.3、日誌輪訓切割

如果不對日誌進行切割,那麼當訪問量大和時間久了之後會發現一個日誌文件會超過100M,那麼大量的日誌資訊保存在一個日誌文件里,也不方便查找,就需要每天將日誌進行切割,切割的日誌文件以日期為命名。

1.編寫腳本文件,為訪問/錯誤日誌做輪訓切割

$ cat /server/scripts/cut_nginx_log.sh  #!/bin/bash  LogPath="/var/log"  AccessLogFile="${LogPath}/nginx/access.log"  ErrorLogFile="${LogPath}/nginx/error.log"  NginxCmd=$(which nginx)    if [ ! ${NginxCmd} ];then     echo "nginx 命令不存在,退出日誌切割..."     exit 1  fi    /bin/mv  ${AccessLogFile} ${LogPath}/nginx/access_$(date +%F -d '-1day').log  /bin/mv  ${ErrorLogFile} ${LogPath}/nginx/error_$(date +%F -d '-1day').log    ${NginxCmd} -s reload

2.執行腳本

$ sh /server/scripts/cut_nginx_log.sh

3.查看日誌切割效果

$ ls -lh /var/log/nginx/  total 8.0K  -rw-r--r-- 1 root root  0 Mar 13 22:59 access_2020-03-12.log  -rw-r--r-- 1 root root  0 Mar 13 23:00 access.log  -rw-r--r-- 1 root root 63 Mar 13 22:59 error_2020-03-12.log  -rw-r--r-- 1 root root 63 Mar 13 23:00 error.log

4.將日誌切割腳本添加到定時任務,每天凌晨執行

// 給腳本賦予可執行許可權  $ chmod +x /server/scripts/cut_nginx_log.sh    // 添加定時任務  $ crontab  -e  ### Cut Nginx access and error logs at 00:00 each day  00 00 * * * /bin/sh /server/scripts/cut_nginx_log.sh  >/dev/null 2>&1

4、Nginx Location

Location在前面的文章里我們已經接觸到了,那麼它到底是幹啥的?

Location的作用是可以根據用戶請求的URI來執行不同的應用(URI=URL),location支援很多語法,這些語法可以認為是正則匹配,根據用戶訪問的URI來匹配到對應的location正則

location語法:

location[=|~|~*|^~|@]uri {      ...  }    // 語法解釋:  location      # 關鍵字  [=|~|~*|^~|@] # 正則匹配規則  uri                     # 匹配的URI路徑  {...}         # 匹配URI後要執行的配置段

location正則匹配:

=      # 精確匹配網站url資源資訊  ~      # 區分大小寫匹配網站url資源資訊  ~*     # 不區分大小寫匹配網站url資源資訊  /mp3/  # 指定匹配網站資源目錄資訊  /      # 默認匹配網站資源資訊  !      # 對匹配的內容進行取反  ^~     # 普通字元匹配,使用前綴匹配    // 正則優先順序  優先順序1:=  優先順序2:^~  優先順序3:~  優先順序3:~*

官方的location舉例:**

location = / {      [ configuration A ]     # 優先順序最高①  }    location / {      [ configuration B ]     # 所有匹配都不滿足時候,匹配默認location ④  }    location /documents/ {      # 根據資源目錄進行匹配  ③      [ configuration C ]  }    location ^~ /images/ {      # 優先匹配②      [ configuration D ]  }    location ~* .(gif|jpg|jpeg)$ {  # 不區分大小寫匹配網站資源 ③      [ configuration E ]  }

5、Nginx 下載站點

Nginx默認是不允許列出整個目錄瀏覽下載,通過autoindex關鍵字可實現目錄瀏覽下載

autoindex語法:

Syntax: autoindex on | off; Default:  autoindex off; Context: http, server, location    // autoindex常⽤參數  autoindex_exact_size off;  默認為on, 顯示出⽂件的確切⼤⼩,單位是bytes。  修改為off,顯示出⽂件的⼤概⼤⼩,單位是kB或者MB或者GB。    autoindex_localtime on;  默認為off,顯示的⽂件時間為GMT時間。  修改為on, 顯示的⽂件時間為⽂件的伺服器時間。    charset utf-8,gbk;  默認中⽂⽬錄亂碼,添加上解決亂碼。

配置目錄瀏覽功能

1.添加nginx配置,開啟目錄瀏覽

$ vim /etc/nginx/conf.d/web_dir.conf  server {      listen 80;      server_name download.hhjy.org;      location / {          root /data/file;          autoindex on;          autoindex_localtime on;          autoindex_exact_size off;        }  }

2.創建站點目錄,並新建幾個測試文件

$ mkdir /data/file  $ touch /data/file/t1.txt  $ touch /data/file/t2.txt

3.平滑重啟nginx

$ nginx -s reload

4.客戶端修改hosts文件,綁定域名對應的nginx伺服器ip

$ vim /etc/hosts  10.4.7.7 download.hhjy.org

5.瀏覽器訪問:download.hhjy.org

6、Nginx 用戶登錄認證

很多時候我們登錄內部網站不想做太複雜的用戶登錄認證,那麼可以使用Nginx自帶的認證,基於auth_basic關鍵字來實現basic auth

auth_basic語法:

// 配置語法  Syntax: auth_basic string| off;  Default: auth_basic off;  Context: http, server, location, limit_except    // ⽤戶密碼記錄配置⽂件  Syntax: auth_basic_user_file file;  Default:  Context: http, server, location, limit_except

basic認證實現:

1.安裝httpd-tools工具

$ yum install httpd-tools    // 使用該工具下的htpasswd命令創建用戶名和密碼  $ htpasswd -bc /etc/nginx/conf.d/auth_conf admin 123456  Adding password for user admin

2.添加nginx配置,配置auth

$ vim /etc/nginx/conf.d/basic_auth.conf  server {      listen 80;      server_name auth.hhjy.org;      location / {          auth_basic "Auth access Input your Passwd!";              auth_basic_user_file /etc/nginx/conf.d/auth_conf;        }  }

3.平滑重啟nginx

$ nginx -s reload

4.客戶端修改hosts文件,綁定域名對應的nginx伺服器ip

$ vim /etc/hosts  10.4.7.7 auth.hhjy.org

5.瀏覽器訪問:auth.hhjy.org,輸入設置好的用戶名和密碼即可訪問