前言
最近有一個前後端分離的專案,前端部署在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;
複製程式碼