nginx筆記

nginx的安裝php

安裝準備: nginx依賴於pcre庫,要先安裝pcre

yum install pcre pcre-develcss

cd /usr/local/src/html

wget http://nginx.org/download/nginx-1.4.2.tar.gz前端

tar zxvf nginx-1.4.2.tar.gz mysql

cd nginx-1.4.2nginx

./configure --prefix=/usr/local/nginxweb

make && make install正則表達式

啓動:

cd /ulsr/local/nginx,看到以下4個目錄算法

./sql

....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`


Nginx配置段

//全局區

worker_processes 1; //有1個工做的子進程,能夠自行修改,但太大無益,由於要爭奪CPU,通常設置爲CPU數*核數

Event {

//通常是配置nginx鏈接的特性

//如1個word能同時容許多少鏈接

worker_connections 1024; //這是指 一個子進程最大容許連1024個鏈接  }

http { //這是配置http服務器的主要段

Server1 { //這是虛擬主機段

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

}              ///如.php單獨處理

}

Server2 {

}

}

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

server {

             listen 80; #監聽端口

server_name a.com; #監聽域名

location / {

root /var/www/a.com; #根目錄定位

index index.html;

}

}

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

server {

listen 8080;

server_name 192.168.1.204;

location / {

root /var/www/html8080;

index index.html;

}

}

日誌管理

咱們觀察nginx的server段,能夠看到以下相似信息

#access_log logs/host.access.log main;

這說明該server,它的訪問日誌的文件是logs/host.access.log ,使用的格式」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等選項.

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/$log_path/access_$day.log

#echo $base_path/$log_path/access_$day.log

kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`

定時任務

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正則表達式 定向後的位置 模式

Goods-3.html ---->Goods.php?goods_id=3

goods-([\d]+)\.html ---> goods.php?goods_id =$1

location /ecshop {

index index.php;

rewrite goods-([\d]+)\.html$ /ecshop/goods.php?id=$1;

rewrite article-([\d]+)\.html$ /ecshop/article.php?id=$1;

rewrite category-(\d+)-b(\d+)\.html /ecshop/category.php?id=$1&brand=$2;

rewrite category-(\d+)-b(\d+)-min(\d+)-max(\d+)-attr([\d\.]+)\.html /ecshop/category.php?id=$1&brand=$2&price_min=$3&price_max=$4&filter_attr=$5;

rewrite category-(\d+)-b(\d+)-min(\d+)-max(\d+)-attr([\d+\.])-(\d+)-([^-]+)-([^-]+)\.html /ecshop/category.php?id=$1&brand=$2&price_min=$3&price_max=$4&filter_attr=$5&page=$6&sort=$7&order=$8;

}

注意:用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

編譯完畢後:

1:nginx+php的配置比較簡單,核心就一句話----把請求的信息轉發給9000端口的PHP進程,讓PHP進程處理 指定目錄下的PHP文件.

以下例子:

location ~ \.php$ {

                               root html;

                               fastcgi_pass 127.0.0.1:9000;

                               fastcgi_index index.php;

                               fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

                               include                 fastcgi_params;  

}

1:碰到php文件,

2:把根目錄定位到html,

3:把請求上下文轉交給9000端口PHP進程,

4:並告訴PHP進程,當前的腳本是$document_root$fastcgi_scriptname(注:PHP會去找這個腳本並處理,因此腳本的位置要指對)


網頁內容的壓縮編碼與傳輸速度優化

咱們觀察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億

2*10^8 * 9*10^4字節

2*10^8 * 9 * 10^4 * 10^-9 = 12*K*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第3方模塊的安裝,以安裝ngx_http_upstream_consistent_hash爲例)

反向代理致使了後端服務器的IP,爲前端服務器的IP,而不是客戶真正的IP,怎麼辦?

做業及下週實驗課程

1:在虛擬機上裝3個端口的nginx服務器

2:裝ecshop/discuz,並作url重寫

3:利用3個端口的服務器,來實現簡單的負載均衡.

下週實驗:

1:數據 企業名稱/電話/簡介 等信息 約2500-3000萬條

2:服務器4臺, 2G/4核(1)   8G/雙核(3)

3:目標3000PV

設計:服務器的架構圖,包括nginx/mysql/php/memcached的分佈.

每人要出一個設計方案


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

Vary的做用:


Vary是用來標誌緩存的依據.

如上圖:看出,這個新聞頁面由

思考:

1:若是2我的,一個瀏覽器支持gzip,一個瀏覽器不支持gzip2個同時請求同個頁面, chinaCache緩存壓縮後,仍是未壓縮的?

2:若是1人,再次請求頁面,chinaCache返回壓縮後的緩存內容,仍是壓縮前的緩存內容?

這個時候Vary的做用體現出來.

即緩存的內容受Accept-Encoding頭信息的影響.

因此若是請求時,不支持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狀態,少了傳輸內容.

Nginx反向代理與負載均衡正向代理


反向代理


具體的負載均衡的方式

注意:負載均衡是一種方案,實現辦法有DNS輪詢,以下圖,DNS服務器容許一個域名有多個A記錄,那麼在用戶訪問時,通常按地域返回一個較近的解析記錄.這樣,全國不一樣的地區的用戶,看到的163的主頁,來自不一樣的服務器.


第二步:當 解析出結果,好比瀏覽器鏈接60.217時,這臺主機後面還有N臺,也要作負載均衡.

1:硬件上作負載均衡, F5 BIG-IP ,硬件負載均衡(很貴).直接從TCP/IP的底層協議上,直接作數據包的中轉.

2:軟件負載均衡, LVS

3:反向代理+負載均衡

反向代理與keep-alive鏈接


Nginx反向代理設置

例:把圖片重寫到8080端口(既然能寫到8080端口,就意味着能夠寫到其餘獨立服務器上)

location ~ \.(jpg|jpeg|png|gif)$ {

proxy_pass http://192.168.1.204:8080;

expires 1d;

}

集羣與均衡,若是後端的服務器很是多,該如何寫?又如何均勻的分發任務


nginx與memcached的組合

用法: nginx響應請求時,直接請求memcached,若是沒有相應的內容,再回調PHP頁面,去查詢database,並寫入memcached.

分析: memcached是k/v存儲, key-->value,nginx請求memecached時,用什麼作key?

通常用uri arg作key,如/abc.php?id=3

Nginx第三方模塊的安裝以ngx_http_php_memcache_standard_balancer-master爲例

1:解壓到path/ngx_module

配置:

./configure --prefix=/xxx/xxx --add_module=/path/ngx_module

編譯安裝

Make && make instal

配置memcache集羣

upstream memserver {  把用到的memcached節點,聲明在一個組裏

hash_key $request_uri; // hash計算時的依據,以uri作依據來hash

server localhost:11211;

server localhost:11212;

}

Location裏

location / {

# root html;

set $memcached_key $uri;

memcached_pass memserver; // memserver爲上面的memcache節點的名稱error_page 404 /writemem.php;

index index.php index.html index.htm;

}

在nginx中作集羣與負載均衡,步驟都是同樣的Upstream {}
模塊 把多臺服務器加入到一個組而後memcached_pass, fastcgi_pass, proxy_pass ==> upstream組

默認的負載均衡的算法:

是設置計數器,輪流請求N臺服務器.

能夠安裝第3方模式,來利用uri作hash等等.

如http://wiki.nginx.org/NginxHttpUpstreamConsistentHash

這個模塊就是用一致性hash來請求後端結節,而且其算法,與PHP中的memcache模塊的一致性hash算法,兼容.

安裝該模塊後:

Nginx.conf中

upstream memserver {

consistent_hash $request_uri;

server localhost:11211;

server localhost:11212;

}

在PHP.ini中,以下配置

memcache.hash_strategy = consistent

這樣: nginx與PHP便可完成對memcached的集羣與負載均衡算法.
相關文章
相關標籤/搜索