Nginx基礎知識點彙總4

問題
需要配置自定義格式的訪問日誌(access log)
解決方案
配置訪問日誌格式:

http {
log_format geoproxy
	'[$time_local] $remote_addr '
	'$realip_remote_addr $remote_user '
	'$request_method $server_protocol '
	'$scheme $server_name $uri $status '
	'$request_time $body_bytes_sent '
	'$geoip_city_country_code3 $geoip_region '
	'"$geoip_city" $http_x_forwarded_for '
	'$upstream_status $upstream_response_time '
	'"$http_referer" "$http_user_agent"';
...
}

這個日誌配置被命名爲 geoproxy,它使用許多 NGINX 變量來演示 NGINX 日誌記錄功能。接下來詳細講解配置選項中各個變量的具體含義:當用戶發起請求時,會記錄服務器時間( timelocal)NGINXgeoipproxyrealipheaderIPIPtime_local )、用於 NGINX 處理 geoip_proxy 和 realip_header指令的打開連接的 IP 地址和客戶端 IP 地址;remote_user 值爲通過基本授權的用戶名稱;之後記錄 HTTP 請求方法( $request_method )、協議( $server_protocol )和 HTTP 方法( $scheme:http 或 https ) ;當然還有服務器名稱( $server_name )、請求的 URI 和響應狀態碼。除基本信息外,還有一些統計的結果數據:包括請求處理的毫秒級時間( $request_time)、服務器響應的數據塊大小( $body_bytes_sent )。此外,客戶端所在國家( $geoip_city_country_code3 )、地區( $geoip_region )和城市信息( $geoip_city )也被記錄在內。變量 $http_x_forwarded_for 用於記錄由其它代理服務器發起的請求的 X-Forwarded-For 頭消息。upstream 模塊中一些數據也被記錄到日誌裏:被代理服務器的響應狀態碼( $upstream_status ) 和服務器處理時間( $upstream_response_time )。請求來源( $http_referer )和用戶代理( $http_user_agent ) 也有被記錄在日誌裏。從上面可以看出 NGINX 日誌記錄功能還是非常強大和靈活的,不過用於定義日誌格式的 log_format 指令僅適用於 http 塊級指令內,這一點需要注意。

這個日誌的每個日誌記錄結果類似下面示例:

[25/Nov/2016:16:20:42 +0000] 10.0.1.16 192.168.0.122 Derek
GET HTTP/1.1 http www.example.com / 200 0.001 370 USA MI
"Ann Arbor" - 200 0.001 "-" "curl/7.47.0"

如果需要使用這個日誌配置,需要結合使用 access_log 指令,access_log 指令接收一個日誌目錄和使用的配置名作爲參數:

server {
	access_log /var/log/nginx/access.log geoproxy;
...
}

access_log 能在多個上下文使用,每個上下文中可以定義各自的日誌目錄和日誌記錄格式。

結論
NGINX 中的日誌模塊允許您爲不同的場景配置日誌格式,以便查看不同的日誌文件。在實際運用中,爲不同上下文配置不同的日誌會非常有用,記錄的日誌內容可以簡單的信息,也可以事無鉅細的記錄所有必要信息。不僅如此,日誌內容除了支持文本也能記錄 JSON 格式和 XML 格式數據。實際上 NGINX 日誌有助於您瞭解服務器流量、客戶端使用情況和客戶端來源等信息。此外,訪問日誌還可以幫助您定位與上游服務器或特定 uri 相關的響應和問題;對於測試來講,訪問日誌同樣有用,它可以用於分析流量情況,模擬真實的用戶交互場景。日誌在故障排除、調試、應用分析及業務調整中作用是不可或缺的。

問題
需要更深入的定位 NGINX 服務器問題,以配置錯誤日誌。
解決方案
使用 error_log 指令定義錯誤日誌目錄及記錄錯誤日誌的等級:

error_log /var/log/nginx/error.log warn;

error_log 指令配置時需要一個必選的日誌目錄和一個可選的錯誤等級選項。除 if 指令外,error_log 指令能在所有的上下文中使用。錯誤日誌等級包括:debug、info、notice、warn、error、crit、alert 和 emerg。給出的日誌等級順序就是記錄最小到最嚴謹的日誌等級順序。需要注意的是 debug 日誌需要在編譯 NGINX 服務器時,帶上 --with-debug 標識才能使用。

結論
請牢記當服務器配置出錯時,首先需要查看錯誤日誌以定位問題。當然,錯誤日誌也是定溫應用服務器(如 FastCGI 服務)的利器。通過錯誤日誌,我們可以調試 worder進程連接錯誤、內存分配、客戶端 IP 和 應用服務器等問題。錯誤日誌格式雖然不支持自定義日誌格式;但是,它同樣記錄當前時間、日誌等級和具體信息等數據。

問題
需要將錯誤日誌通過 syslog 服務記錄到集中日誌服務器。
解決方案
在使用 error_log 和 access_log 指令時,將日誌發送至 syslog 監聽器:

error_log syslog:server=10.0.1.42 debug;
access_log syslog:server=10.0.1.42,tag=nginx,severity=info geoproxy;

error_log 和 access_log 指令的 syslog 參數緊跟冒號(:)和一些參數選項。包括:必選的 server 標記表示需要連接的 IP、DNS 名稱或 UNIX 套接字;可選參數有 facility、severity、tag 和 nohostname。server 參數接收帶端口的 IP 地址或 DNS 名稱;默認是 UDP 514 端口。facility 參數設置syslog 的類型(facility),值是 syslog RFC 標準定義的 23 個值中的一個(@todo)。tag 參數表示日誌文件中顯示時候的標題,默認值是 nginx。
severity 設置消息嚴重程度,默認是 info 級別日誌。nohostname 選項,禁止將 hostname 域添加到syslog的消息頭中。

結論
syslog 是用於在單臺服務器或服務器集羣中記錄和收集日誌的標準協議。在多個主機上運行相同服務的多個實例時,將日誌發送到集中位置有助於調試,這稱爲聚合日誌。聚合日誌允許您在一個地方查看日誌,而不必切換不同服務器,並通過時間戳將日誌文件集成在一起。常見聚合日誌解決方案有 ElasticSearch、Logstash、Kibana 和 ELK Stack。但 NGINX 通過發送日誌到 syslog 監聽器,能夠很容易的將 access_log 和 error_log 指令捕捉的日誌發送到聚合日誌服務器上。

問題
需要結合 NGINX 日誌和應用日誌,查看請求調用棧。
解決方案
使用 request 標識,並將標識寫入到應用日誌裏:

log_format trace '$remote_addr - $remote_user [$time_local] '
				'"$request" $status $body_bytes_sent '
				'"$http_referer" "$http_user_agent" '
				'"$http_x_forwarded_for" $request_id';
	upstream backend {
		server 10.0.0.42;
	}
	server {
		listen 80;
		add\_header X-Request-ID $request\_id; \# Return to client
	location / {
		proxy_pass http://backend;
		proxy_set_header X-Request-ID $request_id; \#Pass to app
		access_log /var/log/nginx/access_trace.log trace;
	}
}

示例中,配置了名爲 trace 的訪問日誌格式,並在日誌中使用 $request_id 參數。同時,通過 proxy_set_header 指令將 request 標記(request ID)設置到請求頭裏,當請求匹配到 location / 前綴,請求被轉發到 upstream 模塊,這樣同一個 request 標識就能記錄到應用服務器日誌裏;此外,通過 add_header 指令將 reqeust 標識設置到響應消息頭,供客戶端使用。

結論
該功能在 NGINX Plus R10 版本和 NGINX 開源版的 1.11.0 版本可用,$request_id 提供了一個隨機生成的 32 個十六進制字符的字符串,這些字符可以用來唯一地標識請求。通過將此標識符傳遞給客戶端和應用服務器,可以將日誌與請求關聯起來。客戶端會收到唯一的 request 標識,服務端也能使用該標識進行日誌篩選。應用服務器使用時,需要獲取這個消息頭,以建立日之間的關聯。基於這個特性,NGINX 能夠構建從客戶端請求到應用服務器做出響應的整個請求調用週期的所有日誌信息之間的關聯。

問題
使用負載測試工具實現自動化測試
解決方案
使用 HTTP 負載測試工具:如 Apache JMeter/ Locust/ Gatling/或團隊自研的負載工具。爲測試定製測試配置,並對服務器進行全面測試,基於測試結果量化性能指標;之後,逐步增加用戶數增加併發量,以模擬生產環境真實請求,找出性能瓶頸優化;如此反覆,直至達到項目的預期性能。
結論
使用自動化的測試工具來定義您的測試,可以讓您通過一個一致的測試來找出對 NGINX 進行調優的基準。性能測試必須是可重複的,通過對性能測試結果進行科學分析。在對 NGINX 配置進行優化前,需對服務器進行測試確定標準,這樣,才能確定之後的配置優化是否實現了性能的優化。對每個配置優化進行度量,將幫助您確定性能得以提升的根源。

問題
增加單個連接的請求數,同時增加空閒連接(idle connections)的的連接時長。
解決方案
keepalive_requests 和 keepalive_timeout 指令允許變更單個連接的最大請求數和空閒連接的連接時長:

http {
	keepalive_requests 320;
	keepalive_timeout 300s;
...
}

keepalive_requests 默認爲 100,keepalive_timeout 的默認值爲 75 秒。

結論
一般情況下,keepalive_requests 和 keepalive_timeout 的默認配置,能夠滿足客戶端的請求,因爲,現代瀏覽器能爲不同域名打開多個連接。但對於同一個域名僅能同時發起 10 以內的請求,這將帶來性能瓶頸。CDN 的實現原理是啓用多個域名指向內容服務器,並以編碼的方式指定使用的域名,以使瀏覽器能夠打開更多的連接。你會發現使用更多的請求連接數和連接時長配置,在客戶端需要頻繁更新數據能提升服務器性能。

問題
需要增加代理服務器與被代理服務器的連接數,提升服務器性能。
解決方案
在 upstream 會計指令中使用 keepalive 指令保持代理服務與被代理服務器連接以複用:

proxy_http_version 1.1;
proxy_set_header Connection "";
upstream backend {
	server 10.0.0.42;
	server 10.0.2.56;
	keepalive 32;
}

keepalive 指令會爲每個 NGINX worker 進程創建一個連接緩存,表示每個worker 進程能保持打開的空閒連接的最大連接數量。如果要使 keepalive指令正常工作,在 upstream 指令上使用的 proxy 模塊指令則是必須的。proxy_http_version 指令表示啓用的 http 1.1 版本,它允許在單個連接上發送多個請求;proxy_set_header 指令刪除 connection 消息頭的默認值 close,這樣就允許保持連接的打開狀態。

結論
當需要保持代理服務器與被代理服務器的連接打開狀態,以節省啓動連接
所需的時間;同時,需要將 worker 進程收到的請求分發值空閒的連接直接
處理。有一點需要注意,開啓的連接數可以多於 keepalive 配置的連接數,
因爲開啓的連接數和空閒連接數不是同一個東西。keepalive 配置的連接數
應儘量少,以確保新的請求能夠被分發到被代理服務器。這條配置技巧能夠
通過減少請求連接的生命週期的手段,提升服務器性能。

問題
將服務器對客戶端的響應寫入內存緩衝區而不是文件裏。
解決方案
調整代理模塊的緩存區設置,允許 NGINX 服務器將響應消息體寫入內存緩衝區:

server {
	proxy_buffering on;
	proxy_buffer_size 8k;
	proxy_buffers 8 32k;
	proxy_busy_buffer_size 64k;
...
}

proxy_buffering 值可以使 on 或 off,默認是 on。proxy_buffer_size 指令表示用於讀取來自代理服務器響應的緩衝大小,依據平臺不同它的默認值爲4k 或 8k。proxy_buffers 指令包含兩個值,支持的緩存區個數和單個緩存區容量大小,默認是 8 個緩存區,依據平臺不同單個緩存區默認容量爲 4k 或 8k。proxy_busy_buffer_size 指令用於配置未完全讀取響應時直接響應客戶端的緩衝區大小,它的空間一般爲 proxy_buffers 的兩倍爲最佳。

結論
代理緩存能顯著提升代理服務性能,這取決於響應內容的大小。開啓緩衝區設置應當仔細測試響應內容的平均大小,並進行大量測試和調試,否則可能引發副作用。而如果將緩存區大小設置的非常大也不行,這回佔用大量的 NGINX 內存。一種方案是將緩衝區大小設置爲與最大響應消息相同以提升性能。

問題
當系統處於負載狀態時,啓用日誌緩衝區以降低 NGINX worker 進程阻塞。
解決方案
設置 access_log 的 buffer 和 flush 參數:

http {
	access_log /var/log/nginx/access.log main buffer=32k flush=1m;
}

buffer 參數用於設置,寫入文件前的緩衝區內存大小;flush 參數設置緩衝區內日誌在緩衝區內存中保存的最長時間。

結論
將日誌數據緩衝到內存中可能是很小的一個優化手段。但是,對於有大量請求的站點和應用程序的磁盤讀寫和 CPU 使用性能有重大意義。buffer 參數的功能是當緩衝區已經寫滿時,日誌會被寫入文件中;flush 參數的功能是,當緩存中的日誌超過最大緩存時間,也會被寫入到文件中,不過也有不足的地方即寫入到日誌文件的日誌有些許延遲。

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