1.Nginx日志管理
1.日志簡單介紹
Nginx提供了日志記錄的功能,日志文件在對我們管理網站十分有用,通過訪問日志(access_log)我們可以獲取請求來源、客戶端信息、請求的資源等信息;通過錯誤日志(error_log)可以獲取錯誤發生時間、錯誤信息等,方便我們及時定位和修復錯誤。看一下Nginx中日志相關的指令。
#設置訪問日志:訪問日志文件為nginx/logs/mysite.access.log,格式為main access_log logs/mysite.access.log main;
位置 格式 #設置錯誤日志:錯誤日志文件為nginx/logs/mysite.error.log,記錄級別為error error_log logs/mysite.error.log error;
位置 級別 #定義main格式的日志 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
在Nginx日志中嚴重程度:debug<info<notice<warn<error<crit,一般記錄warn/error級別;定義日志格式中,$開頭的是Nginx中的變量,在前面已經總結過了,為了方便查看本篇底部也放了一份。記錄網站的訪問/錯誤日志,十分簡單,只需要把access_log/error_log指令放在需要記錄的server主機內即可。也可以把access_log/error_log指令放在http中用來記錄全局日志。
看一個簡單的Nginx配置文件,為了方便演示,這里只配置了默認主機,並刪去了Nginx中一些和日志不相關的配置:
worker_processes 2; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream;#定義main格式的日志 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; #默認主機 server{ listen 80; server_name localhost; location /{ root html; index index.html; } #訪問日志,名字問nginx/logs/mysite.access.log,格式為main格式 access_log logs/mysite.access.log main; #錯誤日志,記錄級別為error error_log logs/mysite.error.log error; } }
當我們輸入虛擬機IP會訪問到默認主機,這時在nginx/logs目錄下自動生成訪問日志mysite.access.log和錯誤日志mysite.error.log。內容如下:
mysite.access.log內容:
訪問日志的內容為main格式中定義的信息,某些信息不存在沒有顯示。我們也可以自定義訪問日志的格式。
mysite.error.log內容:
可以看到錯誤原因是favicon.ico文件找不到,我們也可以知道錯誤發生的時間,請求,客戶端和服務端IP等信息。
2.日志切片
上邊我們已經知道怎么去設置訪問日志和錯誤日志,但是這樣設置有一個弊端:日志文件都放在同一個文件中,長時間運行后日志文件很大,可能達到幾個G,甚至十幾個G大小,查看起來很不方便。為了解決這個問題就需要進行日志切片,如每小時或者每天的日志放在一個單獨的文件中。怎么實現呢?總體思路是:設置一個定時任務,每隔一段時間將日志文件剪切到一個特定的目錄下。
這里以訪問日志切片為例,為了方便演示這里把每分鍾的訪問日志放在一個單獨的文件中,首先,添加一個存放日志文件的目錄,執行命令 mkdir /usr/local/nginx/logs/mysitelogs ,我們打算把mysite的所有訪問日志都放在這個文件夾下。然后添加一個切割日志的腳本,執行命令 vim /usr/local/nginx/mysitelog.sh ,腳本內容如下:
#mysite.com虛擬主機的日志存放路徑 LOGPATH=/usr/local/nginx/logs/mysite.access.log #日志備份文件目錄,mysite虛擬主機的備份日志放在logs下的單獨目錄下 BASEPATH=/usr/local/nginx/logs/mysitelogs #一分鍾記錄一次 bak=$BASEPATH/$(date -d today +%Y%m%d%H%M).mysite.access.log #重名日志文件 mv $LOGPATH $bak touch $LOGPATH #向nginx主進程發送信號,重新寫日志 /usr/local/nginx/sbin/nginx -s reopen
最后添加一個定時任務,執行命令 crontab -e ,編輯內容如下,表示每分鍾執行一次mysitelog.sh腳本:
* * * * * sh /usr/local/nginx/mysitelog.sh
到這里日志切片就結束了,我們看一個日志文件, cd /usr/local/nginx/logs/mysitelogs 到日志文件夾下,看到日志文件為每分鍾存儲一次,前綴格式為yyyyMMddhhmm:
補充:我們在實際使用時一般把一天的日志放在一個文件中(高並發量的除外),下邊的腳本實現每天晚上11:30分存儲一次日志文件:

#-------------------shell腳本 #該虛擬主機的日志存放路徑 LOGPATH=/usr/local/nginx/logs/mysite.access.log #日志備份文件目錄,mysite虛擬主機的備份日志放在logs下的單獨目錄下 BASEPATH=/usr/local/nginx/logs/mysitelogs #一天記錄一次,格式為20190326mysite.access.log bak=$BASEPATH/$(date -d yesterday +%Y%m%d)mysite.access.log #重名日志文件 echo $bak mv $LOGPATH $bak touch $LOGPATH #向nginx主進程發送信號,重新打開日志 /usr/local/nginx/sbin/nginx -s reopen #------------------定時任務 30 23 * * * sh /usr/local/nginx/mysitelog.sh
2.常用Nginx配置總結
Nginx的介紹到這里就基本結束了,這里匯總了一些Nginx中最常用的配置
2.1 基本配置
# 用戶和用戶組 user wyy wyy #工作進程個數,通常設置和邏輯cpu個數一致 worker_processes 8; #cpu親和性,每個進程分配一個cpu 00000001表示第一個cpu,00000010表示第二個cpu,依次類推 worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000; #如果是兩個邏輯cpu,可以設置worker_processes 2; worker_cpu_affinity 01 10; #一個nginx工作進程最多可以打開的文件描述符個數 ,最好和linux最多能打開的文件描述符個數(查看命令:ulimit-n)保持一致。 #出現報錯:too open many file,這時我們把worker_rlimit_nofile 值設置大一些就可以了。 worker_rlimit_nofile 65535 #記錄的級別嚴重程度:debug<info<notice<warn<error<crit],一般記錄warn/error級別 #錯誤日志,級別為error error_log logs/error.log error; #記錄nginx的master進程的pid pid logs/nginx.pid; events { use epoll ; #多路復用IO的一種方式,效率很高,支持linux2.6以上內核 worker_connections 1024; #每個工作進程的最大連接數,一台nginx的理論最大連接數就是(單個工作進程的最大連接數*工作進程個數) multi_accept on; #盡可能多地接受請求 } http { #媒體類型,定義在nginx/conf/mine.types中 include mime.types; #默認的媒體類型 default_type application/octet-stream; #main日志格式 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; #nginx是否調用sendfile函數(zero,copy等)來輸出文件,普通應用都應該設置成on sendfile on; #默認開啟,nginx接受到數據包不馬上發送,等到數據包達到一定大小再發送,使用Nagle算法控制。減少tcp傳輸次數,防止網絡阻塞 tcp_nopush on; #tcp不延遲,和tcp_nopush相反,接收到數據包就發送,提高數據的實時響應 #tcp_nodelay off; #長連接,請求資源獲取完畢后不斷開連接,60s后關閉該連接 keepalive_timeout 60; #上傳時單個文件最大為10M client_max_body_size 10m; #客戶端的請求頭緩沖區大小,一般設置為系統分頁大小即可(查詢系統分頁命令:getconf PAGESIZE) #client_header_buffer_size 4k; #客戶端的請求體緩沖區大小,超過這個大小存放在臨時文件中, #client_body_buffer_size 8k; ######超時管理 代理服務器時才有用 (超時都返回502超時錯誤) #nginx連接后台服務器超時時間, proxy_connect_timeout 90; #后台服務器回傳數據超時時間,90s傳輸數據未完成就報錯 proxy_send_timeout 90; #連接成功,等待后台服務器響應的超時時間 proxy_read_timeout 90; #為打開文件設定緩存,默認是不啟用的,max指定緩存數量,建議和最多能打開文件描述符個數(查詢命令:ulimit -n)一致,inactive是指經過多長時間文件沒被請求后刪除緩存 open_file_cache max=65535 inactive=60s; #多久檢查一次緩存的有效信息 open_file_cache_valid 30s; #定義負載均衡模塊, upstream mysiteServers{ server 123.11.1.2:8080 weight=1 max_fails=2 fail_timeout=30s; server 123.11.1.3:8080 weight=2 max_fails=2 fail_timeout=30s; server 123.11.1.4:8080 weight=3 max_fails=2 fail_timeout=30s; } server{ servername :www.site1.com www.site1.cn; #首頁 location = / { proxy_pass http:/123.11.1.1:8080/Home/Index; } #靜態文件 location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ { root /webroot/res/; #緩存十分鍾 expires:600; } #通用規則,用來轉發動態請求到后端應用服務器 location / { proxy_pass http://mysiteServers; } }
2.2 壓縮配置
gzip可以放在http/server/location/if下,用於壓縮請求資源,減小網絡傳輸的數據尺寸。gzip壓縮常用於文本類型(css/js等)文件壓縮,二進制文件(如圖片,視頻)壓縮比不大,建議使用緩存(expires)進行優化:
#開啟gzip壓縮 gzip on; #最小壓縮大小4000字節,小於4000字節就不壓縮了 gzip_min_length 4000; #壓縮的緩沖設置,緩沖32塊開始輸出,每塊4k大小 #gzip_buffers 32 4k; #壓縮采用的版本 gzip_http_version 1.1; #壓縮級別,級別越大壓縮后尺寸越小方便傳輸,但同時壓縮時耗費cpu資源也越大(最大為9,一般不要超過6) gizp_comp_level 4; #壓縮的文件類型,不屬於這些類型的就不壓縮(可以通過 cat nginx/conf/mine.types查看文件類型),注:二進制文件如圖片/視頻的壓縮比不大,不建議壓縮 gzip_types application/javascript text/plain text/css text/xml; # 是否傳輸gzip壓縮標志,請求頭中有vary標志的返回壓縮版本文件,沒有vary頭的返回原始文件 gzip_vary on;
2.3 負載均衡配置
#1.weight #指定輪詢權重,weight越大,轉發幾率越大,一般用於后端服務器性能不均的情況。 upstream mysiteServers{ server 192.168.70.1:8080 weight=1; server 192.168.70.2:8080 weight=3; } #2.ip_hash #每個請求按訪問ip的hash結果分配,這樣每個訪客固定訪問一個后端服務器,適用后台服務器緩存多的場合,也可以解決session的問題。 upstream mysiteServers{ ip_hash; server 192.168.70.1:8080; server 192.168.70.2:8080; } #一些參數 upstream mysiteServers{ server 192.168.70.1:8080 down; server 192.168.70.1:8081 weight=2; server 192.168.70.2:8080; server 192.168.70.2:8081 backup; } #1.down表示的server暫時不參與負載均衡,請求不會轉發給這台服務器; #2.weight為weight越大,負載的權重就越大; #3.max_fails續請求失敗的次數默認為1.當超過最大次數時,不再轉發請求給這台服務器; #4.fail_timeout:max_fails次失敗后,暫停多久后再向這台服務器轉發請求; #5.backup: 其它所有的非backup機器down或者忙的時候,請求backup機器。所以這台機器壓力會最輕。
補充:也可以使用第三方模塊實現其他負載均衡模式: ①添加nginx-upstream-fair模塊可以實現按響應性能進行負載均衡,響應速度越快的服務器分發請求的幾率越大; ②添加nginx_upstream_hash模塊可以實現按請求url來進行轉發請求,url相同的請求由同一個服務器處理,適用於緩存較多場景。
補充:Nginx的一些全局變量
變量 |
含義 |
$args |
請求中的參數,同$query_string |
$content length |
請求頭中的Content-length字段。 |
$content_type |
請求頭中的Content-Type字段。 |
$document_root |
當前請求在root指令中指定的值。 |
$host |
請求主機頭字段,否則為服務器名稱。 |
$http_user_agent |
用戶代理,一般為用戶瀏覽器信息 |
$http_cookie |
客戶端cookie信息 |
$limit_rate |
這個變量可以限制連接速率。 |
$request_method |
客戶端請求的動作,通常為GET或POST。 |
$remote_addr |
客戶端的IP地址。 |
$remote_port |
客戶端的端口。 |
$remote_user |
已經經過Auth Basic Module驗證的用戶名。 |
$request_filename |
當前請求的文件路徑,由root或alias指令與URI請求生成。 |
$scheme |
協議名(如http,https)。 |
$server_protocol |
請求使用的協議,通常是HTTP/1.0或HTTP/1.1。 |
$server_addr |
服務器地址,在完成一次系統調用后可以確定這個值。 |
$server_name |
服務器名稱。 |
$server_port |
請求到達服務器的端口號。 |
$request_uri |
包含請求參數的原始URI,不包含主機名,如”/user/getuser?id=100”。 |
$uri |
不帶請求參數的當前URI,$uri不包含主機名,如”/user/getuser”。 |
$document_uri |
與$uri相同 |
$http_x_forwarded_for |
代理過程的IP |