最近有一個先後端分離的項目,前端部署在Nginx,因爲接觸過的web服務器只有ibm的ws,還有weblogic等,尚未在生產中使用過Nginx來作web服務器,因此踩了很多的坑,以此記錄,願餘生不用在Nginx踩坑~html
Nginx的安裝有一個坑,那就是最好安裝最新的穩定版,由於低版本坑爹,一開始咱們安裝了一個低版本的,而後配置了HTTPS(跟着阿里雲提供的ssl配置,因此配置錯誤的概率不大),可是一直訪問不了HTTPS,後面搞了很久換了最新的穩定版本,而後才配置成功。安裝的過程以下:前端
yum install -y pcre pcre-devel
複製代碼
yum install -y zlib zlib-devel
複製代碼
yum install -y gcc-c++
複製代碼
yum install -y openssl openssl-devel
複製代碼
wget -c https://nginx.org/download/nginx-1.10.2.tar.gz
複製代碼
tar -zvxf nginx-1.10.2.tar.gz
cd nginx-1.10.2.tar.gz
./configure
複製代碼
make
make install
複製代碼
whereis nginx
nginx -t //檢查默認的配置文件,能夠得知配置文件的路徑
nginx -c /etc/nginx/nginx.conf //第二步的配置文件路徑
複製代碼
參考文章java
結合場景,假設我如今想要把**/api**下的全部請求代理到個人後端接口(eg:www.mydomain.com/api/xxxxx 轉發到 www.mydomain.com:8080/xxxxx),那麼須要向配置文件配置nginx
location /api/ {
proxy_pass http://www.mydomain.com:8080/;
}
複製代碼
此處有個地方須要注意,Nginx的配置是自上而下,也就是說若是你以前先配置了以下面c++
location / {
root /www/resource/;
index index.html index.htm;
}
location /api/ {
proxy_pass http://www.mydomain.com:8080/;
}
複製代碼
這樣子是不會生效的,由於知足**/api/的匹配規則也是知足/** 的匹配規則,並且Nginx是自上而下配置,因此所有都被代理轉發到/匹配規則裏面了。web
更多的反向代理規則以下:正則表達式
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 開頭的地址,繼續往下搜索,匹配到這一條正則,採用
}
複製代碼
結合場景,假設我如今想要把/api下的請求參數獲取出來,而後轉發(eg:www.mydomain.com/api?img=htt…),須要修改配置以下:後端
location /api/ {
proxy_pass $arg_img; # $arg_參數名:能夠獲取參數內容
}
複製代碼
這裏有個小坑,若是不一樣域的話,須要在配置文件寫上api
server {
listen 80;
resovler 8.8.8.8;
}
複製代碼
resovler至關於Nginx幫你解析ip,而後去代理訪問,若是不設置resovler 8.8.8.8的話,Nginx會報502.瀏覽器
結合場景,假設我如今想要把/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';
複製代碼
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的進程數worker_processes,按照CPU的數目來寫,通常是CPU的倍數。
配置一下Nginx的I/O模型,在Linux 2.6版本以後都支持了epoll。若是系統不支持epoll的話,Nginx會默認選擇Select 或者 Poll的I/O模型,好像window就是Select模型。
events{
use epoll;
}
複製代碼
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
複製代碼
Nginx的最大鏈接數,理論上能夠達到Nginx的進程數worker_processes * Ngin的最大鏈接數 worker_connections;
worker_connections 102400;
複製代碼
keepalive 的超時時間。
keepalive_timeout 60;
複製代碼