Nginx高級特性實操

導讀

  nginx從入門到精通,點我直達

下載nginx與安裝

點我直達

 

安裝依賴

yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel

上傳nginx至服務器中

上傳至:/usr/local/software/service

解壓:
cd /usr/local/software/service/
tar -zxvf nginx-1.20.1.tar.gz

編譯
cd /usr/local/software/service/nginx-1.20.1
./configure
make && make install

默認安裝路徑
/usr/local/nginx

啟動nginx
cd /usr/local/nginx/sbin
./nginx

訪問

  ip:80

購買阿里雲域名

點我直達

nginx目錄

核心目錄

  默認安裝位置:/usr/local/nginx

conf  #所有配置文件目錄
  nginx.conf    #默認的主要的配置文件
  nginx.conf.default  #默認模板
​
html  # 這是編譯安裝時Nginx的默認站點目錄
  50x.html #錯誤頁面
  index.html #默認首頁
  
logs  # nginx默認的日誌路徑,包括錯誤日誌及訪問日誌
  error.log  #錯誤日誌
  nginx.pid  #nginx啟動後的進程id
  access.log #nginx訪問日誌
​
sbin  #nginx命令的目錄
  nginx  #啟動命令

常用命令

./nginx  #默認配置文件啟動
​
./nginx -s reload #重啟,加載默認配置文件
​
./nginx -c /usr/local/nginx/conf/nginx.conf #啟動指定某個配置文件
​
./nginx -s stop #停止
​
#關閉進程,nginx有master process 和worker process,關閉master即可
ps -ef | grep "nginx" 
kill -9 PID 

nginx核心配置文件

nginx.conf

#user  nobody; # 指定nginx worker進程運行以及用戶組
worker_processes  1;

#error_log  logs/error.log; # 錯誤日誌的存放路徑,和錯誤日誌
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid; # 進程PID存放路徑


events {
    use epoll;
    # 作為反向代理來說,最大並發數量應該是worker_connections * worker_processes/2。因為反向代理服務器,每個並發會建立與客戶端的連接和後端服務的連接,會佔用2個連接
    worker_connections  1024;
}


http {
    include       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  logs/access.log  main;

    # 是否開啟高效傳輸模式 on開啟 off關閉
    sendfile        on;

    # 減少網絡報文段的數量
    #tcp_nopush     on;

    #keepalive_timeout  0;

    # 客戶端連接保持活動的超時時間,超過這個時間之後,服務器會關閉該連接
    keepalive_timeout  65;

    #gzip  on;

    # 虛擬主機配置
    server {
        listen       80;    # 虛擬主機的服務端口號
        server_name  localhost; # 用來指定IP地址或域名,多個域名之間

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        # url地址匹配
        location / {
            root   html;    # 服務默認啟動路徑
            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;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   //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;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

accessLog日誌挖掘

access.log日誌用處

  • 統計站點訪問ip來源、某個時間段的訪問頻率
  • 查看訪問最頻的頁面、Http響應狀態碼、接口性能
  • 接口秒級訪問量、分鐘訪問量、小時和天訪問量

默認配置

  nginx.conf文件中的配置!!!

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

示例

223.94.83.67 - - [31/Oct/2021:12:12:13 +0000] "GET /prod-api/admin/v1/menu/get_routers HTTP/1.1" 200 1442 "//47.11.11.11:9119/login?redirect=%2Findex" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36"

解釋

  • $remote_addr :對應的是真實日誌里的223.94.83.67,即客戶端ip
  • $remote_user :對應的是第二個中杠” – “,沒有遠程用戶,所以用” – “填充
  • [$time_local] :對應的是[31/Oct/2021:12:12:13 +0000]
  • $request :對應的是”GET /prod-api/admin/v1/menu/get_routers HTTP/1.1″
  • $status :對應的是200狀態碼,200表示正常訪問
  • $body_bytes_sent :對應的是1442位元組,即響應body的大小
  • $http_referer :對應的是”//47.11.11.11:9119/login?redirect=%2Findex”,若是直接打開或域名瀏覽時,referer就會沒有值,為” – “
  • $http_user_agent :對應的是”Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36″
  • $http_x_forwarded_for :對應的是” – “或者空

自定義日誌統計接口性能

日誌格式添加:$request_time

從接受用戶請求的第一個位元組到發送完響應數據的時間,即包括接收請求數據時間、程序響應時間、輸出響應數據時間

$upstream_response_time:指從Nginx向後端建立連接開始到接受完數據然後關閉連接為止的時間

$request_time一般會比upstream_response_time大,因為用戶網絡較差,或者傳遞數據較大時,前者會耗時大很多

 

統計耗時接口,列出傳輸時間超過2秒的接口,顯示前5條

cat time_temp.log|awk '($NF > 2){print $7}'|sort -n|uniq -c|sort -nr|head -5
​
備註:$NF 表示最後一列, awk '{print $NF}'

Nginx站點統計訪問量、高頻URL 

查看訪問最頻繁的前100個IP

awk '{print $1}' access_temp.log | sort -n |uniq -c | sort -rn | head -n 100

統計訪問最多的url前20名

cat access_temp.log |awk '{print $7}'| sort|uniq -c| sort -rn| head -20 | more
  • awk 是文本處理工具,默認按照空格切分,$N 是第切割後第N個,從1開始
  • sort命令用於將文本文件內容加以排序,-n 按照數值排,-r 按照倒序來排
  • 案例的sort -n 是按照第一列的數值大小進行排序,從小到大,倒序就是 sort -rn
  • uniq 去除重複出現的行列, -c 在每列旁邊顯示該行重複出現的次數

nginx負載均衡策略

環境準備

  • 安裝jdk,點我直達
  • 準備2個jar包springboot項目
    • demo1.jar 端口號:8888
    • demo2.jar 端口號:9999
  • 守護方式啟動2個jar包:nohup java -jar demoX.jar &

 

測試接口

nginx配置負載均衡策略

  編輯nginx.conf

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       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  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;
   upstream chenyanbin {
    server 47.116.143.16:8888 weight=1;
    server 47.116.143.16:9999 weight=1;
   }

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }
    
    location /api/ {
        proxy_pass //chenyanbin;
        proxy_set_header Host $host:$server_port;
       }

    }
}

  • 負載均衡策略
    • 節點輪詢(默認)
      • 簡介:每個請求按順序分配到不同的後端服務器
      • 場景:會造成可靠性低和負載分配不均衡,適合靜態文件服務器
    • weight 權重配置
      • 簡介:weight和訪問比率成正比,數字越大,分配得到的流量越高
      • 場景:服務器性能差異大的情況使用
    • ip_hash(固定分發)
      • 簡介:根據請求按訪問ip的hash結果分配,這樣每個用戶就可以固定訪問一個後端服務器
      • 場景:服務器業務分區、業務緩存、Session需要單點的情況

ip_hash示例

   upstream chenyanbin {
      ip_hash;
      server 47.116.143.16:8888 weight=1;
      server 47.116.143.16:9999 weight=1;
   }
  • 標記節點狀態
    • down 表示當前的server暫時不參與負載
    • backup 其它所有的非backup機器down的時候,會請求backup機器,這台機器壓力會最輕,配置也會相對低(三市五中心機房,異地多活架構!!!!)

標記節點狀態示例

   upstream chenyanbin {
      server 47.116.143.16:8888 weight=1 down;
      server 47.116.143.16:9999 weight=1 backup;
   }

重啟nginx

cd /usr/local/nginx/sbin/
./nginx -s reload

演示

Nginx可用性探測

如果某個應用掛了,請求不應該繼續分發過去

  • max_fails 允許請求失敗的次數,默認為1.當超過最大次數時就不會請求

  • fail_timeout : max_fails次失敗後,暫停的時間,默認:fail_timeout為10s

  • 可以通過指令proxy_next_upstream來配置什麼是失敗的嘗試 
   upstream chenyanbin {
      server 47.116.143.16:8888 max_fails=2 fail_timeout=60s;
      server 47.116.143.16:9999 max_fails=2 fail_timeout=60s;
   }


    location /api/ {
        proxy_pass //chenyanbin;
        proxy_set_header Host $host:$server_port;
        proxy_next_upstream error timeout http_500 http_503 http_404;
    }

  備註:連續2次失敗,在60秒內,nginx不會再將請求分發過去,第61秒時,會重試該節點是否可用!!!

nginx經典應用

nginx自定義全局異常json兜底數據

nginx.conf配置

    location /api/ {
        proxy_pass //chenyanbin/;
        proxy_set_header Host $host:$server_port;
        proxy_next_upstream error timeout http_500 http_503 http_404;
        # 存放用戶的真實ip
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        #開啟錯誤攔截配置,一定要開啟
        proxy_intercept_errors on;
    }


error_page   404 500 502 503 504  =200  /default_api;
        location = /default_api {
            default_type application/json;
            return 200 '{"code":"-1","msg":"invoke fail, not found "}';
        }

 

演示

Nginx封禁惡意IP

1、cd /usr/local/nginx/conf

2、touch blacklist.conf

3、vi blacklist.conf
# 寫入如下內容
deny 101.93.218.231;

4、vi nginx.conf

# 全局其效果,放到http{}代碼塊中;針對某個網站起效果,放到server{}代碼塊中

http{
    #......
    include blacklist.conf;
}


server{
    #....
    include blacklist.conf;
}

  注意:從access.log日誌中,查看訪問ip列表(/usr/local/nginx/logs)

Nginx配置瀏覽器跨域

修改nginx.conf

location /api/ {
                proxy_pass //chenyanbin/;
                proxy_set_header Host $host:$server_port;
                proxy_next_upstream error timeout http_500 http_503 http_404;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_intercept_errors on;


                # 配置跨域
                add_header 'Access-Control-Allow-Origin' $http_origin;
                add_header 'Access-Control-Allow-Credentials' 'true';
                add_header 'Access-Control-Allow-Headers' 'DNT,web-token,app-token,Authorization,Accept,Origin,Keep-Alive,User-Agent,X-Mx-ReqToken,X-Data-Type,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
                add_header Access-Control-Allow-Methods 'GET,POST,OPTIONS';

                if ($request_method = 'OPTIONS') {
                        add_header 'Access-Control-Max-Age' 1728000;
                        add_header 'Content-Type' 'text/plain; charset=utf-8';
                        add_header 'Content-Length' 0;
                        return 200;
                }
        }
    

Nginx配置websocket反向代理

    location /api/ {
        proxy_pass //chenyanbin/;
        proxy_set_header Host $host:$server_port;
        proxy_read_timeout 300s; //websocket空閑保持時長
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_http_version 1.1;
   
        # 添加下面2句話
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;



    }

Nginx壓縮配置(重要)

  對文本、js和css文件等進行壓縮,一般壓縮後的大小是原始大小的25% 

nginx.conf

    #開啟gzip,減少我們發送的數據量
    gzip on;
    gzip_min_length 1k;

    #4個單位為16k的內存作為壓縮結果流緩存
    gzip_buffers 4 16k;

    #gzip壓縮比,可在1~9中設置,1壓縮比最小,速度最快,9壓縮比最大,速度最慢,消耗CPU
    gzip_comp_level 4;

    #壓縮的類型
    gzip_types application/javascript text/plain text/css application/json application/xml    text/javascript; 

    #給代理服務器用的,有的瀏覽器支持壓縮,有的不支持,所以避免浪費不支持的也壓縮,所以根據客戶端的HTTP頭來判斷,是否需要壓縮
    gzip_vary on;

    #禁用IE6以下的gzip壓縮,IE某些版本對gzip的壓縮支持很不好
    gzip_disable "MSIE [1-6].";

    location /static {
          alias /usr/local/software/static;
    }

 

Tags: