nginx常用配置學習

一:概念

nginx用來作爲網關暴露到外面,裏面負載均衡其他的應用服務器tomcat,當然,靜態資源,js,圖片,之類的可以直接放到nginx服務器,來加快訪問速度;

和haproxy對比

1.nginx可以支持幾萬的併發連接數,在性能方面應該和haproxy都差不多,

2.使用起來簡單一點,主要是通過配置文件來使用相應的模塊

3.沒有監控頁面(這裏說的nginx只說免費版本),haproxy有

4.haproxy完全免費,可以拿到4,7層數據來定製我們想要的任何功能,不過需要深入學習;nginx的話如果現有的模塊不支持某個功能,要不使用商業版本(如果支持),要不自己開發模塊來支持,比較困難

二:版本

1.http://nginx.org/ 免費版本 就是我們常說的nginx open source

2.https://www.nginx.com/ 商業版本,全稱nginx plus

三:安裝

 兩種安裝方式

a.使用yum install直接安裝編譯好的版本,參考http://nginx.org/en/linux_packages.html#RHEL-CentOS

b.自己編譯源碼,好處就是可以指定編譯的模塊

考慮到以後有可能會增加模塊,我們使用第二種方法安裝

1.安裝編譯需要的工具包

[root@deappa17 soft]# yum -y install make zlib zlib-devel gcc-c++ libtool  openssl openssl-devel

2.安裝PCRE讓Nginx 支持 Rewrite 功能

[root@deappa17 soft]# wget https://nchc.dl.sourceforge.net/project/pcre/pcre/8.43/pcre-8.43.tar.gz
[root@deappa17 soft]# tar zxvf pcre-8.43.tar.gz
[root@deappa17 soft]# cd pcre-8.43
[root@deappa17 pcre-8.43]# ./configure
[root@deappa17 pcre-8.43]# make && make install
[root@deappa17 pcre-8.43]# pcre-config --version
8.43

3.安裝nginx

[root@deappa17 soft]# wget http://nginx.org/download/nginx-1.16.1.tar.gz
[root@deappa17 soft]# tar xzvf nginx-1.16.1.tar.gz
[root@deappa17 soft]# cd nginx-1.16.1
[root@deappa17 nginx-1.16.1]# ./configure --prefix=/usr/local/webserver/nginx --with-http_stub_status_module --with-http_ssl_module
[root@deappa17 nginx-1.16.1]# make
[root@deappa17 nginx-1.16.1]# make install
[root@deappa17 nginx-1.16.1]# /usr/local/webserver/nginx/sbin/nginx -v
nginx version: nginx/1.16.1

四:常用操作

1.啓動nginx

[root@deappa17 nginx-1.16.1]# /usr/local/webserver/nginx/sbin/nginx 

2.檢查配置文件的正確性

用於已經啓動,調整了配置文件,重新加載之前使用

/usr/local/webserver/nginx/sbin/nginx -t

3.其他常用命令

/usr/local/webserver/nginx/sbin/nginx -s reload            # 重新載入配置文件,如果配置文件中配置的目錄不存在,則不報錯,但不生效,需要看日誌來確認是否重新載入是否成功
/usr/local/webserver/nginx/sbin/nginx -s reopen            # 重新打開日誌文件,並不是重啓nginx
/usr/local/webserver/nginx/sbin/nginx -s stop              # 停止 Nginx
/usr/local/webserver/nginx/sbin/nginx -s quit               # 平緩停止 Nginx

五:常用配置

這裏不羅列所有的配置,如果需要可以參考nginx官網http://nginx.org/en/docs/,模塊內部有詳細全面的指令說明,可用內部變量及例子

1.配置成web服務器

http {
    server {
        listen 127.0.0.1:8080;        
    }

    server {
        listen      80;
        server_name example.org www.example.org;
    }

    server {
        listen 80 default_server;
        location /some/path/ {
            #...
        }

        location ~ \.html? {
            #...
        }

        location /images/ {
            root /data;
        }

        location / {
            proxy_pass http://www.example.com;
        }
        // 可以使用內置變量$remote_addr,
        // 參考每個模塊最下面的變量說明,例如ngx_http_core_module模塊內部可以使用的內置變量
        //https://nginx.org/en/docs/http/ngx_http_core_module.html?&_ga=2.205840795.900571110.1585708043-1368246722.1570772956#variables
        
        // 返回特定的響應碼
        location /wrong/url {
            return 404;
        }
        location /permanently/moved/url {
            return 301 http://www.example.com/moved/here;
        }
        
        // 重寫http相應的內容
        location / {
            sub_filter      /blog/ /blog-staging/;
            sub_filter_once off;
        }
        location / {
            sub_filter     'href="http://127.0.0.1:8080/'    'href="https://$host/';
            sub_filter     'img src="http://127.0.0.1:8080/' 'img src="https://$host/';
            sub_filter_once on;
        }

        // 處理錯誤
        location /old/path.html {
            error_page 404 /404.html;
        }
        location /old/path2.html {
            error_page 404 =301 http:/example.com/new/path.html;
        }
        // 出現404轉到後端
        location /images/ {                
            root /data/www;     
            open_file_cache_errors off;
            error_page 404 = /fetch$uri;
        }
        location /fetch/ {
            proxy_pass http://backend/;
        }
           

    }
}

location匹配優先級

首先說明:匹配字符串有兩種,正則表達式和普通字符串(非正則表達式)

1)遇到=號,直接返回,優先級最高

2)找到最長匹配的普通字符串,如果前面有^~則直接返回

3)找到匹配的正則表達式,直接返回

4)沒有找到匹配的正則表達式,則使用步驟2匹配到的最長普通字符串匹配

2.提供靜態資源

server {
    root /www/data; // 資源位置

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

    location /images/ {
        autoindex on; // 返回列表目錄頁面
    }

    location /images2/ {
        try_files $uri /images/default.gif; // 如果請求資源不存在,則返回默認的
    }

    location /images3/ {
        try_files $uri $uri/ $uri.html =404; // 如果請求資源不存在,則返回404
    }

    location /images4/ {
        try_files $uri $uri/ @backend; // 如果請求資源不存在,則定向到下面backend
    }

    location ~ \.(mp3|mp4) {
        root /www/media;
    }    

    location @backend {
        proxy_pass http://backend.example.com;
    }
    // 優化性能相關
    location /mp3 {
        //默認情況下,NGINX處理文件傳輸本身,並在發送之前將文件複製到緩衝區中。啓用
        //sendfile指令消除了將數據複製到緩衝區的步驟,並允許將數據從一個文件描述符直接
        //複製到另一個文件描述符。或者,爲了防止一個快速連接完全佔用工作進程,可以使用                
        //sendfile_max_chunk指令來限制單個sendfile()調用中傳輸的數據量(在本例中爲1 MB):
        sendfile           on;
        sendfile_max_chunk 1m;
        tcp_nopush on;
        tcp_nodelay       on;
        keepalive_timeout 65;
    }
}

3.反向代理

location /some/path/ {
    proxy_pass http://www.example.com/link/;
}

location ~ \.php {
    proxy_pass http://127.0.0.1:8000;
}
 // 設置header
location /some/path/ {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_pass http://localhost:8000;
}
// 阻止傳遞header
location /some/path/ {
    proxy_set_header Accept-Encoding "";
    proxy_pass http://localhost:8000;
}
// 配置緩存大小,默認已經啓動
location /some/path/ {
    proxy_buffers 16 4k;
    proxy_buffer_size 2k;
    proxy_pass http://localhost:8000;
}
// 關閉緩存
location /some/path/ {
    proxy_buffering off;
    proxy_pass http://localhost:8000;
}
// 綁定sorceip,比如有多網卡,或者其他的需求
location /app1/ {
    proxy_bind 127.0.0.1;
    proxy_pass http://example.com/app1/;
}

location /app2/ {
    proxy_bind 127.0.0.2;
    proxy_pass http://example.com/app2/;
}

location /app3/ {
    proxy_bind $server_addr;
    proxy_pass http://example.com/app3/;
}

4.http負載均衡

http {
    upstream backend {
        # no load balancing method is specified for Round Robin
        #least_conn; 
        #ip_hash;   
        #Random 還可以加其他的參數,請參考官網
        #https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/
     
        
        server backend1.example.com;
        server backend2.example.com;
        server 192.0.0.1 backup;
        # 如果一個服務器需要暫時從負載平衡循環中移除,可以使用down參數來標記它,
        # 以保持當前客戶端IP地址的散列。本服務器處理的請求被自動發送到組中的下一個服務器
        server backend3.example.com down;
        # 30秒內3次失敗,則這臺服務器標識爲不可用30秒(30秒是否又可用了?)
        server backend2.example.com max_fails=3 fail_timeout=30s;
        #設置服務器將其權重從0恢復到一個標稱值的時間,當不健康的服務器變得健康時,
        #或服務器在一段時間後變得可用時(服務器被認爲不可用)。默認值爲0,即禁用慢啓動。
        server backend1.example.com slow_start=30s;
    }
    
    server {
        location / {
            proxy_pass http://backend;
        }
    }
}

5.TCP負載均衡

stream {
    # ...
    server {
        listen     127.0.0.1:12345;
        proxy_pass backend.example.com:12345;
        proxy_bind 127.0.0.1:12345;
    }


     upstream stream_backend {
        server backend1.example.com:12345;
        server backend2.example.com:12345;
        server backend3.example.com:12346;
        # ...
    }
}

6.限流

1)限制併發連接數

http {
    limit_conn_zone $server_name zone=servers:10m;

    server {
        limit_conn servers 1000;
    }
}

2)限制訪問速率

http {
    #...

    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

    server {
        #...

        location /search/ {
            # 每秒處理一個請求,超出的直接返回503
            limit_req zone=one;
        }
        
        location /search2/ {
            # 每秒處理一個請求,超出的進入桶中延遲處理(以指定的速率處理,客戶端會卡着),如果桶滿了,則直接返回503
            limit_req zone=one burst=5;
        }

        location /search3/ {
            # 每秒處理一個請求,超出的進入桶中立即處理,好像桶中有個計時器,每進入一個請求加1,每過一秒
            # 減1,如果計時器=5,則此時新來的請求直接返回503,此種配置可以應對突發的情況並且不延遲,突發的緩衝是5
            # 個人認爲此種方式比較完美
            limit_req zone=one burst=5 nodelay;
        }
    }
}

3)限制下載帶寬


http {
    limit_conn_zone $binary_remote_address zone=addr:10m

    server {
        root /www/data;
        // 正常可以打開5個連接,現代瀏覽器會直接打開3個連接
        limit_conn addr 5;

        location / {
        }

        location /download/ {
            #限制打開1個連接
            limit_conn       addr 1;
            #1M後開始限制,可以不要此參數,直接限制
            limit_rate_after 1m;
            limit_rate       50k;
        }
    }
}

7.緩存

http {
    
    # 定義緩存的名稱,單個緩存內容的最大size,總緩存的最大size,和緩存的目錄(必須存在)
    proxy_cache_path /data/nginx/cache keys_zone=mycache:10m max_size=10g;
    # 定義一個變量$purge_method,他的值有$request_method決定
    map $request_method $purge_method {
        PURGE   1;
        default 0;
    }
    # 創建變量,其值依賴於客戶端IP地址
    geo $purge_allowed {
       default         0;  # 默認不允許
       192.168.100.17  1;  # 本地允許
       192.168.0.0/24  1;  # 同一個網段允許
    }

    map $request_method $purge_method2 {
       PURGE   $purge_allowed;
       default 0;
    }
    server {
        # 使用緩存
        proxy_cache mycache;
        # 定義緩存的key
        proxy_cache_key "$host$request_uri$cookie_user";
        # 被請求多少次才被緩存,默認是1
        proxy_cache_min_uses 5;
        # 定義各種響應碼的緩存時間(測試過程發現如果不定義此參數緩存不生效)
        proxy_cache_valid 200 302 10m;
        proxy_cache_valid 404      1m;
        # 僅僅200, 301, and 302會被緩存
        proxy_cache_valid 5m;
        # 所有響應碼會被緩存
        proxy_cache_valid any      1m;
        # 指定忽略響應頭的內容,內容是否被緩存,還和響應頭中的內容有關,比如響應頭中有Set-Cookie字段
        # 則響應的內容不會被緩存
        proxy_ignore_headers Set-Cookie Cache-Control;
        # 如果後面的幾個參數,任何一個參數值不爲空或者不等0,nginx就不會查找緩存,直接進行代理轉發
        proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;
        # 定義不需要緩存的情況,參數使用和proxy_cache_bypass一樣
        proxy_no_cache $http_pragma $http_authorization;
        # 清除緩存,如果收到請求method=PURGE ,則清除指定的緩存,如果路徑/*結尾,則清除匹配的所有緩存    
        # 並不會真正從磁盤清除,有三種條件可以真正從磁盤清除,如下
        # proxy_cache_path使用purger=on或者inactive參數,或者下次訪問此緩存時
        proxy_cache_purge $purge_method;
        # 除了清除緩存功能,可以限制訪問此清除功能的客戶端ip
        proxy_cache_purge $purge_method2;

        # 如果緩存的文件比較大,比如視頻文件,可以切片緩存,具體可以參考
        # https://docs.nginx.com/nginx/admin-guide/content-cache/content-caching/
        


        location / {
            proxy_pass http://localhost:8000;
        }
    }
}

六:常見問題

1.上傳大文件失敗,小文件可以

  • client_body_buffer_size 配置請求體緩存區大小
  • client_body_temp_path 設置臨時文件存放路徑,只有當上傳的請求體超出緩存區大小時,纔會寫到臨時文件中
  • client_max_body_size 設置上傳文件的最大值

通過設置client_max_body_size 100m解決掉

2.防止惡意攻擊某個地址,比如發短信

location ~ /account(/.*)  
{
    if ($http_referer ~  "https://www.xxxxxxxx.net/account/sendPhoneCode") {
       #如果匹配就直接返回200,返回404,也行啊,自己定。給可愛的攻擊者,不傳給後端web
       return 200;        
    }
    #不匹配,傳給後端web
    proxy_pass  http://web_group;
}

 

參考網站:

https://docs.nginx.com/

http://nginx.org/en/docs/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章