首先確保nginx能正常鏈接phpphp
location ~ \.php$ { root html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; //這裏的document_root是上面定義的root html fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }
訪問 http://xx.xx.xx.xx/test.php 確保可以正常運行html
cd nginx vi ../fastphp/lib/php.ini //搜索memecache,若是沒有就編譯擴展 cd /usr/local/src/ //在php已經安裝好的狀況下,如何添加擴展? tar xvf memcache-2.2.7.tar cd memcache-2.2.7 ls //發現configure都沒有,該如何編譯呢? //指定想對哪一個php來編譯(fastphp) /usr/local/fastphp/bin/phpize ls //發現有了configure ./configure --help //指定php config的地址 ./configure --with-php-config=/usr/local/fastphp/bin/php-config make && make install cd /usr/local/fastoho/ vim lib/php.ini //搜索.so //修改以下 extension = /usr/local/fastphp/lib/php/extendions/no-debug-non-zts-10100525/memcache.so //殺一下php進程 ,pkill 是根據名字殺的意思 pkill -9 php //啓動php ./sbin/php-fpm cd /usr/local/nginx/ vim test.php phpinfo();
訪問 http://xx.xx.xx.xx/test.php ,由於會輸出phpinfo,因此在頁面中查看是否有memcache,說明php成功鏈接到了memcachemysql
mysql中建好表nginx
mysql -uroot -p use test show tables Tables_in_test select * from user
vim cong/nginx.cong locaction /{ //設置查找memchached的key set $memcheched_key "$uri?args" //拿到key以後去哪臺服務器找 memcached_pass 127.0.0.1:11211; //若是是404的話,回調 error_page 404 /callback.php } vim html/callback.php <?php //將請求的基本信息打印出來,發現是有請求的地址信息的 //print_r($_SERVER); //得到uri,用來當key $uri = $_SERVER['REQUEST_URI']; //分析出user2345.html中的uid $uid = substr($uri,5,strpos($uri,'.')-5); //echo $uid; //鏈接數據庫,查詢並寫入memcached $connn=mysql_connect('localhost','root',''); $sql = 'use test'; mysql_query($sql,$conn); $sql = 'set names utf8'; mysql_query($sql,$conn); $sql = 'select * from user where uid'.$uid; $rs = mysql_query($sql,$conn); echo 'from mysql query</br>' $user=mysql_fetch——assoc($rs); if(empty($user)){ echo 'no this user'; }else{ //print_r($user); $html = '<h1>'.$user['uname'].'</h1>'; echo $html; $mem = new memcache(); $mem->connect('localhost',11211); $mem->add($uri,$html,0,300); #mem->close(); } ./sbin/nginx -s reload
telnet localhost 11211 //注意這裏有/ add /user1.html 0 0 7 iamlisi
訪問http://xx.xx.xx.xx/user1.html ,會輸出iamlisi
訪問 http://xx.xx.xx.xx/user2.html , 由於沒有這個頁面,本應該輸出404,可是上面設置若是請求404,就回調PHP,輸出from mysql quesry no thos usergit
第一次訪問 http://xx.xx.xx.xx/user2.html 的時候,若是數據庫已經有了
from mysql query
Array([ui]=>2 [uname]=>zhangsan )
而後儲存到memceched
再次訪問
獲得
zhangsangithub
若是有多態memcached,某個key去請求哪一個memcached?PHP又幫nginx把內容存儲到哪一個mem?
以.user2.html爲例 a b c d e 5 臺server,請求誰?web
若是有多態memcached,某個key去請求哪一個memcached?PHP又幫nginx把內容存儲到哪一個mem?
以.user2.html爲例 a b c d e 5 臺server,請求誰?算法
整體思路:
請求的時候經過hash(uri),存儲的時候也經過hash(uri)sql
下載 第三方模塊ngx_httpo_consistent_hash(github上直接下載)數據庫
cd /usr/local/src wget xxxxxxxx(模塊地址) unzip xxxxxxxx cd /usr/local/src/nginx-1.4.2 ./conffigure --help | grep with ./conffigure --help | grep moudle ./configure --prefix=/usr/local/nginx/ --add-module=usr/local/src/ngx_http_consistent_hash-master Make && make instal
以ngx_http_php_memcache_standard_balancer-master爲例
1:解壓 到 path/ngx_module
配置:
./configure --prefix=/xxx/xxx --add_module=/path/ngx_module
編譯 安裝
Make && make instal
配置memcache集羣
安裝了memcached模塊就能夠在nginx裏面用了
upstream memserver { 把用到的memcached節點,聲明在一個組裏 hash_key $request_uri; // hash計算時的依據,以uri作依據來hash //這裏不寫localhost用具體的ip server 192.168.xx.xx:11211; server 192.168.xx.xx: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; }
啓動memcached
/usr/local/memcached/bin/memcached -u nodody -vv -p 11211 /usr/local/memcached/bin/memcached -u nodody -vv -p 11212
這個時候訪問 xx.xx.xx.xx/user4.html
經過查看memcached日誌,發現會規定的去一個memcached訪問,假如是11211但是第一次沒有查到結果,將請求傳給上節中的callback.php,php往11212中存儲,修改callback.php
<?php //將請求的基本信息打印出來,發現是有請求的地址信息的 //print_r($_SERVER); //得到uri,用來當key $uri = $_SERVER['REQUEST_URI']; //分析出user2345.html中的uid $uid = substr($uri,5,strpos($uri,'.')-5); //echo $uid; //添加多臺服務器 $mem = new memcached(); //這裏不用localhost用ip $mem->addServer('192.168.xx.xx',11211); $mem->addServer('192.168.xx.xx',11212); //鏈接數據庫,查詢並寫入memcached $connn=mysql_connect('localhost','root',''); $sql = 'use test'; mysql_query($sql,$conn); $sql = 'set names utf8'; mysql_query($sql,$conn); $sql = 'select * from user where uid'.$uid; $rs = mysql_query($sql,$conn); echo 'from mysql query</br>' $user=mysql_fetch——assoc($rs); if(empty($user)){ echo 'no this user'; }else{ //print_r($user); $html = '<h1>'.$user['uname'].'</h1>'; echo $html; //$mem = new memcache(); //$mem->connect('localhost',11211); $mem->add($uri,$html,0,300); #mem->close(); }
但是仍是有問題的,memcached請求的和經過php存儲的不是一個,由於nginx用的是一致性hash,php是用的簡單的算數法,取模法
經過查閱資料 memcached_hash_strategy (memcached hash策略)=========》standard 默認就是取模法 ,能夠改爲consistant,改爲以後php對memcached就會使用一致性hash
修改:
vi /usr/local/fastphp/lib/php.ini //添加下面這句話 memcached_hash_strategy=consistent //重啓nginx pkill -9 php -fpm /usr/local/fastphp/sbin/php-fpm
經過查看memcached日誌,11211 是get(第一次查的時候),11211也是add(經過php往裏面加的時候),以前是11211 是get(第一次查的時候),11212是add(經過php往裏面加的時候)
注意上面的nginx的配置和callback.php中的ip寫成ip,不要寫成localhost
至此達到了一致性。
在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 { //將傳遞過來的uri當作hash的參數,經過hash算法,判斷請求落在下面那個服務器上 consistent_hash $request_uri; server localhost:11211; server localhost:11212; }
在PHP.ini中,以下配置
memcache.hash_strategy = consistent
這樣: nginx與PHP便可完成對memcached的集羣與負載均衡算法.