Nginx

nginx 簡介

高性能WEB服務器javascript

Nginx ('engine x') 是一個高性能的HTTP和反向代理服務器,也是一個 IMAP/POP3/SMTP 代理服務器.
Nginx 是由Igor Sysoev爲落實訪問量第二的Rambler.ru 站點開發的.php

編譯安裝

root@# yum install pcre #先安裝pcre,正則表達式的庫
root@# ./configure --prefix=/usr/local/nginx
root@# make && make install
root@# cp /usr/local/nginx/conf/nginx.conf.default /usr/local/conf/nginx.conf

查看nginx文件底下目錄:css

conf // 配置文件目錄
html // 放置網頁文件
logs // 日誌目錄
sbin // 主要二進制程序文件

啓動nginxhtml

> ./sbin/nginx

報錯:前端

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

不能綁定80端口,80端口已經被佔用.
解決,把佔用80端口的軟件或服務關閉便可.java

> kill -9 標識
> pkill -9 服務
> pkill -9 http

編譯PHP

./configure --prefix=/usr/local/php --enable-fpm
cp /source-path/php.ini-development /usr/local/php/lib/php.ini

信號量

nginx有兩個進程,主進程msater進程。主進程不直接響應瀏覽器,是管理子進程使用。
瀏覽器訪問會到子進程中響應。node

> kill -INT pid(進程號)

> ps aux | grep 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 平滑的升級 (升級nginx)
WINCH Gracefully shutdown the worker processes 優雅關閉舊的進程(配合USR2來進行升級)
> kill -信號選項 nginx的主進程號
> kill -HUP 1480  (修改配置文件並不須要重啓服務器,才能生效)

在linux中,一個文件對應一個節點inode,inode是文件真正在磁盤上的位置。文件名字是表現。
日誌須要備份,文件在被nginx進程所打開,不能使用mv命令。
除了使用mv命令,還須要創建新的文件,同時須要告知nginx服務器,來讀取最新的日誌文件。mysql

> kill -信號控制 `cat /xxx/path/log/nginx.pid`
> kill -USR1 1480
> kill -USR1 `cat /xxx/path/log/nginx.pid`
> kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`

> ./sbin/nginx  -h

> ./sbin/nginx -s reload // 關閉
> ./sbin/nginx // 開啓
> ./sbin/nginx -s reopen // 重讀日誌,至關於 // kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`
> ./sbin/nginx -t // 檢查日誌文件是否準確

虛擬主機配置

nginx配置段linux

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

#user  nobody;
worker_processes  1; # 工做進程,子進程

Evnet區

通常配置nginx鏈接的特性
例如,1個worker能同時容許多少連接

Http段

http { // 這是配置http服務器的主要段
    Server1 { // 這是虛擬主機段
        Location { // 定位,把特殊的路徑或文件再次定位,如image目錄單獨處理// 如 .php 單獨處理

        }
    }
    Server2 {

    }
}

nginx配置文件:

#user  nobody;
worker_processes  1; # 工做進程,子進程

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;

# 配置nginx鏈接的特性
events {
# 1個worker能同時容許多少連接 
    worker_connections  1024;  # 這是指 一個子進程最大容許1024個連接
}


# http 段是配置http服務器的主要段
http {
    include       mime.types;
    default_type  application/octet-stream;


    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    server { # 這是虛擬主機
        listen       80;
        server_name  localhost;

        #access_log  logs/host.access.log  main;

        location / { #
            root   html;
            index  index.html index.htm;
        #error_page  404              /404.html;

        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        #
        #}

        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    include        fastcgi_params;
        #}

        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443;
    #    server_name  localhost;

    #    ssl                  on;
    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_timeout  5m;

    #    ssl_protocols  SSLv2 SSLv3 TLSv1;
    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers   on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

簡單的虛擬主機配置:

server {
    listen 80;
    server_name z.com;
    location / {
        root z.com; # root 路徑能夠是相對路徑 相對nginx安裝的根目錄
        # 能夠是絕對路徑   /usr/loca/nginx;
        index index.html index.htm;
    }
}
server {
    listen 2022;
    server_name z.com;
    location / {
        root /home/mm/twinkle/; 
        index index.html index.htm;
    }
}
> ifconfig // 查看信息

日誌管理

nginx的server段,能夠看到的信息有:
#access_log logs/host.access.log main;該虛擬主機,它的訪問日誌的文件是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類型的日誌,記錄了remove_addr...http_x_forwarded_for等選項.

remote_addr // 遠程地址
remote_user[$time_local] // 訪問遠程的時間, 若是訪問http頭信息沒有攜帶,是空的。
$request  // 請求方法`get` & `post`
$status // 請求狀態碼 例如:400
$body_bytes_sent // 主體發送的字節
$http_referer // referer頭
$http_user_agent // 用戶代理/蜘蛛
$http_x_forwarded_for // 被轉發的請求原始IP (在通過代理時,代理把原本IP加在此頭信息中,傳輸原始IP. )

蜘蛛:搜索引擎的服務器.
百度robots
蜘蛛協議.

Nginx容許針對不一樣的server作不一樣的Log(有的web服務器不支持,如:lighttp)

access_log logs/z.com.access.log main; // 配置單獨的log日誌

定時任務

shell 腳本

shell 腳本注意空格

變量聲明

a // 定義
$a // 使用

輸出執行返回結果

echo `date -d yesterday %Y%m%d` // 第一種: ``
echo $(date -d yesterday %Y%m%d) // 第二種: $()

日誌切割

#!/bin/bash
LOGPATH=/usr/local/nginx/logx/z.com.access.log
BASEPATH=/data

bak=$BASEPATH/$(date -d yesterday +%Y%m%d%H%M).zcom.access.log

#echo $bak

mv $LOGPATH $bak
touch $LOGPATH

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

Location

location 有定位的意思,根據Uri來進行不一樣定位

在虛擬主機的配置中,是必不可少的location能夠把網站的不一樣部分,定位到不一樣的處理方式上。
好比。碰到.php,如何調用PHP解釋器,這時須要location。

location 的語法

location [=|~|~*|^~] patt {
}

中括號能夠不寫任何參數,此時稱之爲通常匹配
也能夠寫參數
所以,大類型能夠分爲3種:

  1. location = patt {} [精準匹配]

  2. location patt {} [通常匹配]

  3. location ~ patt {} [正則匹配]

=開頭表示精確匹配
^~開頭表示uri以某個常規字符串開頭,不是正則匹配
~開頭表示區分大小寫的正則匹配
~*開頭表示不區分大小寫的正則匹配
/通用匹配,若是沒有其它匹配,任何請求都會匹配到

精準匹配

如何發揮做用?

首先看是否有精準匹配,若是有,則中止匹配過程.

location = patt {
    config A
}

若是 $uri == patt, 匹配成功,使用 config A

判斷使用的那個location

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

若是訪問的是:http://www.xxx.com
定位流程:

  1. 精準匹配中 /,獲得index 頁爲index.htm

  2. 再次訪問 /index.htm, 這次內部跳轉uri是/index.htm,跟目錄爲/usr/local/nginx/html

  3. 最終結果,訪問了 /usr/local/nginx/html/index.htm

精準匹配測試

location = /index.htm { // 添加匹配文件,而非目錄.
}
location /index.htm {
}

通常匹配精準匹配衝突時,精準發揮做用.

正則匹配

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

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

若是訪問: http://xxx.com/image/a.jpg
這時,//image/a.jpg 匹配,同時image正則與image/a.jpg也能匹配,誰發揮做用?

通常匹配正則匹配衝突,正則發揮做用。

圖片真正訪問的地址:/var/www/image/a.jpg

locatiorn / {
  root /usr/loca/nginx/html;
  index index.html index.htm;
}

location /foo {
  root /var/www/html;
  index inde.html
}

當訪問http://xxx.com/foo

對於uri爲/foo,兩個location的patt,都可以匹配。
/可以左前綴匹配,/foo也能左前綴匹配.
此時真正訪問的是/var/www/html/foo.
緣由:/foo匹配更長,所以使用.

location總體流程

正則匹配有順序關係,從上到下.有匹配上的就退出.
普通匹配不須要考慮順序,挨個匹配,最長的就是匹配上.

clipboard.png

location 的匹配過程:

  1. 先判斷精準匹配,若是匹配成功,當即返回結果並結束解析過程.

  2. 判斷通常命中,若是有多個命中,記錄下來最長的匹配結果. (注意:記錄但不結束,最長爲準).

  3. 繼續正則表達式的解析結果,按配置裏的正則表達式順序爲準,由上到下開始匹配,一旦匹配成功,理解返回結果,並結束解析過程.

延伸分析:

  • 普通匹配順序無所謂,是按照匹配長短來肯定的.

  • 正則匹配是按照順序來匹配.

rewrite

rewrite(重寫)語法詳解

重寫的規則能夠放在location或者service中.

經常使用的命令

  1. if 空格 (條件) {} # 設定條件,再進行重寫

  2. set # 設置變量

  3. return # 返回狀態碼

  4. break # 跳出rewrite

  5. rewrite # 重寫

if 語法

if 空格 (條件) { // 空格不容許少
    重寫默認
}

條件寫法:

  1. =來判斷相等,用於字符串比較

  2. ~用正則來匹配(區分大小寫) , ~*用來正則匹配(不區分大小寫)

  3. -f-d-e 來判斷是否爲文件,爲目錄,是否存在.

相等

location / {
  if ($remote_addr = 192.168.1.12) {
      return 403;
  }
  root html;
  index index.html index.htm;
}

正則

location / {
  if ($http_user_agent ~* chrome) {
      rewrite ^.*$ /chrome.html;
      #  不加 break; 會致使循環重定向, 頁面現象, 500 內部服務器錯誤
      break;
  }
  root html;
  index index.html index.htm;
}

-f-d-e
除了 nginx.conf配置文件中能夠看到變量
在文件conf/fastcig.conf查看所有nginx能夠引用的變量.

$fastcgi_script_name 當前訪問的uri.
例如:/abc.html

location {
    if (!-e $document_root$fastcgi_script_name) {
      rewrite ^.*$ /404.html;
      break;
    }
    root html;
    index index.html index.htm;
}

http://xxx.com/abcds.html,不存在的頁面爲例.
注意:此處須要加break,由於觀察訪問日誌,日誌中顯示的訪問路徑,依然是地址欄輸入的uri.(GET /abcds.html HTTP/1.1)。
提示:服務器內部的rewrite和302跳轉不同。跳轉的話是URL變化,從新發送請求404.html,而內部rewrite,僅僅是從新讀取404.html的內容,上下文沒有變化,就是 fastcgi_script_name 仍然是 /abcds.html,所以會循環重定向。

set
set是設置變量使用,能夠達到多條件判斷時作標記使用。
達到apache下的rewrite_condition的效果。

判斷chrome瀏覽器,而且不用break。

if ($http_user_agent ~* chrome) {
  set $ischrome 1;
}

if ($fastcgi_script_name = chrome.html) {
  set $ischrome 0;
}

if ($ischrome 1) {
 rewrite ^.*$ chrome.html;
}

全局變量
能夠做用if判斷的全局變量

$args: 等於請求行中的參數,同$query_string
$content_length: 請求頭中的Content-length字段
$content_type: 請求頭中的Content-Type字段
$document_root: 當前請求在root指令中指定的值
$host: 請求主機頭字段,不然爲服務器名稱
$http_user_agent: 客戶端agent信息
$http_cookie: 客戶端cookie信息
$limit_rate: 能夠限制鏈接速率
$request_method: 客戶端請求的動做,一般爲GET或POST
$remote_addr: 客戶端的IP地址
$remote_port: 客戶端的端口
$remote_user: 已經通過Auth Basic Module驗證的用戶名
$request_filename: 當前請求的文件路徑,由root或alias指令與URI請求生成
$scheme: HTTP方法(如http,https)
$server_protocol: 請求使用的協議,一般是HTTP/1.0或HTTP/1.1
$server_addr: 服務器地址,在完成一次系統調用後能夠肯定這個值
$server_name : 服務器名稱
$server_port: 請求到達服務器的端口號
$request_uri: 包含請求參數的原始URI,不包含主機名,如:」/foo/bar.php?arg=baz」
$uri: 不帶請求參數的當前URI,$uri不包含主機名,如」/foo/bar.html」
$document_uri: 與$uri相同

編譯PHP

安裝mysql:yum install mysql mysql-devel

nginx+php的編譯.
apache通常是把php看成本身的一個模塊來啓動的,而nginx則是把http請求的變量(如get,user_agent等)轉發給php進程,即PHP獨立進程,與nginx進行通信.稱之爲fastcgi運行方式.
所以,爲此apache所編譯的PHP,是不能用於nginx的,須要從新編譯。

注意,編譯的PHP有以下功能:

  1. 連接mysql

  2. gd庫

  3. ttf字體

  4. fpm(fastcgi)方式運行.

前期安裝

> yum install gd
> yum install freetype
> yum install gd-devel

配置與安裝

./configure --prefix=/usr/local/fastphp \
--with-mysql=mysqlnd \
--enable-mysqlnd \
--with-gd \
--enable-gd-native-ttf \
--enable-gd-jis-conv \
--enable-fpm

make && make install

編譯完畢後:

> cp /usr/local/src/php-5.4.19/php.ini-development ./lib/php.ini

> cd etc/
> cp etc/php.fpm.conf.default etc/php-fpm.conf

運行:

> ./sbin/php-fpm

nginx與PHP是相互獨立的,PHP以9000端口做爲進程獨立運行。nginx接收到請求,把請求轉給PHP進程
配置核心:把請求的信息轉發給9000端口的PHP進程,讓PHP進程處理指定目錄下的PHP文件.

修改nginx配置文件:conf/nginx.conf

location ~ \.php$ {
    root           html;
    fastcgi_pass   127.0.0.1:9000; # 發送到9000端口進程
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;  # 尋找PHP目錄地址
    include        fastcgi_params;
}

解釋

  1. 碰到PHP文件

  2. 把根目錄定位到html

  3. 把請求上下文轉交給9000端口的PHP進程。

  4. 並告知PHP進程,當前腳本是$document_root$fastcgi_script_name(注:PHP會去尋找當前腳本位置,因此腳本位置要指對)

  5. PHP處理以後,返回給nginx服務器.

url重寫

注意:用url重寫,正則裏若是有{},整個正則須要使用""包起來

靜態文件地址重寫到動態目錄地址
例如:goods-10.html 重寫到 goods.php?id=10

location /zf {
    rewrite "goods-(\d{1,7}).html" /zf/goods.php?id=$1;
}

正則表達式支持後向引用

location /zf {
    index index.php;
    rewrite goods-([\d]+)\.html$ /zf/goods.php?id=$1;
    rewrite article-([\d]+)\.html$ /zf/article.php?id=$1;
    rewrite category-(\d+)-b(\d+)\.html /zf/category.php?=$1&barnd=$2;
}

經過兩次路由對比寫出正則

category.php?id=3&barnd=1&price_min=200&price_max=1700&filter_attr=167.229.202.199
category-3-b2-min200-max700-attr167.229.202.199.html

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

/category.php?id=3&barnd=2&price_min=0&price_max=0&page=2&sort=goods_id&order=DESC

/category-3-b0-min0-max9-attr0-1-goods_id-DESC.html

category-(\d+)-b(\d+)-min(\d+)-max(\d+)-attr([\d\.]+)-(\d+)-(\w+)-(\w+)\.html caetgory.php?id=$1&barnd=$2&price_min=$3&price_max=$4&filter_attr=$5&page=$6&sort=$7&order=$8.html

gzip壓縮

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

響應頭中有:

Content-Encoding: gzip

原理:
瀏覽器-->請求-->聲明能夠接受gzip壓縮或default壓縮或compress或sdch壓縮(sdch是google倡導的一種壓縮方式,目前支持的服務器尚很少)
從http協議角度看,請求頭,聲明acceopt->encoding:gzip default sdch (是壓縮算法)
服務器-->迴應-->把內容gzip方式壓縮-->發送瀏覽器 --> 接收gzip壓縮內容(瀏覽器接收以後是壓縮後的二進制文件)--> 解碼gzip --> 瀏覽

gzip經常使用參數

gzip on|off # 是否開啓gizp
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則知足1.1的才壓縮)
gzip_proxied  # 設置請求着代理服務器如何緩存內容
gzip_types text/plain  appliction/xml #對哪些類型的文件用壓縮 如txt,xml,html,css
gzip_vary on|off #是否傳輸gzip壓縮標誌

寫在server段上

server {
    gzip on;
    gzip_buffers 32 4K;
    gzip_comp_level 6;
    gzip_min_length 200;
    gzip_types text/css text/xml application/x-javascript;
}

注意:圖片/mp3等的二進制文件,沒必要壓縮,由於壓縮比較小,好比100->80字節,並且壓縮也是壓縮也是耗費CPU資源

expires緩存

expires緩存提高網站負載

nginx緩存設置,提升網站性能。
對於網站的圖片,尤爲是新聞站,圖片一旦發佈,改動的可能性很是小,用戶訪問一次以後,圖片緩存到瀏覽器端,且時間比較長的緩存。使用到nginx的expires

nginx中設置過時時間,在location段,或if中寫:

expires 30s;
expires 30m; // 2分鐘過時
expires 2h; // 2小時過時
expires 30d; // 30天過時

location ~* .\(git|jpg|jpeg|png) {
    root html;
    expires 1d; # 1天
}

注意:服務器的日期須要準確,若是服務器的日期和實際日期,可能致使緩存失效。

304也是一種緩存手段,原理是:服務器響應文件內容,同時響應etag標籤(內容簽名)和last_modified_since 2個標籤值,瀏覽器下次請求時,瀏覽器要發送這兩個頭信息標籤,服務器檢測文件有沒有發生變化,沒有變化的話,返回頭信息(etag和last_modified_since)瀏覽器知道內容無改變,因而直接調用本地緩存。

這過程當中,也請求了服務器,可是傳輸內容極少,對於變化週期較短,如靜態html,css。

反向代理

nginx反向代理服務器

使用nginx作反向代理和負載均衡支持兩個用法:

  1. proxy

  2. upstream

nginx不本身處理php的相關請求,而是把php的相關轉發給apache處理(php不讓nginx跑)

clipboard.png

這種形式,就是動靜分離,更爲嚴謹的說法是反向代理

註釋掉nginx解析php的配置,經過代理形式轉到apache解析php,(要保證apache可以支持php)

location ~ \.php$ {
    proxy_prss http://102.168.1.10:8000;
}

nginx服務器經過中間的代理,交代給誰完成任務,或者交代給幾我的作,都是可行的。
把任務分配給多臺機器,就是負載均衡。

負載均衡

反向代理後端若是有多臺服務器,天然可造成負載均衡。
可是proxy_pass 如何指向多態服務器?
把多臺服務器用up_stream指定綁定在一塊兒並起一個組名,而後proxy_pass指向該組.
配置服務器:

server {
    listen 81;
    server_name localhost;
    root /var/www/image;
}
server {
    listen 82;
    server_name localhost;
    root /var/www/image;
}

增長組:

#upstream 組名字 {
#    server ip wight=1(權重) fail_timeout=3(鏈接不上的時間) max_fails=2(鏈接不上的次數)
#}
upstream imageserver {
    server 192.168.1.100:81 weight=1 fail_timeout=3 max_fails=2;
    server 192.168.1.100:82 fail_timeout=3 max_fails=2;
}

而後修改反向代理配置代碼:

location ~* \.(jpg|jpge|git|png) {
    proxy_pass http://imageserver;
}

默認的負載均衡的算法,就是正對後端服務器的順序,逐個請求。也有其它的負載均衡算法,如一致性哈希,須要安裝第三方模塊ngx_http_upstream_consistent_hash

問題:
反向代理致使了後端服務器的IP,爲前端服務器的IP,而不是客戶真正的IP
解決方式:
使用x-forwar
爲了避免改變用戶的IP,須要經過變量存儲IP帶過去,通常約定俗成是經過頭信息是:

proxy_set_header X-Forwarded-For $remote_addr;

location ~* .(jpg|jpge|git|png) {

proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://imageserver;

}

鏈接memcached

編譯或安裝memcached

git clone https://github.com/memcached/memcached.git
cd memcached
sudo apt-get install autotools-dev
sudo apt-get install automake
./autogen.sh // 生成configure文件
./configure --with-php-config=/etc/php/7.1/fpm // 配置指定php的配置文件
make && make install

安裝好以後提示的信息:

安裝好後:Installing shared extensions:     /usr/local/sxin/php7/lib/php/extensions/no-debug-zts-20151012/

修改php.ini配置文件

entension=/usr/local/sxin/php7/lib/php/extensions/no-debug-zts-20170722/memcached.so

刪除進程,重啓php

pkill -9 php

測試是否成功:

<?php
phpinfo();
?>

在phpinfo中是否輸出memcache模塊

安裝過程當中出現的錯誤:

clipboard.png

方法1:
須要安裝libevent,可能會報沒法安裝,使用wget方式安裝

sudo apt-get install libevent libevent-deve

clipboard.png

方法2:

wget http://monkey.org/~provos/libevent-1.4.14b-stable.tar.gz
tar -zxvf libevent-1.4.14b-stable.tar.gz 
cd libevent-1.4.14b-stable
./configure --prefix=/usr  
make && make install

nginx直連memcached

原理:

clipboard.png

  • nginx須要設定key,去查memcached

  • 若是不存在須要回調php,並把key值傳給php

nginx請求memcached時,用什麼作key?
通常用 uri arg作key, 如abc.php?id=2

location / {
    set $memcached_key "$uri";
    memcacehd_pass 127.0.0.1:11211;
    error_page 404 /callback.php
}

問題:
若是多臺memcaehed,某個key去請求那個memcached?
php又幫nginx把內容存儲到哪一個memcached?
回調的php,有把信息寫在哪兒?
最終問題:多態memcached,nginx與php,如何保持集羣上的算法同步.

  • 要有穩定集羣算法

  • nginx與php對於memcached的算法要同步

解決:
nginx hash($uri) --> 某臺memcached
php hash($uri) --> 同一臺memcached
須要一個hash規則
這樣才能保證分佈式的數據同步。
默認的nginx分佈式是經過計數器來輪流請求,須要第三方模塊和一致性哈希應用

第3方模塊編譯

第3方模塊編譯和一致性哈希應用

編譯第三方模塊

下載模塊,而後從新指定nginx編譯參數

./configure --prefix=/usr/local/nginx --add-module=/usr/local/src/ngx_http_consistent/hash/
make && make install

安裝模塊後

upstream memserver {
    consistent_hash $requrest_uri;
    #server localhost:11211;
    #server localhost:11212;
    #server localhost:11213;
    server 192.168.1.100:11211;
    server 192.168.1.100:11212;
    server 192.168.1.100:11213;
}

server {
    listent 80;
    server_name localhost;
    location / {
        set $memcached_key "$uri";
        memcached_pass memserver;
        error_page 404 /callback.php;
    }
}

在php.ini中修改默認hash取模的策略

memcache.hash_strategy=consistent

php代碼

<?php
// 添加多臺服務器, // php要添加和nginx同樣 的服務器

$mem = new memcache();
// $mem->addServer('localhost', 11211);
// $mem->addServer('localhost', 11212);
// $mem->addServer('localhost', 11213);

$mem->addServer('192.168.1.100', 11211);
$mem->addServer('192.168.1.100', 11212);
$mem->addServer('192.168.1.100', 11213);

注意:
在 upstream作負載均衡時,要用IP或遠程主機名,不能使用localhsot

大訪問量優化

大訪問量優化總體思路

高性能的服務器的架設

網站的請求量是絕對的,很難降下來。

對於高性能網站,請求量大,如何支撐?

  • 要減小請求
    對於開發人員 -- 合併css,背景圖片,壓縮文件,減小mysql查詢

  • nginx的expiress,利用瀏覽器緩存等,減小查詢

  • 利用cdn來響應請求

  • 最終剩下來的,不可避免的請求 -- 服務器集羣 + 負載均衡來支撐

如何響應高併發請求

既然響應是不可避免的,要作的是把工做內容「平均」分給每臺服務器,最理想的狀態:每臺服務器的性能都被充分利用。

服務器講究:
像存儲數據的,cpu不必定要強,可是硬盤必定要好,安裝了ssd固態硬盤。
有的計算複雜的,cpu要高服務器
有的計算不復雜,可是進程多,內存多的服務器

服務器分清:計算密集,IO密集,進程密集。

nginx觀察統計模塊

./configure --prefix=/usr/local/nginx/ --add-module=/usr/local/ngx_http_consistent_hash_master --with-http_stub_status_module
make && make install

修改nginx.conf,配置統計模塊參數

location /status {
    stub_status on;
    access_log off;
    allow 192.168.1.100;
    deny all;
}

ab工具壓力測試,觀察數據

優化思路

對於nginx 來講,nginx請求,來響應。訪問,mysql或硬盤中的.html文件等等

  1. 創建socket鏈接

  2. 打開文件,並沿socket返回

創建socket鏈接可否不少,打開文件是否可以打開不少。

socket中處理的包括:系統層面nginx
系統層面:

最大鏈接數 somaxconn
洪水攻擊 // 不作洪水抵禦 
加快tcp鏈接回收 recycle
空的tcp是否容許回收利用 reuse

echo 50000 > /proc/sys/net/core/somaxconn
echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle
echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse

echo 0 > /proc/sys/net/ipve4/tcp_syncookies

nginx:

// 每一個子進程打開的鏈接(worker_connections)
evnets {
    worker_connnections 10240;
}
//  http鏈接關閉 
http {
    keepalive_timeout 0;
}

文件中處理的包括:系統層面nginx
系統層面的限制:

ulimit -n 50000 // 設置一個比較大的值

nginx:

// 子進程容許打開的文件(worker_limit_onfile)
// nginx配置文件中的全局區修改
worker_limit_nofile 10000;

響應頭中:Connection: keep-alive
防止頻繁的tcp,還保持時間的話,就浪費

http {
    keepalive_timeout 0;
}

時間修改成0以後,Connection: close

相關文章
相關標籤/搜索