基本命令
start nginx
nginx -s stop(當即中止)
nginx -s quit(平緩中止,有請求事不會意外中止)
nginx -s reload
遇到的坑:不要重複地去啓動多個nginx進程,這樣會致使你修改的nginx對應不上,能夠經過資源管理器殺掉進程javascript
短鏈接:TCP創建鏈接->請求資源->響應資源-> 關閉鏈接 每次請求都要經歷這樣的過程
長鏈接:創建一次鏈接後,每次請求都複用該鏈接。
並行鏈接:併發的短鏈接
http1.0中爲了支持長鏈接必須在請求頭中指定css
Connection:keep-alive
在 HTTP 1.1 中 全部的鏈接默認都是持續鏈接,除非特殊聲明不支持;如今大多數瀏覽器都默認是使用HTTP/1.1,因此keep-alive都是默認打開的html
Connection:close 指定不使用長鏈接
怎麼判斷一個請求數據接收完?
在響應頭中若是有Tansfer-Encoding:chunked則表示body爲流式輸出,會被分紅多個塊,每一個塊開始都會標識當前塊的長度,此時body不須要長度;若是是非chunked則按照content-length來接收數據;不然等到服務端主動斷開鏈接。
nginx中關於transfer-encoding的設置chunked_transfer_encoding on | off;
創建鏈接後服務端不是一直在等待下一次請求,經過nginx設置最大等待時間
nginx: http模塊中能夠設置超大等待時間 keepalive_timeout 65;
java
pipeline流水線做業
http1.1新特性,一個鏈接作屢次請求;
在keepaiive中第二個請求要等第一個請求響應徹底接受以後才能發起。
在pipeline中沒必要等待第一個請求處理後就能夠發起第二個請求,nginx會把讀取的數據放在buffer中,在nginx處理完第一個請求時發現buffer中還有數據,就會任務剩下的數據是下一個請求的開始,而後處理下一個請求,不然設置爲keepalivenode
擴展:TCP的keepalive:
AB在三次握手創建TCP鏈接以後,B忽然宕機了,可是A內核還會維護着AB之間的鏈接,浪費系統資源。引入keepalive機制,A定時給B發送空數據包,稱爲心跳包,一旦發現B網絡不通則關閉鏈接。
Nginx涉及到tcp層面的keepalive只有一個:so_keepalivenginx
Http處理過程
初始化http request(讀取客戶端數據,生成HTTP Request對象,該對象包含了全部請求信息)
處理請求頭
處理請求體
調用此請求的url或者location關聯的handle
依次調用各phase handler處理(phase handler是指包含某階段若干個handler)正則表達式
一個phase handler處理的任務chrome
當nginx讀取到一個http Request的header時,首先尋找與請求關聯的虛擬主機配置,若是找到則經歷如下幾個phase handler
1.server級別的url重寫階段,在讀取請求頭過程當中nginx會根據host和端口尋找對應的虛擬主機配置:json
server{ rewrite 規則 定向路徑 重寫類型 # 訪問 /last.html 的時候,頁面內容重寫到 /index.html 中 rewrite /last.html /index.html last; } 規則:字符串或者正則來匹配目標url 定向路徑:匹配到規則後要定向的url 重寫類型: 1. last 完成重寫瀏覽器地址欄url不變 2. break終止後面的匹配,地址欄url不變 3. redirect 302臨時重定向,地址欄顯示跳轉後的url 4. permanent 301永久重定向,顯示跳轉後的url
2.location rewrite瀏覽器
location 與 location rewrite的區別:
rewrite regex replacement [flag]; 1.重寫帶http:// location /{ # 當匹配 正則表達式 /test/(.*)時 請求將被臨時重定向到 http://www.$1.com rewrite /test/(.*) http://www.$1.com return 200 'ok' } # 在瀏覽器中輸入 127.0.0.1:8080/test1/baidu # 則臨時重定向到 www.baidu.com # 後面的 return 指令將沒有機會執行了 2.重寫不帶http:// location / { rewrite /test/(.*) www.$1.com; return 200 "ok"; } # 發送請求以下 # curl 127.0.0.1:8080/test/baidu # ok # 此處沒有帶http:// 因此只是簡單的重寫。請求的 uri 由 /test/baidu 重寫爲 www.baidu.com # 由於會順序執行 rewrite 指令 因此 下一步執行 return 指令 響應了 ok
TCP優化
http { sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 60; ... ...
senfile on能夠提升靜態資源託管效率,是一個系統調用,不須要先read再write,沒有上下文切換開銷
tcp_nopush 在sendfile開啓後才生效,啓用後數據包累計必定的大小纔會發送,提升了網絡效率,減小了開銷
tcp_nodelay 數據包累計到必定大小後儘快發送,nginx只會針對處於keepalive的TCP鏈接啓用tcp_nodelay
keepalive_timeout 表示每一個tcp鏈接能夠保持多少秒,默認是75秒,有些瀏覽器最可能是保持60秒,因此設置爲60秒
TFO(TCP Fast open)優化策略
客戶端第一次創建鏈接仍是要三次握手,不一樣的是客戶端會在第一個SYN設置一個fast-open的標誌,服務端會生成fast-open cookie並放在SYN-ACK中,客戶端就能夠把cookie存起來之後syn用;
在這以後用戶再創建TCP鏈接,發送syn包的同時會把cookie帶上,而後能夠直接帶上http數據。換句話說在發送SYN包的時候把應用層數據發送出來,減小了一個RTT對性能的影響。
可是這種優化成本很是高須要操做系統、內核的支持(服務端和用戶端都要支持)。
開啓gzip
http { gzip on; gzip_vary on; gzip_comp_level 6; gzip_buffers 16 8k; gzip_min_length 1000; gzip_proxied any; gzip_disable "msie6"; gzip_http_version 1.0; gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript; ... ... }
gzip_vary 用來輸出vary響應頭解決某些服務緩存問題
//請求頭 Accept:*/* 接受任何MIME類型資源 Accept-Encoding:gzip,deflate,sdch 接受gzip,deflate,sdch壓縮過的資源 Accept-Language:zh-CN,en-US;q=0.8,en;q=0.6 能夠接受zh-ch,en-us,en;其中zh-cn的優先級最高(q 取值 0 - 1,最高爲 1,最低爲 0,默認爲 1),服務端應優先返回zh-cn //響應頭 Content-Type: text/javascript 表示文檔確切的類型是text/javascript Content-Encoding: gzip 文檔使用了gzip壓縮 //沒有content-language一般表示返回的是Accept-language權重最高的那種語言
Accept字段並不夠用,若是要針對特定瀏覽器,如ie6就要使用到user-agent;cookie也可能做爲服務器輸出內容差別的依據。
若是服務器和客戶端之間存在有緩存服務器,而服務器根據不一樣的user-agent返回不一樣的內容,緩存服務器卻把針對特定瀏覽器的內容緩存下來統一返回,就會有問題。
因此http協議規定,若是服務器提供的內容是取決於user-agent(Accept以外的字段)請求頭字段,響應頭中必需要包含vary字段,並且vary字段必須包含user-agent。
//當內容取決於User-Agent和cookie時,vary字段應該相似於這樣,也就是列出一個響應字段列表,告訴緩存服務器遇到同一個url的時候如何緩存和篩選合適的版本。 Vary:User-Agent, Cookie;
Content-Encoding在緩存服務器的問題
緩存服務器應該根據不一樣的Content-Encoding緩存不一樣的內容,再根據請求頭的Accept-Encoding來返回合適的版本。爲了不給客戶端返回不合適的版本:
1.將請求頭的Cache-control改成private
2.增長vary:Accept-Encoding明確告訴緩存服務器按照Accept-Encoding字段內容緩存不一樣的版本。
以上的工做nginx都以gzip_vary: on搞定,至關於在啓用了gzip的響應上加vary:Accept-Encoding
gzip_disable
接受一個正則匹配,請求的User-Agent匹配到後響應不會啓用gzip。是爲了解決某些瀏覽器啓用gzip帶來的問題。
gip_http_version
nginx默認啓用http版本是Http/1.1,由於早期Http/1.0啓用gzip有bug,如今基本忽略,全部能夠指定gzip_http_version: 1.0;
開啓緩存
優化代碼邏輯的極限是移除全部極限;優化請求的極限是不發送任何請求。
http{ proxy_cache_path /home/nginx/proxy_cache_path levels=1:2 keys_zone=pnc:300m inactive=7d max-size=10g; }
/home/nginx/proxy_cache_path: 本地路徑,緩存文件存放的路徑
levels:默認全部文件放在/home/nginx/proxy_cache_path下,影響緩存性能,大部分場景是推薦使用2級目錄來緩存文件。
post請求提交數據的四種格式
http協議規定post方法提交的數據主體必須方式消息主體中(entity-body),可是協議並無規定數據必須使用什麼編碼格式。開發者能夠本身決定主體內容。服務器都內置瞭解析常見數據格式的功能,根據請求頭的content-type來獲取消息中的請求消息主體是以何種方式編碼,再對主體進行解析。
Content-Type
application/x-www-form-urlencoded
原生的form提交不設置enctype屬性時默認使用這種格式提交,提交格式按照val1=key1&val2=key2格式進行編碼,key和val都進行了url轉碼。
POST http://www.example.com HTTP/1.1 Content-Type: application/x-www-form-urlencoded;charset=utf-8 title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3
multipart/form-data
若是傳輸的是文件,還要包括文件名和文件類型信息。消息主體最後以--boundary--結束。
POST http://www.example.com HTTP/1.1 Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA ------WebKitFormBoundaryrGKCBY7qhFd3TrwA Content-Disposition: form-data; name="text" title ------WebKitFormBoundaryrGKCBY7qhFd3TrwA Content-Disposition: form-data; name="file"; filename="chrome.png" Content-Type: image/png PNG ... content of chrome.png ... ------WebKitFormBoundaryrGKCBY7qhFd3TrwA--
application/json