Nginx的踩坑日記

Koali發表於2019-03-22

前言

最近有一個前後端分離的專案,前端部署在Nginx,由於接觸過的web伺服器只有ibm的ws,還有weblogic等,還沒有在生產中使用過Nginx來做web伺服器,所以踩了不少的坑,以此記錄,願餘生不用在Nginx踩坑~

Nginx的安裝

Nginx的安裝有一個坑,那就是最好安裝最新的穩定版,因為低版本坑爹,一開始我們安裝了一個低版本的,然後配置了HTTPS(跟著阿里雲提供的ssl配置,所以配置錯誤的機率不大),但是一直訪問不了HTTPS,後面搞了好久換了最新的穩定版本,然後才配置成功。安裝的過程如下:

1.安裝PCRE依賴

yum install -y pcre pcre-devel
複製程式碼

2.安裝Zlib的依賴

yum install -y zlib zlib-devel
複製程式碼

3.安裝c++的依賴

yum install -y gcc-c++
複製程式碼

4.安裝ssl的依賴(如果需要配置SSL證照的需要

yum install -y openssl openssl-devel
複製程式碼

5.下載Nginx(最好下載最新的穩定版)

wget -c https://nginx.org/download/nginx-1.10.2.tar.gz
複製程式碼

6.解壓並且使用預設的配置

tar -zvxf nginx-1.10.2.tar.gz
cd nginx-1.10.2.tar.gz
./configure
複製程式碼

7.編譯還有安裝

make
make install
複製程式碼

8. 檢視安裝的路徑,然後啟動

whereis nginx 
nginx -t //檢查預設的配置檔案,可以得知配置檔案的路徑
nginx -c  /etc/nginx/nginx.conf  //第二步的配置檔案路徑
複製程式碼

參考文章

Nginx的反向代理

1.Nginx的反向代理

結合場景,假設我現在想要把**/api**下的所有請求代理到我的後端介面(eg:www.mydomain.com/api/xxxxx 轉發到 www.mydomain.com:8080/xxxxx),那麼需要向配置檔案配置

location /api/ {
    proxy_pass http://www.mydomain.com:8080/;
}
複製程式碼

此處有個地方需要注意,Nginx的配置是自上而下,也就是說如果你之前先配置瞭如下面

location / {
    root  /www/resource/;
    index index.html index.htm;
}
location /api/ {
    proxy_pass http://www.mydomain.com:8080/;
}
複製程式碼

這樣子是不會生效的,因為滿足**/api/的匹配規則也是滿足/** 的匹配規則,而且Nginx是自上而下配置,所以全部都被代理轉發到/匹配規則裡面了。

更多的反向代理規則如下:

location  = / {
  # 精確匹配 / ,主機名後面不能帶任何字串
}

location  / {
  # 因為所有的地址都以 / 開頭,所以這條規則將匹配到所有請求
  # 但是正則和最長字串會優先匹配
}

location /documents/ {
  # 匹配任何以 /documents/ 開頭的地址,匹配符合以後,還要繼續往下搜尋
  # 只有後面的正規表示式沒有匹配到時,這一條才會採用這一條
}

location ~ /documents/Abc {
  # 匹配任何以 /documents/ 開頭的地址,匹配符合以後,還要繼續往下搜尋
  # 只有後面的正規表示式沒有匹配到時,這一條才會採用這一條
}

location ^~ /images/ {
  # 匹配任何以 /images/ 開頭的地址,匹配符合以後,停止往下搜尋正則,採用這一條。
}

location ~* \.(gif|jpg|jpeg)$ {
  # 匹配所有以 gif,jpg或jpeg 結尾的請求
  # 然而,所有請求 /images/ 下的圖片會被 config D 處理,因為 ^~ 到達不了這一條正則
}

location /images/ {
  # 字元匹配到 /images/,繼續往下,會發現 ^~ 存在
}

location /images/abc {
  # 最長字元匹配到 /images/abc,繼續往下,會發現 ^~ 存在
  # F與G的放置順序是沒有關係的
}

location ~ /images/abc/ {
  # 只有去掉 config D 才有效:先最長匹配 config G 開頭的地址,繼續往下搜尋,匹配到這一條正則,採用
}
複製程式碼

2.Nginx獲取引數

結合場景,假設我現在想要把/api下的請求引數獲取出來,然後轉發(eg:www.mydomain.com/api?img=htt…),需要修改配置如下:

location /api/ {
    proxy_pass $arg_img; # $arg_引數名:可以獲取引數內容
}
複製程式碼

這裡有個小坑,如果不同域的話,需要在配置檔案寫上

server {
    listen 80;
    resovler 8.8.8.8;
}
複製程式碼

resovler相當於Nginx幫你解析ip,然後去代理訪問,如果不設定resovler 8.8.8.8的話,Nginx會報502.

3.Nginx設定Cookie

結合場景,假設我現在想要把/api 下的請求引數獲取出來,並且設定到Cookie裡(eg.www.mydomain.com/api?cookie=…)

location /api/ {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    add_header 'Set-Cookie' 'mycookie=$arg_cookie';
    add_header 'domain' '.mydomain.com'; 
    proxy_pass https://www.mydomain.com/;
}
複製程式碼

前兩個引數設定了使用者的訪問的IP,設定Cookie,其中涉及到一個問題,如果後臺的Set-Cookie,瀏覽器是不會儲存Cookie,因為不同域,瀏覽器會丟掉這個Cookie,假如是用Java寫Set-Cookie的話

Cookie cookie = new Cookie("cookie","cookie");
cookie.setPath("/");
cookie.setDomain(".domain.com");
request.addCookie(cookie);
複製程式碼

也是需要設定域,區分一下域和域名(.mydomain.com是域,www,mydomain.com則是域名),域名可以DNS解析為IP。

所以Nginx再設定Cookie的時候需要注意一點,就是還要

add_header 'domain' 'xxxx';
複製程式碼

4.Nginx的負載均衡

Nginx還有一個比較出名的用處就是負載均衡,其中負載均衡策略有6種:權重(weight),ip_hash(依據ip分配方式),least_conn(最少連線數),fair(根據響應時間),url_hash(根據URL分配)。下面以權重的負載均衡策略配置為例:

//假設現在在 https://www.mydomain.com:8090 還有https://www.mydomain.com:8091 部署兩個後臺
upstream tomcat_pool 
    {
    server https://www.mydomain.com:8090 weight=4 max_fails=2 fail_timeout=30s;
      server https://www.mydomain.com:8091 weight=4 max_fails=2 fail_timeout=30s;
    }
複製程式碼

其中weight代表權重,權重較大者,被分配到的機會比較大,max_fails是指最大失敗次數,如果達到失敗次數,那麼該節點會被標記為不可用,等待fail_timeout為時間週期到,再去請求~

Nginx的優化

1.worker_processes

Nginx的程式數worker_processes,按照CPU的數目來寫,一般是CPU的倍數。

2.I/O模型

配置一下Nginx的I/O模型,在Linux 2.6版本之後都支援了epoll。如果系統不支援epoll的話,Nginx會預設選擇Select 或者 Poll的I/O模型,好像window就是Select模型。

events{
    use epoll;
}
複製程式碼

3.worker_rlimit_nofile

worker_rlimit_nofile一般跟系統的檔案運算元相同(ulimit -n)。擴充一下如何獲取優化系統的檔案運算元。

首先修改程式最大的檔案控制程式碼

ulimit -n 1048576
複製程式碼

修改單個程式可分配的最大檔案數

echo 2097152 > /proc/sys/fs/nr_open
複製程式碼

寫進配置檔案/etc/security/limits.conf

*   soft nofile  1048576
*   hard nofile 1048576
*   soft nproc unlimited
root soft nproc unlimited
複製程式碼

最後清掉一下舊的檔案

rm -rf /etc/security/limits.d/*
複製程式碼

然後再修改/etc/sysctl.conf檔案

fs.nr_open=2097152
fs.file-max = 1048576
複製程式碼

fs.nr_open 是指單個程式可分配的最大檔案運算元,file-max是指最大的檔案控制程式碼,然後使配置檔案生效。

systcl -p
複製程式碼

4.worker_connections

Nginx的最大連線數,理論上可以達到Nginx的程式數worker_processes * Ngin的最大連線數 worker_connections;

worker_connections 102400;
複製程式碼

5.keepalive_timeout

keepalive 的超時時間。

keepalive_timeout 60;
複製程式碼

相關文章