1. 程式人生 > >nginx--學習總結

nginx--學習總結

學習總結 fas fault failed 時間 爭奪 ace 存在 -m

最近復習了一下nginx,由於要考試了,大概總結一下

下載地址: http://nginx.org/download/nginx-1.4.2.tar.gz
安裝準備: nginx依賴於pcre庫,要先安裝pcre
yum install pcre pcre-devel
cd /usr/local/src/
wget http://nginx.org/download/nginx-1.4.2.tar.gz
tar zxvf nginx-1.4.2.tar.gz
cd nginx-1.4.2
./configure --prefix=/usr/local/nginx
make && make install
(unbantu下類似主要是記得安裝pcre庫)



啟動:
cd /usr/local/nginx, 看到如下4個目錄
./
....conf 配置文件
... html 網頁文件
...logs 日誌文件
...sbin 主要二進制程序

[root@localhost nginx]# ./sbin/nginx
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
....
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] still could not bind()

不能綁定80端口,80端口已經被占用

(有時是自己裝了apache,nginx等,還有更多情況是操作系統自帶了apache並作為服務啟動)
解決: 把占用80端口的軟件或服務關閉即可.





nginx信號控制

TERM, INT -------Quick shutdown
QUIT --------Graceful shutdown 優雅的關閉進程,即等請求結束後再關閉
HUP -------- Configuration reload ,Start the new worker processes with
a new configuration Gracefully shutdown the old worker processes

改變配置文件,平滑的重讀配置文件
USR1- ---------Reopen the log files 重讀日誌,在日誌按月/日分割時有用
USR2 --------Upgrade Executable on the fly 平滑的升級
WINCH ---------Gracefully shutdown the worker processes 優雅關閉舊的進程(配合USR2來進行升級)



具體語法:
Kill -信號選項 nginx的主進程號
Kill -HUP 4873

Kill -信號控制 cat /xxx/path/log/nginx.pid

Kil; -USR1 cat /xxx/path/log/nginx.pid



還有另外一種
-s signal : send signal to a master process: stop, quit, reopen, reload
nginx -s reload/stop/quit/reopen 重讀配置/停止nginx/平滑的停止/重讀日誌

Nginx配置段

// 全局區
worker_processes 1; // 有1個工作的子進程,可以自行修改,但太大無益,因為要爭奪CPU,一般設置為 CPU數*核數

Event {
// 一般是配置nginx連接的特性
// 如1個worker能同時允許多少連接
worker_connections 1024; // 這是指 一個子進程最大允許連1024個連接
}

http { //這是配置http服務器的主要段
Server1 { // 這是虛擬主機段,一個虛擬主機

   
        Location {  //定位,把特殊的路徑或文件再次定位 ,如image目錄單獨處理
        }             /// 如.php單獨處理//uri的處理

}

Server2 {
}
}



例子1: 基於域名的虛擬主機

server {
listen 80; #監聽端口,默認80端口
server_name a.com; #監聽域名 比如www.etiantian.org

location / {
root /var/www/a.com; #根目錄定位
index index.html;
}
}

例子2: 基於端口的虛擬主機配置

server {
listen 8080;
server_name 192.168.1.204;//ip,域名,unix等

location / {
root /var/www/html8080;
index index.html;
}
}



一個小技巧:
可以用:egrep -v "#|^$" nginx.conf.defalut>nginx.conf//可以去掉配置文件中的空格和#號





日誌管理
我們觀察nginx的server段,可以看到如下類似信息
#access_log logs/host.access.log main;
這說明 該server, 它的訪問日誌的文件是 logs/host.access.log ,(路徑為相對路徑,即nginx的安裝路徑)
使用的格式”main”格式.
除了main格式,你可以自定義其他格式.

main格式是什麽?
log_format main ‘$remote_addr - $remote_user [$time_local] "$request" ‘
‘$status $body_bytes_sent "$http_referer" ‘
‘"$http_user_agent" "$http_x_forwarded_for"‘;

main格式是我們定義好一種日誌的格式,並起個名字,便於引用.
以上面的例子, main類型的日誌,記錄的 remote_addr.... http_x_forwarded_for等選項.
其中有兩個相對比較重要的參數,後面會經常遇到
http_user_agent-----客戶端的代理信息,即用的那種瀏覽器可以通過它獲得比如MSIE Firefox,andriod,iphone等
http_x_forwarded_for 相當於網路訪問路徑,比如代理服務器從哪兒來的,都可以通過設置它來獲得
1: 日誌格式 是指記錄哪些選項
默認的日誌格式: main
log_format main ‘$remote_addr - $remote_user [$time_local] "$request" ‘
‘$status $body_bytes_sent "$http_referer" ‘
‘"$http_user_agent" "$http_x_forwarded_for"‘;

如默認的main日誌格式,記錄這麽幾項
遠程IP- 遠程用戶/用戶時間 請求方法(如GET/POST) 請求體body長度 referer來源信息
http-user-agent用戶代理/蜘蛛 ,被轉發的請求的原始IP

http_x_forwarded_for:在經過代理時,代理把你的本來IP加在此頭信息中,傳輸你的原始IP





2: 聲明一個獨特的log_format並命名

log_format mylog ‘$remote_addr- "$request" ‘
‘$status $body_bytes_sent "$http_referer" ‘
‘"$http_user_agent" "$http_x_forwarded_for"‘;
在下面的server/location,我們就可以引用 mylog

在server段中,這樣來聲明
Nginx允許針對不同的server做不同的Log ,(有的web服務器不支持,如lighttp)

access_log logs/access_8080.log mylog;
聲明log log位置 log格式;



實際應用: shell+定時任務+nginx信號管理,完成日誌按日期存儲
分析思路:
淩晨00:00:01,把昨天的日誌重命名,放在相應的目錄下
再USR1信息號控制nginx重新生成新的日誌文件

具體腳本:
#!/bin/bash
base_path=‘/usr/local/nginx/logs‘
log_path=$(date -d yesterday +"%Y%m")
day=$(date -d yesterday +"%d")
mkdir -p $base_path/$log_path
mv $base_path/access.log $base_path/$logpath/access$day.log
#echo $base_path/$logpath/access$day.log
kill -USR1 cat /usr/local/nginx/logs/nginx.pid#重讀日誌



以上腳本用來避免日誌文件過大,即每天分割日誌

定時任務
Crontab 編輯定時任務(Crontab用法請自行查閱)
01 00 * /xxx/path/b.sh 每天0時1分(建議在02-04點之間,系統負載小)









location 語法
location 有”定位”的意思, 根據Uri來進行不同的定位.
在虛擬主機的配置中,是必不可少的,location可以把網站的不同部分,定位到不同的處理方式上.
比如, 碰到.php, 如何調用PHP解釋器? --這時就需要location
location 的語法
location [=|~|~*|^~] patt {
}
中括號可以不寫任何參數,此時稱為一般匹配
也可以寫參數
因此,大類型可以分為3種
location = patt {} [精準匹配]
location patt{} [一般匹配]
location ~ patt{} [正則匹配]



如何發揮作用?:
首先看有沒有精準匹配,如果有,則停止匹配過程.
location = patt {
config A
}
如果 $uri == patt,匹配成功,使用configA
location = / {
root /var/www/html/;
index index.htm index.html;
}

     

location / {
root /usr/local/nginx/html;
index index.html index.htm;
}

如果訪問  http://xxx.com/
定位流程是 
1: 精準匹配中 ”/” ,得到index頁為  index.htm
2: 再次訪問 /index.htm , 此次內部轉跳uri已經是”/index.htm” ,
根目錄為/usr/local/nginx/html
3: 最終結果,訪問了 /usr/local/nginx/html/index.htm



再來看,正則也來參與.
location / {
root /usr/local/nginx/html;
index index.html index.htm;
}

location ~ image {
root /var/www/image;
index index.html;
}

如果我們訪問 http://xx.com/image/logo.png
此時, “/” 與”/image/logo.png” 匹配
同時,”image”正則 與”image/logo.png”也能匹配,誰發揮作用?
正則表達式的成果將會使用.

圖片真正會訪問 /var/www/image/logo.png





location / {
root /usr/local/nginx/html;
index index.html index.htm;
}

location /foo {
root /var/www/html;
index index.html;
}
我們訪問 http://xxx.com/foo
對於uri “/foo”, 兩個location的patt,都能匹配他們
即 ‘/’能從左前綴匹配 ‘/foo’, ‘/foo’也能左前綴匹配’/foo’,
此時, 真正訪問 /var/www/html/index.html
原因:’/foo’匹配的更長,因此使用之.;









rewrite 重寫

重寫中用到的指令
if (條件) {} 設定條件,再進行重寫
set #設置變量
return #返回狀態碼
break #跳出rewrite
rewrite #重寫



If 語法格式
If 空格 (條件) {
重寫模式
}

條件又怎麽寫?
答:3種寫法
1: “=”來判斷相等, 用於字符串比較
2: “~” 用正則來匹配(此處的正則區分大小寫)
~* 不區分大小寫的正則
3: -f -d -e來判斷是否為文件,為目錄,是否存在.

例子:

if ($remote_addr = 192.168.1.100) {
return 403;
}



if ($http_user_agent ~ MSIE) {
rewrite ^.*$ /ie.htm;
break; #(不break會循環重定向)
}

if (!-e $document_root$fastcgi_script_name) {
rewrite ^.*$ /404.html break;
}
註, 此處還要加break,
以 xx.com/dsafsd.html這個不存在頁面為例,
我們觀察訪問日誌, 日誌中顯示的訪問路徑,依然是GET /dsafsd.html HTTP/1.1
提示: 服務器內部的rewrite和302跳轉不一樣.
跳轉的話URL都變了,變成重新http請求404.html, 而內部rewrite, 上下文沒變,
就是說 fastcgi_script_name 仍然是 dsafsd.html,因此 會循環重定向.
set 是設置變量用的, 可以用來達到多條件判斷時作標誌用.
達到apache下的 rewrite_condition的效果

如下: 判斷IE並重寫,且不用break; 我們用set變量來達到目的
if ($http_user_agent ~* msie) {
set $isie 1;
}

if ($fastcgi_script_name = ie.html) {
set $isie 0;
}

if ($isie 1) {
rewrite ^.*$ ie.html;
}



Rewrite語法
Rewrite 正則表達式 定向後的位置 模式



註意:用url重寫時, 正則裏如果有”{}”,正則要用雙引號包起來



nginx+php的編譯
apache一般是把php當做自己的一個模塊來啟動的.
而nginx則是把http請求變量(如get,user_agent等)轉發給 php進程,即php獨立進程,與nginx進行通信. 稱為 fastcgi運行方式.
因此,為apache所編譯的php,是不能用於nginx的.

註意: 我們編譯的PHP 要有如下功能:
連接mysql, gd, ttf, 以fpm(fascgi)方式運行
./configure --prefix=/usr/local/fastphp \
--with-mysql=mysqlnd \
--enable-mysqlnd \
--with-gd \
--enable-gd-native-ttf \
--enable-gd-jis-conv
--enable-fpm



網頁內容的壓縮編碼與傳輸速度優化
我們觀察news.163.com的頭信息
請求:
Accept-Encoding:gzip,deflate,sdch
響應:
Content-Encoding:gzip
Content-Length:36093
再把頁面另存下來,觀察,約10W字節,實際傳輸的36093字節
原因-------就在於gzip壓縮上.

原理:
瀏覽器---請求----> 聲明可以接受 gzip壓縮 或 deflate壓縮 或compress 或 sdch壓縮
從http協議的角度看--請求頭 聲明 acceopt-encoding: gzip deflate sdch (是指壓縮算法,其中sdch是google倡導的一種壓縮方式,目前支持的服務器尚不多)
服務器-->回應---把內容用gzip方式壓縮---->發給瀏覽器
瀏覽<-----解碼gzip-----接收gzip壓縮內容----

推算一下節省的帶寬:
假設 news.163.com PV 2億
210^8 910^4 字節 ==
2
10^8 9 10^4 10^-9 = 12K*G = 18T
節省的帶寬是非常驚人的

gzip配置的常用參數
gzip on|off; #是否開啟gzip
gzip_buffers 32 4K| 16 8K #緩沖(壓縮在內存中緩沖幾塊? 每塊多大?)
gzip_comp_level [1-9] #推薦6 壓縮級別(級別越高,壓的越小,越浪費CPU計算資源)
gzip_disable #正則匹配UA 什麽樣的Uri不進行gzip
gzip_min_length 200 # 開始壓縮的最小長度(再小就不要壓縮了,意義不在)
gzip_http_version 1.0|1.1 # 開始壓縮的http協議版本(可以不設置,目前幾乎全是1.1協議)
gzip_proxied # 設置請求者代理服務器,該如何緩存內容
gzip_types text/plain application/xml # 對哪些類型的文件用壓縮 如txt,xml,html ,css
gzip_vary on|off # 是否傳輸gzip壓縮標誌



註意:
圖片/mp3這樣的二進制文件,不必壓縮
因為壓縮率比較小, 比如100->80字節,而且壓縮也是耗費CPU資源的.
比較小的文件不必壓縮,
nginx的緩存設置 提高網站性能
對於網站的圖片,尤其是新聞站, 圖片一旦發布, 改動的可能是非常小的.我們希望 能否在用戶訪問一次後, 圖片緩存在用戶的瀏覽器端,且時間比較長的緩存.
可以, 用到 nginx的expires設置 .
nginx中設置過期時間,非常簡單,
在location或if段裏,來寫.
格式 expires 30s;
expires 30m;
expires 2h;
expires 30d;
(註意:服務器的日期要準確,如果服務器的日期落後於實際日期,可能導致緩存失效)
另: 304 也是一種很好的緩存手段
原理是: 服務器響應文件內容是,同時響應etag標簽(內容的簽名,內容一變,他也變), 和 last_modified_since 2個標簽值
瀏覽器下次去請求時,頭信息發送這兩個標簽, 服務器檢測文件有沒有發生變化,如無,直接頭信息返回 etag,last_modified_since
瀏覽器知道內容無改變,於是直接調用本地緩存.
這個過程,也請求了服務器,但是傳著的內容極少.
對於變化周期較短的,如靜態html,js,css,比較適於用這個方式

nginx反向代理服務器+負載均衡
用nginx做反向代理和負載均衡非常簡單,
支持兩個用法 1個proxy, 1個upstream,分別用來做反向代理,和負載均衡
以反向代理為例, nginx不自己處理php的相關請求,而是把php的相關請求轉發給apache來處理.

----這不就是傳說的”動靜分離”,動靜分離不是一個嚴謹的說法,叫反向代理比較規範.

反向代理後端如果有多臺服務器,自然可形成負載均衡,
但proxy_pass如何指向多臺服務器?
把多臺服務器用 upstream指定綁定在一起並起個組名,
然後proxy_pass指向該組

默認的均衡的算法很簡單,就是針對後端服務器的順序,逐個請求.
也有其他負載均衡算法,如一致性哈希,需要安裝第3方模塊.



Nginx具體的壓縮配置
常用以下配置
gzip on|off
gzip_buffers 4K|8K 緩沖(和硬盤塊相當)
gzip_comp_level [1-9] 推薦6
gzip_disable 正則匹配如User-Agent,針對古老瀏覽器不壓縮
gzip_min_length 200
gzip_http_version 1.0|1.1
gzip_types text/plain , application/xml (各mime之間,一定要加空格,不是逗號)
gzip_vary on|off





請求時,不支持gzip, 緩存服務器將會生成一份未gzip的內容.
請求時,支持gzip, 緩存服務器將會生成一份gzip的內容.

下次再請求時, 緩存服務器會考慮客戶端的Accept-Encoding因素,並合理的返回信息

Nginx對於圖片,js等靜態文件的緩存設置
註:這個緩存是指針對瀏覽器所做的緩存,不是指服務器端的數據緩存.

主要知識點: location expires指令

location ~ .(jpg|jpeg|png|gif)$ {
expires 1d;
}
location ~ .js$ {
expires 1h;
}

設置並載入新配置文件,用firebug觀察,
會發現 圖片內容,沒有再次產生新的請求,原因--利用了本地緩存的效果.



註: 在大型的新聞站,或文章站中,圖片變動的可能性很小,建議做1周左右的緩存
Js,css等小時級的緩存.



如果信息流動比較快,也可以不用expires指令,
用last_modified, etag功能(主流的web服務器都支持這2個頭信息)
原理是:
響應: 計算響應內容的簽名, etag 和 上次修改時間
請求: 發送 etatg, If-Modified-Since 頭信息.
服務器收到後,判斷etag是否一致, 最後修改時間是否大於if-Modifiled-Since
如果監測到服務器的內容有變化,則返回304,
瀏覽器就知道,內容沒變,直接用緩存.



304 比起上面的expires 指令
多了1次請求,
但是比200狀態,少了傳輸內容.



相關配置實際例子
負載均衡加熱備
worker_processes??1;
events?{
????worker_connections??1024;
}
http?{
????include???????mime.types;
????default_type??application/octet-stream;
????sendfile????????on;
????keepalive_timeout??65;

upstream?web_pools?{
????
????server?10.0.0.9:80?weight=5?max_fails=10?fail_timeout=10s;
????server?10.0.0.10:80?weight=5;
????server?10.0.0.10:80?weight=5??backup;
}
????server?{
????????listen???????80;
????????server_name??www.etiantian.org;
????????location?/?{
????????????root???html;
????????????index??index.html?index.htm;
????????????proxy_pass?http://web_pools;
????????????proxy_set_header?Host??$host;#設置傳給web的host信息
????????????proxy_set_header?X-Forwarded-For?$remote_addr;#web真正的ip
????????}

????}
}





proxy.conf優化配置:

proxy_redirect?off;?
????????proxy_set_header?Host?$host;?
????????proxy_set_header?X-Real-IP?$remote_addr;?
????????proxy_set_header?X-Forwarded-For?$proxy_add_x_forwarded_for;?
????????proxy_connect_timeout?90;?
????????proxy_send_timeout?90;?
????????proxy_read_timeout?90;?
????????proxy_buffer_size?4k;?
????????proxy_buffers?4?32k;
????????proxy_busy_buffers_size?64k;?
proxy_temp_file_write_size?64k;

            

            
        動靜分離
                worker_processes??1;

events?{
????worker_connections??1024;
}
http?{
????include???????mime.types;
????default_type??application/octet-stream;
????sendfile????????on;
????keepalive_timeout??65;

upstream?static_pools?{
????server?10.0.0.9:80?weight=5?max_fails=10?fail_timeout=10s;
}

upstream?dynamic_pools?{
????server?10.0.0.10:80?weight=5;
}
????server?{
????????listen???????80;
????????server_name??www.etiantian.org;
????????location?/?{
????????????root???html;
????????????index??index.html?index.htm;
????????????proxy_pass?http://dynamic_pools;
????????????include?proxy.conf;
????????}
????????location?~?.*.(gif|jpg|jpeg|png|bmp|swf|css|js)$?{
????????proxy_pass?http://static_pools;
????????include?proxy.conf;
}
????}
}

worker_processes??1;
events?{
????worker_connections??1024;
}
http?{
????include???????mime.types;
????default_type??application/octet-stream;
????sendfile????????on;
????keepalive_timeout??65;

upstream?static_pools?{
????server?10.0.0.9:80?weight=5?max_fails=10?fail_timeout=10s;
}

upstream?dynamic_pools?{
????server?10.0.0.10:80?weight=5;
}
????server?{
????????listen???????80;
????????server_name??www.etiantian.org;
????????location?/?{
????????????root???html;
????????????index??index.html?index.htm;
????????????proxy_pass?http://dynamic_pools;
????????????include?proxy.conf;
????????}
???????location?/image/?{?
????????proxy_pass?http://static_pools;
????????include?proxy.conf;
???????}

???????location?/dynamic/?{
????????proxy_pass?http://dynamic_pools;
????????include?proxy.conf;
???????}



????}
}







//另一種分離,通過if條件達到和location同樣的效果
????????if?($request_uri???~???"..(php|php5)$")
????????{
????????????????proxy_pass?http://php_server_pools;
????????}
????????if?($request_uri???~???"..(jsp|jsp|do|do)$")
????????{
????????????????proxy_pass?http://java_server_pools;
????????}

            


根據擴展名實現服務器的動靜分離
location?~?..(gif|jpg|jpeg|png|bmp|swf|css|js)$?{
proxy_pass?http://static_pools;
include?proxy.conf;
}
location?~?.
.(php|php3|php5)$?{
proxy_pass?http://dynamic_pools;
include?proxy.conf;
}





server?{
????????listen???????80;
????????server_name??www.etiantian.org;
????????location?/?{
????????if?($http_user_agent?~?"MSIE")
??????????{
????????????proxy_pass?http://dynamic_pools;
??????????}
????????if?($http_user_agent?~
?"Firefox")
??????????{
????????????proxy_pass?http://static_pools;
????????????}
????????proxy_pass?http://dynamic_pools;
????????include?proxy.conf;
????}

    

    

extra/proxy.conf
#允許客戶端請求的最大的單個文件字節數
????????client_max_body_size?????10m;
????????#緩沖區代理緩沖用戶端請求的最大字節數?可以理解為先保存到本地再傳給用戶
????????client_body_buffer_size??128k;
????????#跟後端服務器連接的超時時間_發起握手等候響應超時時間
????????proxy_connect_timeout????600;
????????#連接成功後_等候後端服務器響應時間_其實已經進入後端的排隊之中等候處理
????????proxy_read_timeout???????600;
????????#後端服務器數據回傳時間_就是在規定時間之內後端服務器必須傳完所有的數據
????????proxy_send_timeout???????600;
????????#代理請求緩存區_這個緩存區間會保存用戶的頭信息以供Nginx進行規則處理_一般只要能保存下頭信息即可
????????proxy_buffer_size????????8k;
????????#同上?告訴Nginx保存單個用的幾個Buffer?最大用多大空間
????????proxy_buffers????????????4?32k;
????????#如果系統很忙的時候可以申請更大的proxy_buffers?官方推薦*2
????????proxy_busy_buffers_size?64k;
????????#proxy緩存臨時文件的大小
????????proxy_temp_file_write_size?64k;



一些優化參數
net.ipv4.tcp_fin_timeout?=?2
net.ipv4.tcp_tw_reuse?=?1
net.ipv4.tcp_tw_recycle?=?1
net.ipv4.tcp_syncookies?=?1
net.ipv4.tcp_keepalive_time?=?600
net.ipv4.ip_local_port_range?=?4000????65000
net.ipv4.tcp_max_syn_backlog?=?16384
net.ipv4.tcp_max_tw_buckets?=?36000
net.ipv4.route.gc_timeout?=?100
net.ipv4.tcp_syn_retries?=?1
net.ipv4.tcp_synack_retries?=?1
net.core.somaxconn?=?16384
net.core.netdev_max_backlog?=?16384
net.ipv4.tcp_max_orphans?=?16384
#以下參數是對iptables防火墻的優化,防火墻不開會提示,可以忽略不理。
net.ipv4.ip_conntrack_max?=?25000000
net.ipv4.netfilter.ip_conntrack_max=25000000
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established=180
net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait=120
net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait=60
net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait=120



http://zyan.cc/nginx_cache/
??#設置Web緩存區名稱為cache_one,內存緩存空間大小為200MB,1天沒有被訪問的內容自動清除,硬盤緩存空間大小為30GB。
??proxy_cache_path??/data0/proxy_cache_dir??levels=1:2???keys_zone=cache_one:200m?inactive=1d?max_size=30g;
??

nginx--學習總結