Linux下Nginx基礎應用

上古南城發表於2021-08-02

    

Nginx簡介:

  • Nginx ("engine x") 是一個高效能的HTTP和反向代理伺服器,也是一個IMAP/POP3/SMTP伺服器。其將原始碼以類BSD許可證的形式釋出,因它的穩定性、豐富的功能集、示例配置檔案和低系統資源的消耗而聞名。
  • Nginx是一款輕量級的Web 伺服器/反向代理伺服器及電子郵件(IMAP/POP3)代理伺服器,並在一個BSD-like 協議下發行。其特點是佔有記憶體少,併發能力強,事實上nginx的併發能力確實在同型別的網頁伺服器中表現較好。
  • Nginx不但是一個優秀Web服務軟體,還具有反向代理負載均衡功能和快取服務功能,與lvs負載均衡及Haproxy等專業代理軟體相比,Nginx部署起來更為簡單,方便;在快取功能方面,它又類似於Squid等專業的快取服務軟體。

Nginx相對於傳統的Apache服務的優缺點:

  • (1) 作為 Web 伺服器:相比 Apache,Nginx 使用更少的資源,支援更多的併發連線,體現更高的效率,這點使 Nginx 尤其受到虛擬主機提供商的歡迎。在高連線併發的情況下,Nginx是Apache伺服器不錯的替代品;
  • (2) Nginx 配置簡潔,Apach複雜;Nginx靜態處理效能比Apache高3倍以上;Apache對PHP支援比較簡單,Nginx需要配合其他後端用;Apache的元件比Nginx多;
  • (3) apache是同步多程式模型,一個連線對應一個程式;nginx是非同步的,多個連線(萬級別)可以對應一個程式;
  • (4) nginx處理靜態檔案好,耗費記憶體少,但apache目前也有它的優勢,有很多豐富的特性,所以還需要搭配著來;當然如果能確定nginx就適合需求,那麼使用nginx會是更經濟的方式;
  • (5) nginx的負載能力比apache高很多,而且nginx改完配置能-t測試一下配置有沒有問題,apache重啟的時候發現配置出錯了,會很崩潰,改的時候都會非常小心翼翼現在看有好多叢集站,前端nginx抗併發,後端apache叢集,配合的也不錯;

Nginx模組化體系結構:

 

nginx的模組根據其功能基本上可以分為以下幾種型別:

  • event module: 搭建了獨立於作業系統的事件處理機制的框架,及提供了各具體事件的處理。包括ngx_events_module, ngx_event_core_module和ngx_epoll_module等。nginx具體使用何種事件處理模組,這依賴於具體的作業系統和編譯選項。
  • phase handler: 此型別的模組也被直接稱為handler模組。主要負責處理客戶端請求併產生待響應內容,比如ngx_http_static_module模組,負責客戶端的靜態頁面請求處理並將對應的磁碟檔案準備為響應內容輸出。
  • output filter: 也稱為filter模組,主要是負責對輸出的內容進行處理,可以對輸出進行修改。例如,可以實現對輸出的所有html頁面增加預定義的footbar一類的工作,或者對輸出的圖片的URL進行替換之類的工作。
  • upstream: upstream模組實現反向代理的功能,將真正的請求轉發到後端伺服器上,並從後端伺服器上讀取響應,發回客戶端。upstream模組是一種特殊的handler,只不過響應內容不是真正由自己產生的,而是從後端伺服器上讀取的。
  • load-balancer: 負載均衡模組,實現特定的演算法,在眾多的後端伺服器中,選擇一個伺服器出來作為某個請求的轉發伺服器。

 Nginx程式流程:

  

 Nginx 伺服器,正常執行過程中:

  • 多程式:一個 Master 程式、多個 Worker 程式
  • Master 程式:管理 Worker 程式
    • 對外介面:接收外部的操作(訊號)
    • 對內轉發:根據外部的操作的不同,通過訊號管理 Worker
    • 監控:監控 worker 程式的執行狀態,worker 程式異常終止後,自動重啟 worker 程式
  • Worker 程式:所有 Worker 程式都是平等的
    • 實際處理:網路請求,由 Worker 程式處理;
    • Worker 程式數量:在 nginx.conf 中配置,一般設定為核心數,充分利用 CPU 資源,同時,避免程式數量過多,避免程式競爭 CPU 資源,增加上下文切換的損耗。

以下是常見http功能模組:

http類模組名模組功能說明
ngx_http_core_module http核心模組,對應配置檔案中的http段,包含很多指令,如location指令
ngx_http_access_module 訪問控制模組,控制網站使用者對nginx的訪問,對應於配置檔案中的allow和deny等指令
ngx_http_auth_basic_module 通過使用者名稱和密碼認證的訪問控制,如訪問站點時需要資料使用者名稱和密碼,指令包括auth_basic和auth_basic_user_file
ngx_http_charset_module 設定網頁顯示字符集。指令之一為charset,如charset utf-8
ngx_http_fastcgi_module fastcgi模組,和動態應用相關。該模組下有非常多的子模組。
ngx_http_flv_module 支援flv視訊流的模組,如邊下邊播
ngx_http_mp4_module 同flv模組
ngx_http_gzip_module 壓縮模組,用來壓縮nginx返回的響應報文。一般只壓縮純文字內容,因為壓縮比例非常大,而圖片等不會去壓縮
ngx_http_image_filter_module 和圖片裁剪、縮圖相關模組,需要安裝gd-devel才能編譯該模組
ngx_http_index_module 定義將要被作為預設主頁的檔案,對應指令為index。"index index.html,index.php"
ngx_http_autoindex_module 當index指令指定的主頁檔案不存在時,交給autoindex指令,將自動列出目錄中的檔案autoindex {on/off}  
ngx_http_log_module 和訪問日誌相關的模組,指令包括log_format和access_log
ngx_http_memcached_module 和memcached相關的模組,用於從memcached伺服器中獲取相應響應資料
ngx_http_proxy_module 和代理相關,允許傳送請求到其它伺服器
ngx_http_realip_module 當nginx在反向代理的後端提供服務時,獲取到真正的客戶端地址,否則獲取的是反向代理的IP地址
ngx_http_referer_module 實現防盜鏈功能的模組
ngx_http_rewrite_module 和URL地址重寫相關的模組,需要安裝pcre-devel才能編譯安裝該模組
ngx_http_scgi_module simple cgi,是cgi的替代品,和fastcgi類似,但更簡單
ngx_http_ssl_module 提供ssl功能的模組,即實現HTTPS
ngx_http_stub_status_module 獲取nginx執行狀態資訊
ngx_http_upstream 和負載均衡相關模組

Nginx官方站點:

第一部分:CentOS7下使用YUM安裝Nginx指定版本。

# 準備環境
[root@Server-01 ~]# cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)
[root@Server-01 ~]# uname -a
Linux Server-01 3.10.0-862.el7.x86_64 #1 SMP Fri Apr 20 16:44:24 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
[root@Server-01 ~]# uname -r
3.10.0-862.el7.x86_64
[root@Server-01 ~]# setenforce 0
[root@Server-01 ~]# systemctl stop firewalld
[root@Server-01 ~]# hostname -I
172.16.70.37

# 安裝nginx-1.14.2;目前(2021-07)最新版本為nginx-1.20.1
[root@nginxServer ~]# rpm -ivh http://nginx.org/packages/centos/7/x86_64/RPMS/nginx-1.14.2-1.el7_4.ngx.x86_64.rpm
[root@nginxServer ~]# nginx -v
nginx version: nginx/1.14.2

[root@nginxServer ~]# rpm -qa | grep nginx
nginx-1.14.2-1.el7_4.ngx.x86_64
[root@nginxServer ~]# rpm -ql nginx | less
/etc/logrotate.d/nginx
/etc/nginx         # 相關配置檔案存放目錄
/etc/nginx/conf.d            
/etc/nginx/conf.d/default.conf     
/etc/nginx/fastcgi_params
/etc/nginx/koi-utf
/etc/nginx/koi-win
/etc/nginx/mime.types
/etc/nginx/modules
/etc/nginx/nginx.conf
/etc/nginx/scgi_params
/etc/nginx/uwsgi_params
/etc/nginx/win-utf
/etc/sysconfig/nginx
/etc/sysconfig/nginx-debug
/usr/lib/systemd/system/nginx-debug.service
/usr/lib/systemd/system/nginx.service
/usr/lib64/nginx
/usr/lib64/nginx/modules
/usr/libexec/initscripts/legacy-actions/nginx
/usr/libexec/initscripts/legacy-actions/nginx/check-reload
/usr/libexec/initscripts/legacy-actions/nginx/upgrade
/usr/sbin/nginx
/usr/sbin/nginx-debug
/usr/share/doc/nginx-1.14.2
/usr/share/doc/nginx-1.14.2/COPYRIGHT
/usr/share/man/man8/nginx.8.gz
/usr/share/nginx
/usr/share/nginx/html    # 預設站點存放目錄
/usr/share/nginx/html/50x.html
/usr/share/nginx/html/index.html
/var/cache/nginx
/var/log/nginx        # 日誌檔案存放目錄

-----------------------------------------------------------------------------
# systemctl命令:
服務狀態 systemctl status nginx
服務啟動 systemctl start nginx
服務停止 systemctl stop nginx
服務重啟 systemctl restart nginx

# nginx命令語法及引數:
[root@nginxServer ~]# nginx -h
nginx version: nginx/1.14.2
Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]

Options:
  -?,-h         : this help
  -v            : 輸出版本號
  -V            : 輸出版本號以及編譯選項
  -t            : 檢查配置檔案的語法
  -T            : 檢查配置檔案的語法並輸出配置的內容
  -q            : 靜默模式,不輸出任何資訊
  -s signal     : 向主程式傳送訊號:stop, quit, reopen, reload
  -p prefix     : 設定nginx的basedir(預設為編譯時的prefix)
  -c filename   : 指定配置檔案
  -g directives : 提前設定全域性指令
-------------------------------------------------------------------------------
# 啟動,並設定開機啟動
[root@nginxServer ~]# systemctl start nginx && systemctl enable nginx
Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.

[root@nginxServer ~]# ps -ef |grep nginx
root       1466      1  0 16:54 ?        00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx      1467   1466  0 16:54 ?        00:00:00 nginx: worker process
root       1486   1178  0 16:54 pts/0    00:00:00 grep --color=auto nginx
[root@nginxServer ~]# netstat -nutlp | grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1466/nginx: master
  • Web檢測測試效果。

  • Nginx預設配置檔案解析:
[root@nginxServer ~]# cat /etc/nginx/nginx.conf

user  nginx;      # 配置使用者或組
worker_processes  1;      # worker允許生成的程式數

error_log  /var/log/nginx/error.log warn;    # 制定日誌路徑,級別。這個設定可以放入全域性塊,http塊,server塊,級別以此為:debug|info|notice|warn|error|crit|alert|emerg
pid        /var/run/nginx.pid;    # 指定nginx程式執行檔案存放位置


events {    # 事件區塊
    worker_connections  1024;    # 每個worker程式支援的最大連線數
}


http {    # 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;    # 預設log格式

    sendfile        on;    # 允許sendfile方式傳輸檔案,可以在http塊,server塊,location塊
    #tcp_nopush     on;

    keepalive_timeout  65;   # 連線超時時間,可以在http塊,server塊,location塊

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;  # 生效包含自定義配置
}

[root@nginxServer nginx]# cat conf.d/default.conf
server {    # 網站配置區域
    listen       80;  # 提供服務的埠,預設80
    server_name  localhost;    # 提供服務的域名主機名

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {    # location區塊開始
        root   /usr/share/nginx/html;    # 站點的根目錄(相對與nginx安裝目錄)
        index  index.html index.htm;    # 預設的首頁檔案,多個用空格分開
    }

    #error_page  404              /404.html;    

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;    # 出現對應的http狀態碼時,使用50x.html回應客戶
    location = /50x.html {      # location區塊開始,訪問50x.html
        root   /usr/share/nginx/html;    # 指定對應的站點目錄為html
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

-----------------------------------------------------------
# 整個nginx配置檔案的核心框架如下
worker_processes 1;
events {
    
    worker_connections 1024;

}
http {
    include mime.types;
    server {
        listen  80;
        server_name localhost;
        location / {
            root  html;
            index  index.html index.htm;
        }
    }
}

 第二部分:設定虛擬主機。

  • nginx使用server容器定義一個虛擬主機。在nginx中,沒有嚴格區分基於IP和基於名稱的虛擬主機,它們通過listen指令和server_name指令結合起來形成不同的虛擬主機。
# 配置檔案目錄結構
[root@nginxServer ~]# tree /etc/nginx/
/etc/nginx/
├── conf.d
│   ├── default.conf
├── fastcgi_params
├── koi-utf
├── koi-win
├── mime.types
├── modules -> ../../usr/lib64/nginx/modules
├── nginx.conf
├── scgi_params
├── uwsgi_params
└── win-utf

2 directories, 10 files

說明:其中".default"字尾的是對應字首配置檔案的備份配置檔案,".params"是對應字首的引數檔案。

# 建立站點目錄及站點內容
[root@nginxServer ~]# for i in {1..3}; do mkdir -p /data/web/nginx/www$i; echo "Mysite-$i www$i.nginx.com" > /data/web/nginx/www$i/index.html; done
[root@nginxServer ~]# tree /data/web/nginx/
/data/web/nginx/
├── www1
│   └── index.html
├── www2
│   └── index.html
└── www3
    └── index.html

3 directories, 3 files
[root@nginxServer ~]# cat /data/web/nginx/www*/*
Mysite-1 www1.nginx.com
Mysite-2 www2.nginx.com
Mysite-3 www3.nginx.com

[root@nginxServer ~]# cd /etc/nginx/conf.d/
[root@nginxServer conf.d]# mv default.conf default.conf_bak

# 新增虛擬主機配置檔案
[root@nginxServer conf.d]# vim vhosts.conf
# 基於埠port
server {
    listen       8081;
    server_name  www1.nginx.com;
    location / {
        root   /data/web/nginx/www1;
        index  index.html index.htm;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /data/web/nginx/www1;
    }
}

server {
    listen       8082;
    server_name  www2.nginx.com;
    location / {
        root   /data/web/nginx/www2;
        index  index.html index.htm;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /data/web/nginx/www2;
    }
}

# 基於域名FQDN
server {
    listen       80;
    server_name  www1.nginx.com;
    location / {
        root   /data/web/nginx/www1;
        index  index.html index.htm;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /data/web/nginx/www1;
    }
}

server {
    listen       80;
    server_name  www3.nginx.com;
    location / {
        root   /data/web/nginx/www3;
        index  index.html index.htm;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /data/web/nginx/www3;
    }
}

#基於IP地址
server {
    listen       80;
    server_name  172.16.70.37;
    location / {
        root   /data/web/nginx/www2;
        index  index.html index.htm;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /data/web/nginx/www2;
    }
}

server {
    listen       80;
    server_name  172.16.70.38;
    location / {
        root   /data/web/nginx/www3;
        index  index.html index.htm;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /data/web/nginx/www3;
    }
}

# 新增nginx狀態資訊配置檔案
[root@nginxServer conf.d]# vim status.conf
# State information

server{

    listen 80;
    server_name status.nginx.com;
    location / {
        stub_status on;
        access_log off;
    }
}


# 基於域名,新增地址解析
[root@nginxServer conf.d]# echo '172.16.70.37 www1.nginx.com www2.nginx.com www3.nginx.com status.nginx.com' >> /etc/hosts

# 基於IP,新增IP地址
[root@nginxServer conf.d]# ip addr add 172.16.70.38/24 dev ens33
[root@nginxServer conf.d]# ip addr | grep ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 172.16.70.37/24 brd 172.16.70.255 scope global noprefixroute dynamic ens33
    inet 172.16.70.38/24 scope global secondary ens33
[root@nginxServer conf.d]# ping 172.16.70.38 -c2
PING 172.16.70.38 (172.16.70.38) 56(84) bytes of data.
64 bytes from 172.16.70.38: icmp_seq=1 ttl=64 time=0.015 ms
64 bytes from 172.16.70.38: icmp_seq=2 ttl=64 time=0.059 ms

--- 172.16.70.38 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.015/0.037/0.059/0.022 ms

[root@nginxServer conf.d]# nginx -t    # 檢測配置檔案語法
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

[root@nginxServer conf.d]# nginx -s reload    # 過載nginx
[root@nginxServer conf.d]# netstat -ntupl | grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1466/nginx: master
tcp        0      0 0.0.0.0:8081            0.0.0.0:*               LISTEN      1466/nginx: master
tcp        0      0 0.0.0.0:8082            0.0.0.0:*               LISTEN      1466/nginx: master

# 檢測測試結果
[root@nginxServer conf.d]# hostname -I
172.16.70.37
# 基於埠
[root@nginxServer conf.d]# curl 172.16.70.37:8081
Mysite-1 www1.nginx.com
[root@nginxServer conf.d]# curl 172.16.70.37:8082
Mysite-2 www2.nginx.com
# 基於域名
[root@nginxServer conf.d]# curl www1.nginx.com
Mysite-1 www1.nginx.com
[root@nginxServer conf.d]# curl www3.nginx.com
Mysite-3 www3.nginx.com
# 基於IP
[root@nginxServer conf.d]# curl 172.16.70.37
Mysite-2 www2.nginx.com
[root@nginxServer conf.d]# curl 172.16.70.38
Mysite-3 www3.nginx.com

# 顯示狀態結果
[root@nginxServer conf.d]# curl status.nginx.com
Active connections: 1
server accepts handled requests
 105 105 116
Reading: 0 Writing: 1 Waiting: 0

說明:
  Active connections    當前nginx正處理的活動連線數
  server           總共處理的連線數
  accepts           成功建立握手次數
  handled requests     總共處理請求數(平均每次握手處理了1.3個資料請求)         
  Reading          nginx讀取到客戶端的Header資訊數
  Writing          nginx返回給客戶端的Header資訊數
  Waiting          nginx已經處理完正在等候下一次請求指令的駐留連線。在開啟keep-alive的情況下,這個值等於active - (reading+writing)

 第三部分:Nginx Web認證

  • 基於使用者認證。即需要輸入使用者名稱和密碼才能訪問站點的功能為web身份認證功能。nginx中由ngx_http_auth_basic_module模組提供該功能。指令包括auth_basic和auth_basic_user_file。這兩個指令可以在http根段、server段、location段使用。
[root@nginxServer conf.d]# pwd
/etc/nginx/conf.d
[root@nginxServer conf.d]# vim vhosts.conf
server {
    listen       80;
    server_name  www1.nginx.com;
    location / {
        root   /data/web/nginx/www1;
        index  index.html index.htm;
        auth_basic "Auth your name";
        auth_basic_user_file /etc/nginx/.ngxpasswd;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /data/web/nginx/www1;
    }
}

# htpasswd命令由httpd-tools所提供
[root@nginxServer conf.d]# yum install -y httpd-tools
[root@nginxServer conf.d]# htpasswd -c -b -m /etc/nginx/.ngxpasswd user1 user1
Adding password for user user1
[root@nginxServer conf.d]# htpasswd -b -m /etc/nginx/.ngxpasswd user2 user2
Adding password for user user2

說明:
 -c表示建立密碼檔案,只能為第一個使用者使用該選項,否則後面使用會覆蓋前面已經建立過的
 -b選項是表示batch模式,不用互動輸入密碼
 -m表示強制使用md5

[root@nginxServer conf.d]# cat /etc/nginx/.ngxpasswd
user1:$apr1$MaM8PAS.$FjeZesqyESHjUyUarao.q/
user2:$apr1$3Tvnt.Kp$ysOph6mgMyTHaqgLy6fsH1

[root@nginxServer conf.d]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginxServer conf.d]# nginx -s reload
  •  檢測測試結果。

  WIN10的hosts檔案新增解析:將'172.16.70.37 www1.nginx.com www2.nginx.com www3.nginx.com'新增到C:\Windows\System32\drivers\etc\hosts

 

Nginx訪問日誌輪詢切割:

  • 預設情況下Nginx會把所有的訪問日誌生成到一個指定的訪問日誌檔案access.log裡,但這樣一來,時間長了就會導致日誌個頭很大,不利於日誌的分析和處理,因此,有必要對Nginx日誌,按天或按小時進行切割,使其分成不同的檔案儲存。
[root@nginxServer nginx]# pwd
/etc/nginx

[root@nginxServer nginx]# cat cut_nginx_log.sh
#!/bin/bash
#日誌切割指令碼可掛定時任務,每天00點整執行

Dateformat=`date +%Y%m%d`
Nginxlogdir="/var/log/nginx"
Logname="access"

[ -d $Nginxlogdir ] && cd $Nginxlogdir || exit 1
[ -f ${Logname}.log ] || exit 1
/usr/bin/mv ${Logname}.log ${Logname}.log_${Dateformat}
/usr/sbin/nginx -s reload

# 新增計劃任務
[root@nginxServer nginx]# cat /etc/cron.d/cut_nginx_log.cron
#cut nginx access log
00 00 * * *    root /usr/bin/bash /etc/nginx/cut_nginx_log.sh >/dev/null 2>&

 

相關文章