1. 程式人生 > >nginx基本配置整理

nginx基本配置整理

前言

記性不好,遇到的相關nginx問題和解決方法都會擴充在上面,如有問題請留言。

目錄

安裝nginx

裝好gcc g++ 開發庫環境
ubunto

$ apt-get install build-essential
$ apt-get install libtool

centos

$ yum -y install gcc automake autoconf libtool make
$ yum install gcc gcc-c++

下載nginx
* nginx

下載依賴模組gzpi、rewrite、ssl
* zlib
*

pcre
* openssl

設定nginx安裝目錄

/usr/local/nginx/

解壓nginx後編譯安裝

$ sudo ./configure \
--prefix=/usr/local/nginx/nginx \
--with-pcre=/usr/local/opensoft/pcre-8.39 \
--with-zlib=/usr/local/opensoft/zlib-1.2.8 \
--with-openssl=/usr/local/opensoft/openssl-1.0.1t

執行

/usr/local/nginx/sbin/nginx

檢視80埠是否執行

netstat -ano | grep 80

訪問 localhost ,顯示Welcome to nginx! 完成安裝。

管理nginx

配置nginx.conf

配置介紹

user www www;      #執行使用者和組
worker_processes  number | auto;      #worker程序數,cpu總核同數量,減少cpu排程成本。
worker_cpu_affinity 01 10;     #多核繫結,位圖表示法,ps -F檢視,PSR列對應CPU號
pid /usr/local/webserver/nginx/nginx.pid;     #指定pid存放的路徑
worker_rlimit_nofile;     #檔案描述符數量
master_process on | off; #啟動程序池機制,預設on,如果設定為off,將不會建立master程序,用一個worker來處理。worker_processes也會失效。 daemon on | off; #是否守護程序,預設on。 #任意域可配 error_log file | level #debug | info | notice | warn | error | crit | alert | emerg 預設error,過濾前面包含後面,debug需要編譯--with-debug,debug按模組控制等級,例如debug_http。 events{ use poll; #開啟多路複用IO(linux2.6核心以上) worker_connections 65535; #單個worker程序最大連線併發數 debug_connection 192.168.1.0/24; #單個ip段進行debug } http{ include mime.types; #包含mime.types檔案 include vhost/*.conf; #包含vhost下的所有虛擬主機配置檔案 default_type application/octet-stream; #指定預設的MIME型別 client_max_body_size 8m; #客戶端上傳的檔案大小 #設定日誌格式 log_format name '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" $http_x_forwarded_for ' '"$upstream_addr" "$upstream_status" "$upstream_response_time" "$request_time"'; #日誌存放路徑、格式和快取大小,格式設定為上面定義的name access_log /var/log/nginx/access.log name; sendfile on; #sendfile是個比 read 和 write 更高效能的系統介面, 反向代理時候無效,因為檔案控制代碼是 socket。 tcp_nopush on; #呼叫tcp_cork方法,這個也是預設的,結果就是資料包不會馬上傳送出去,等到資料包最大時,一次性的傳輸出去,這樣有助於解決網路堵塞。 tcp_nodelay on; #合併小的TCP 包為一個,避免了過多的小報文的 TCP 頭所浪費的頻寬。如果開啟了這個演算法 (預設),則協議棧會累積資料直到以下兩個條件之一滿足的時候才真正傳送出去,積累的資料量到達最大的 TCP Segment Size或收到了一個 Ack。 server_tokens off; #關閉nginx 版本號,修改版本號 vi src/core/nginx.h,NGINX_VER gzip on; #啟用壓縮 gzip_static on; #啟用HTTPGzipStatic模組(不在core和standard模組組中,但rpm安裝帶了此模組),該模組可以讀取預先壓縮的gz檔案,這樣可以減少每次請求進行gzip壓縮的CPU資源消耗。 gzip_comp_level 5; #壓縮級別,1最小最快,9最大最慢,一般設為3 gzip_min_length 1024; #壓縮的最小長度,小於此長度的不壓縮(此長度即header中的Content-Length) gzip_types text/plain text/css application/x-javascript application/javascript application/xml; (什麼型別的頁面或文件啟用壓縮) limit_zone myzone $binary_remote_addr 10m; #myzone 名字,$binary_remote_addr = $remore_addr,,10m的會話空間池 limit_req_zone $binary_remote_addr zone=req_one:10m rate=1r/s; #rate=1r/s 的意思是每個地址每秒只能請求一次,也就是說根據漏桶(leaky bucket)演算法 burst=120 一共有120塊令牌,並且每秒鐘只新增1塊令牌, 120塊令牌發完後 多出來的那些請求就會返回503 server{ limit_conn one 1; #限制客戶端併發連線數量為1 limit_req zone=req_one burst=120; #加上 nodelay之後超過 burst大小的請求就會直接 返回503 } #反向代理時nginx需要訪問的上游伺服器和負載均衡策略 #加權輪詢,基礎策略,計算各個後端伺服器的當前權值,選擇得分最高的伺服器處理當前請求。 #ip雜湊,雜湊選擇失敗20以上或一臺後端伺服器,採用加權。 #加權適用性強,不依賴客戶端任何資訊,能把客戶端請求合理均勻的分配,劣勢是同一個客戶端多次請求會被分配到不同的後端伺服器處理,無法滿足會話保持。 #ip雜湊較好地把同一客戶端的多次請求分配到同一臺後端伺服器,劣勢是某個ip地址請求特別多(大量使用者通過一個nat代理請求),會導致某臺後端伺服器壓力非常大,其他伺服器很空閒的不均衡情況。 upstream back_end{ ip_hash; #負載均衡策略,預設使用加權輪詢(round robin),官方內建,一致雜湊、fair第三方模組。 server 127.0.0.1:80; #一臺普通上游伺服器 server 127.0.0.1:8080 max_fails=3 fail_timeout=30s; #預設值1 和 30s,30s內連線3次失敗,休息一會,30s後再來。 server UNIX:/tmp/backend3 backup; #備機,不可用時,不能使用ip_hash,擾亂雜湊結果違背ip_hash策略初衷。 server 192.168.0.1:9000 down; #主動宕機,不參與被選。 server backend1.example.com weight=3; #權重3,預設1,與加權策略配合使用。 } #取$is_args的值,定義為$my_flag,預設值為0,如果是“?”,值為1 map $is_args $my_flag{ default 0; "?" 1; } #禁止使用者通過ip地址訪問伺服器,nginx未配置該域名或通過伺服器ip來訪問採用。 server{ listen 80 default; #表示這個server是80埠預設的server return 500; #表示任何使用這個server配置的請求將會返回500 } #虛擬主機配置塊 server{ listen 80; #監聽80埠 server_name localhost | *.ibeiliao.com | *.* ; #主機名稱,~開頭的正則表示式 keepalive_timeout 75 | 0;#超時時間,預設75s,設為0自動斷連, http、location、server域中。 # nginx 常用變數(按階段執行,先統一set變數) # curl -v -o /dev/null 'http://localhost/index.html?a=1&b=2' -H 'hello:world' # $uri : 當前請求的uri,不包含?後的引數 = /index.html # $is_args : 當前請求是否帶引數,如果有引數值為?,否則是空字串 =? # $args : 當前請求的完整引數,即?後面的字串 =a=1&b=2 # $request_uri : 當前請求的完整URI,包含引數 =/index.html?a=1&b=2 # $arg_xxx : 當前請求的某個引數 arg_a=1 # $http_xxx : 當前請求的xxx頭部對應的值 http_hello= world # $sent_http_xxx : 返回給客戶端的響應頭部對應的值 =nginx/1.8.0 # # nginx 自定義變數 # set $max_size 10000; # set $new_uri /v2$request_uri # set $log_tag "extra action" # # location [ = | ~ | ~* | ^~ | @ ] uri { ... } # 例如 location /image/ {...} 匹配 /image/001.jpg # = : URI必須完全匹配 # ~ : 大小寫敏感匹配 location ~ \.(php)$ {...} 大小寫敏感處理php請求 # ~* : 大小寫不敏感匹配 location ~* \.(png)$ {...} 忽略大小寫,匹配所有的png檔案 # ^~ : 匹配前半部分即可 location ^~ /image/ {...} 匹配/image/*.* 優先順序比上面低。 # @ : 用於內部子請求,外部無法訪問 #一個轉發的location location /passto { proxy_set_header Host $host; #轉發原始請求的host頭部 proxy_buffering off; #禁用反向代理快取,保證每次請求真實轉發 proxy_pass http://back_end; #轉發到upstream塊定義的伺服器叢集 #能用try_files代替則用它,否則不要用if,官方宣告if用不好的話會有bug。 #例子:優先使用person下的圖片,目錄不存在則使用公共目錄的圖片 if(-e "${document_root}/person"){ rewrite ^/(.*)$ /person/$1 break; } #try_files寫法 try_files /person$uri /$uri =400; } location / { #匹配任意URI root html; #http請求根目錄,靜態web伺服器 alias /var/data/; #請求目錄,與root不同的是,會把location當為別名。location /image/ {...},返回/var/data/001.jpg index index.php; #預設index檔案 auth_basic Auth; #彈出資訊提示字元為Auth auth_basic_user_file /etc/ngx_passwd; #賬號密碼 autoindex on; #自動列出目錄,禁用index autoindex_exact_size on; #設定索引檔案大小的單位 autoindex_localtime on; #開啟本地時間顯示檔案時間 } #增加websocket的支援 location /wsapp/ { proxy_pass http://wsbackend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } location = /50x.html { root html; } location ~ ^(.*)\/\.svn\/{ #禁止訪問SVN配置檔案 deny all; #禁止該匹配下的所有訪問 deny 192.168.10.1; #禁止該ip訪問,403 forbidden錯誤。 } #下列檔案快取在本地瀏覽器30天 location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)${ expires 30d; } #下列檔案快取在本地瀏覽器1小時 location ~ .*\.(js|css)?${ expires 1h; } error_page 500 502 503 504 /50x.html; #錯誤返回頁面 } }

nginx優點

事件驅動,nginx內部流程的向前推進基本都是靠各種事件觸發來驅動的,否則nginx將一直阻塞在函式epoll_wait()或sigsuspend()這樣的系統呼叫上。

nginx比apache更快是因為啟用了epoll模式(linux kenel 2.6+),它不會隨著被監控描述符數目的增長而導致效率急速下降。 而apache用的是select模式,採用遍歷掃描來判斷每個描述符是否有事件發生。監控的描述符數目越多,消耗也就越大。而且受系統預設限制,select模型最多隻能同時監控1024個描述符。

首先,基於poll的epoll具有原生poll的優點,即同時監控的描述符個數不受限制(受程序可開啟檔案描述符個數限制,cat /proc/sys/fs/file-max),其次,epoll模型對事件的響應是觸發式的,無需列表掃描。

epoll
1、監控描述符不受限制(受程序可開啟檔案描述符個數限制)
2、I/O事件響應觸發(LT水平觸發,不做處理核心持續通知,ET邊緣觸發,通知一次,更有優勢)
select
1、監控最大1024個描述符
2、I/O事件輪詢觸發

select 標準的I/O複用模型,unix系統都提供,效能較差,nginx可編譯中禁用。
poll 標準的I/O複用模型,理論上比select優,同select類似。
epoll Linux 2.6+上正式提供的更為優秀的I/O複用模型
kqueue FreeBSD4.1+、OpenBSD2.9+、NetBSD2.0、OS X上特有的更優秀的I/O複用模型
eventport 系統Solaris 10上可用的高效能I/O複用模型
/dev/poll 同上
rtsig 實時訊號模型(real time signals)
aio 非同步I/O

多路複用模型
例子:如果要監控10條高速公路堵車(是否可讀),需要10個人(10個執行緒,10處程式碼)來做這件事,利用某種技術把10條馬路的情況統一傳達到某個中心,那麼只需要1個人在中心進行監控就行了。而select或epoll這樣的多路I/O複用機制好比攝像頭的功能,能把多個I/O埠的狀況反饋到一處,比如某個特定的檔案描述符上,這樣,應用程式只需要利用對應的select()或epoll_wait()系統呼叫阻塞關注一處即可。

除錯nginx

遇到效能瓶頸(strace -T 跟蹤消耗時間)、啟動失敗、響應資料與預期不一致、莫名其妙的Segment ation Fault段錯誤。

ps aux | grep nginx

狀態為Ts(s代表Nginx程序為會話的首程序,session leader,T代表處在TASK_STOPPED狀態)

使用gdb | cgdb 除錯
1、編譯nginx的時候繫結gdb
2、修改nginx為一個工作程序,關閉守護程序。
3、開始除錯gdb -q -p 4614

使用strace(系統呼叫)/pstack(內部函式)除錯
1、strace -p 4033
2、wget 127.0.0.1 函式

其他除錯
System Tap/

參考

  • 深入剖析 nginx – 高群凱
  • 實戰nginx:取代apache的高效能web伺服器 – 張宴