Ningx的基本使用
user www;
worker_processes 2;
error_log logs/error.log info;
pid logs/nginx.pid;
events {
worker_connections 1024; // 控制允許接受的並發連接數
}
http { // 定義與web服務相關的
include mime.types;
default_type application/octet-stream;
....
}
一、部署web服務
每一個server { } 定義一個網站
例子:
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root html; # 定義網站的根目錄
index index.html index.htm index.php; # 定義目錄的默認頁面
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location ~ \.php$ { # 匹配所有以 .php結尾的訪問請求
root html;
fastcgi_pass 127.0.0.1:9000; # 把請求交給本地監聽9000端口的進程來處理
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
include fastcgi_params;
}
}
}
URL的組成: http://www.upl.com/bbs/upload/11.jpg
http 協議
:// 格式符號 例如: ftp:// file://
www.upl.com 目的地,這個請求要發給誰,可以寫IP地址
/bbs/upload/11.jpg 網絡路徑(請求路徑)
nginx: Location
squid: url_path
apache: Location
在原有默認網站的基礎上,再去定義一個網站
http{
...
...
server {
默認網站
}
server {
第二個網站
}
}
定義好第二個網站的例子:
server {
listen 80;
server_name bbs.upl.com;
root /web/bbs.upl.com/wwwroot;
access_log /web/bbs.upl.com/logs/access.log;
location / {
index index.html index.htm index.php;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
include fastcgi_params;
}
# mkdir -p /web/bbs.upl.com/{wwwroot,logs}
# chown -R www:www /web/bbs.upl.com/{wwwroot,logs}
重載
# /usr/local/nginx/sbin/nginx -s reload
測試的時候
客戶端需要修改hosts:
10.1.1.21 www.upl.com upl.com bbs.upl.com
======================================================================
例子: location學習
匹配訪問請求中的路徑,不同的請求路徑不同的處理方法
location
syntax: location [=|~|~*|^~|@] /uri/ { ... }
= 精確匹配某個路徑
~ 可以使用正則表達式匹配(對大小寫敏感)
~* 忽略大小寫的正則表達式匹配
^~ 以什么開頭請求,可以使用正則表達式
location = / {
# 僅僅只能匹配以/開頭並且沒有多余的字符的路徑 http://www.upl.com/
[ configuration A ]
}
location / {
# 如果后面或者前面有更精確匹配或者有正則表達的location能夠匹配,首先匹配它們,然后再
# 匹配本location,如果選項沖突按照前者生效,如果選項不沖突,那么按照本location
# 可以匹配任何以 / 開頭的請求
[ configuration B ]
}
location ^~ /images/ {
# 正則表達是匹配,匹配所有以 /images開頭的訪問請求
# http://www.upl.com/images/xxx/xxx/.jpg
[ configuration C ]
}
location ~* \.(gif|jpg|jpeg)$ {
# 忽略大小寫,匹配所有以gif或者jpg或者jpeg結尾的訪問請求。
# 如果存在多個正則表達式匹配某個請求,那么誰在前面,誰優先生效,后面就不會再去匹配。
# Configuration C.
[ configuration D ]
}
Example requests:
* / -> configuration A <--- http://www.upl.com/
* /documents/document.html -> configuration B
<-- http://www.upl.com/documents/document.html
* /images/1.gif -> configuration C
<--- http://www.upl.com/images/1.gif
* /documents/1.jpg -> configuration D
通過設定location,給所有的網站指定404錯誤頁面
1、把同一個報錯頁面的相關文件放在一個目錄里
# mkdir -p /web/common
# chown www:www /web/common
# ls /web/common/
404.html no.png
# cat 404.html
<center><img src="/no.png" /></center>
server {
..
error_page 404 /404.html;
location = /404.html {
root /web/common;
}
location = /no.png {
root /web/common;
}
..
}
server {
..
error_page 404 /404.html;
location = /404.html {
root /web/common;
}
location = /no.png {
root /web/common;
}
..
}
狀態頁面
location /status {
stub_status on;
access_log off;
allow 10.1.1.21;
deny all;
}
正則匹配,地址重寫
if 條件判斷,匹配用戶的請求,然后作出相應的動作
匹配的操作符號
~ performs a case-sensitive match
~* performs a case-insensitive match (firefox matches FireFox)
!~ and !~* mean the opposite, "doesn't match"
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break;
}
地址重寫rewrite
rewrite ^(.*)$ /zh/$1 break;
rewrite 客戶端發過來的請求地址 nginx轉換出來的地址 flag;
如果客戶端瀏覽器語言是zh_CN,那么就把它請求轉換成/zh開頭的
http://www.upl.com/test.html --轉換后-> http://www.upl.com/zh/test.html
例子1:中文語言客戶端訪問中文頁面
server {
...
if ($http_user_agent ~ zh-CN) {
rewrite ^(.*)$ /zh/$1 break;
}
location { .. }
}
# mkdir /wwwroot/zh
# ls /wwwroot/test.html <---英文頁面
# ls /wwwroot/zh/test.html <---中文頁面
效果:使用中文的瀏覽器訪問的時候,就會實際訪問到 中文頁面
客戶實際訪問的URL
但事實上被nginx偷偷加載 /wwwroot/zh/test.html 返回給客戶端。
例子: 防止盜鏈
www.upl.com網站上的圖片,只要出現在非www.upl.com的網站里都會被返回一張盜鏈提示的圖片
原理: 只要www.upl.com服務器接受訪問圖片的請求,而這些請求的來路(Referer)不是www.upl.com開頭,那么絕對就是盜鏈。
location ~* \.(gif|jpg|jpeg|png)$ {
if ( $http_referer !~ http://www.upl.com/(.*) ) {
rewrite ^(.*)$ /no.png last;
}
}
例子:偽靜態
http://www.upl.com/read-tid-1.html <---這個頁面在服務器上根本不存在,但是可以被訪問。
/read-tid-1.html ---> nginx通過正則表達是匹配該請求----轉換用戶請求read.php?tid=1 ---> nginx背后按照轉換后的請求去返回資源給客戶端
為了實現偽靜態的前提:
1、網站跑的應用程序要支持。
2、web服務器上rewrite規則要正確
默認的URL形式為 "http://www.phpwind.net/thread.php?fid=2"
新的URL形式為 "http://www.phpwind.net/thread-fid-2.html" <--客戶端在瀏覽器輸入的地址
$1 /thread
$2 fid-2.html
轉換后:
/thread.php?fid-2.html
/read.php?tid-1.html
1、登錄論壇后台設定
靜態目錄: -htm-
靜態目錄擴展名設置: .html
2、寫規則
server {
rewrite ^(.*)-htm-(.*)$ $1.php?$2 last;
location { ..}
}
===============================================================================
web服務器的調優
如何評價一個web服務的性能:
1、並發請求數目並不等價同時有多個不同的IP連接。具體是指連接請求。
# lsof -i:80 -n | grep 199
nginx 9194 www 13u IPv4 156781 0t0 TCP 10.1.1.21:http->10.1.1.199:40161 (ESTABLISHED)
nginx 9194 www 15u IPv4 156788 0t0 TCP 10.1.1.21:http->10.1.1.199:40164 (ESTABLISHED)
nginx 9194 www 16u IPv4 156789 0t0 TCP 10.1.1.21:http->10.1.1.199:40165 (ESTABLISHED)
nginx 9194 www 27u IPv4 156899 0t0 TCP 10.1.1.21:http->10.1.1.199:40175
以上代表四個並發請求
2、請求時間(響應時間)
站住客戶端的角度去分析:
響應時間 = 請求發送出去的時間 + 服務器處理請求的時間 + 請求返回的時間
站在服務端的角度去分析:
響應時間 = 服務器處理請求的時間(從接受到請求到返回那刻開始)
3、吞吐量
服務器在單位時間內,處理了多少的數據。
理想目標:
在系統資源允許的條件下,響應時間在可以接受的范圍內,並發請求越多越好,吞吐量越大越好。
調優手段:
1、模擬並發請求,增加對服務器的壓力
# ab 命令 <---安裝httpd-tools軟件包
2、調整參數,對比調整前后的指標
調整的方向:
可以減少cpu的開銷,就盡可能減少。
並發請求、連接建立和撤銷、動態頁面的編譯消耗cpu資源
可以減少內存的開銷,盡可能減少。
頁面的編譯、頁面的代碼、請求的類型、連接駐留(保持連接)
如果服務器是屬於cpu密集型,主要是以消耗cpu為主的,服務器主要體現在cpu運算能力不足:增加內存的使用,減少cpu的開銷,前提:內存足夠
如果服務器是屬於內存密集型,主要是以消耗內存為主的,服務器主要體現在內存不足: 減少內存開銷,往往就會帶來cpu開銷增加。前提:cpu運算能力足夠
3、不斷變化調整,最后找到一個最恰當的參數
調整參數之前,在一定比例的並發數下,在響應時間允許的情況下,做測試。
# ab -c 500 -n 5000 http://10.1.1.21/thread-htm-fid-2.html
-A:指定連接服務器的基本的認證憑據; -c:指定一次向服務器發出請求數; -C:添加cookie; -g:將測試結果輸出為“gnuolot”文件; -h:顯示幫助信息; -H:為請求追加一個額外的頭; -i:使用“head”請求方式; -k:激活HTTP中的“keepAlive”特性; -n:指定測試會話使用的請求數; -p:指定包含數據的文件; -q:不顯示進度百分比; -T:使用POST數據時,設置內容類型頭; -v:設置詳細模式等級; -w:以HTML表格方式打印結果; -x:以表格方式輸出時,設置表格的屬性; -X:使用指定的代理服務器發送請求; -y:以表格方式輸出時,設置表格屬性。
-c參數是指定並發量,就是我一次對這個網站發起多少個連接。
-n 測試的次數,比如說我們用10的並發量向服務器去請求1000次的HTTP請求,相當於我們訪問了1000次指定的網頁。
# vmstat 2
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 1575384 130720 1495268 0 0 41 15 17 117 24 3 73 0 0
1 0 0 1571896 130720 1498780 0 0 0 0 728 784 5 2 94 0 0
28 0 0 1570148 130732 1489188 0 0 0 4 11455 3698 71 30 0 0 0
35 0 0 1573712 130732 1489232 0 0 0 0 11372 3867 72 28 0 0 0
33 0 0 1572968 130740 1489260 0 0 0 84 11106 3832 73 27 0 0 0
32 0 0 1572300 130740 1489284 0 0 0 0 10958 3835 73 28 0 0 0
35 0 0 1558512 130748 1498772 0 0 0 8 10803 4693 72 29 0 0 0
以上的測試條件,讓服務器的響應時間很慢,運行隊列(系統負載)很高。
修改參數:
# ab -c 100 -n 1000 http://10.1.1.21/thread-htm-fid-2.html
Benchmarking 10.1.1.21 (be patient)
Completed 100 requests 分10次測試所有請求,每次完成100個請求
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests
Server Software: nginx/1.0.15
Server Hostname: 10.1.1.21
Server Port: 80
Document Path: /thread-htm-fid-2.html
Document Length: 56666 bytes
Concurrency Level: 100 ######
Time taken for tests: 23.535 seconds <---整個測試消耗的時間
Complete requests: 1000 <---測試了1000個請求 #####
Failed requests: 28 <--- 有28個失敗。 #######
(Connect: 0, Receive: 0, Length: 28, Exceptions: 0)
Write errors: 0
Non-2xx responses: 28
Total transferred: 55747689 bytes 本次測試一共傳輸接受了多少字節的數據
HTML transferred: 55119348 bytes 屬於html文本代碼有多少
Requests per second: 42.49 [#/sec] (mean) 平均每秒鍾完成多少個請求
Time per request: 2353.484 [ms] (mean) 每個測試階段。完成每個階段的所有請求消耗多少時間 #########
Time per request: 23.535 [ms] (mean, across all concurrent requests) 每個請求消耗多少時間 #####
Transfer rate: 2313.21 [Kbytes/sec] received 每秒鍾的傳輸的數據量(吞吐量)#####
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 6 5.6 4 31
Processing: 500 2249 3628.9 1226 21294
Waiting: 485 2166 3642.5 1144 21294
Total: 510 2254 3630.0 1231 21306
Percentage of the requests served within a certain time (ms)
50% 1231
66% 1301
75% 1367
80% 1418
90% 4365
95% 7516
98% 21032
99% 21306
100% 21306 (longest request)
總結:
模擬100個並發請求的條件,測試結果表明服務器完成100的並發請求,需要消耗2353.484 ms
由於上面的測試是兩台電腦同時測試的,所有最終的結果是:
同時完成200個並發請求,需要消耗2353.484 ms。
測試的過程中,其他客戶端訪問頁面的時候非常慢,所以總結以上的測試壓力對於服務器來說,是非常大的。
nginx一個進程使用內存30M左右
php-cgi進程 每個占用20-30M
要么:降低測試壓力。
要么:調整參數,看一下能否把負載降低。
設定工作進程數目: 等於cpu的核心數。
worker_processes 2;
更均衡給工作進程分配cpu核心
worker_cpu_affinity 01 10;
允許工作進程最多打開多少個資源(文件描述符、連接)
worker_rlimit_nofile 65535; <---應該也罷ulimit -n 的值設定成一樣
events
{
use epoll; <--- Linux 2.6內核后才有的一種高效的網絡IO調度算法。
worker_connections 20480; <---允許處理多大並發請求。
}
http
{
include mime.types;
default_type application/octet-stream;
server_names_hash_bucket_size 128;
client_header_buffer_size 4k;
large_client_header_buffers 8 4k;
client_max_body_size 8m; //限制允許上傳的最大文件尺寸
keepalive_timeout 8; // 保持連接8秒,保持連接需要浪費內存,建立與撤銷連接需要消耗cpu,也會影響響應時間,如何設定?根據應用的類型,一般常規設定為8秒,相冊類型: 可以設定比瀏覽照片時間稍微長2秒鍾。
gzip off; //cpu資源過剩,然后打開壓縮可以省帶寬。一般針對文本進行壓縮,圖片不需要。
server {
# rewrite ^(.*)-htm-(.*)$ $1.php?$2 last; 取消偽靜態,因為需要cpu開銷
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)?$ {
expires 7d; //告訴客戶端緩存7天
}
location ~ .*\.(js|css)?$ {
expires 1d; //告訴客戶端緩存1天
}
}
//以下參數對本次調整意義不大,不會降低cpu開銷
fastcgi_connect_timeout 60;
fastcgi_send_timeout 60;
fastcgi_read_timeout 60;
fastcgi_buffer_size 4k;
fastcgi_buffers 64 4k; //內存足夠的情況下可以調整大一些
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
gzip on;
gzip_min_length 1k;
gzip_buffers 16 4k;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;
//以下所有的fastcgi_cache 相關參數在本次實驗中不是用
// 這些參數都是為了緩存php動態頁面的編譯結果,減少重復對相同頁面的編譯帶來的無用cpu開銷
fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=2:2 keys_zone=phpcache:30m inactive=5m;
fastcgi_cache phpcache;
fastcgi_cache_valid 200 302 1h;
fastcgi_cache_valid 301 1d;
fastcgi_cache_valid any 1m;
fastcgi_cache_min_uses 1;
fastcgi_cache_use_stale error timeout invalid_header http_500;
fastcgi_cache_key http://$host$request_uri;
// 不使用的原因:因為論壇不適合緩存,沒人喜歡看一個不會變化的論壇。其次,論壇頁面絕大多數都不會成功被緩存,因為頁面有cookie字段。
作業:
搜索 nginx優化 、 nginx十萬並發
http協議詳解
反向代理
實現簡單的負載均衡。
================================================
http協議的概要:
響應頭信息原始頭信息
Server nginx/1.0.15
Date Thu, 03 Jan 2013 06:31:20 GMT
Content-Type text/html
Content-Length 85
Last-Modified Thu, 03 Jan 2013 06:27:02 GMT
Connection keep-alive
Accept-Ranges bytes
請求頭信息原始頭信息
Host bbs.upl.com
User-Agent Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.24) Gecko/20111104 Red Hat/3.6.24-3.el6_1 Firefox/3.6.24
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language zh-cn,zh;q=0.5
Accept-Encoding gzip,deflate
Accept-Charset GB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive 115
Connection keep-alive
請求頭信息原始頭信息
Host www.upl.com
User-Agent Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.24) Gecko/20111104 Red Hat/3.6.24-3.el6_1 Firefox/3.6.24
Accept image/png,image/*;q=0.8,*/*;q=0.5
Accept-Language zh-cn,zh;q=0.5
Accept-Encoding gzip,deflate
Accept-Charset GB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive 115
Connection keep-alive
Referer http://bbs.upl.com/test.html <---來路
If-Modified-Since Thu, 03 Jan 2013 06:25:06 GMT
Cache-Control max-age=0
