1、nginx與memcached整合
#安裝memcached支援的事務庫libevent
<code>wget https:</code><code>//github</code><code>.com</code><code>/libevent/libevent/releases/download/release-2</code><code>.0.22-stable</code><code>/libevent-2</code><code>.0.22-stable.</code><code>tar</code><code>.gz</code>
<code>tar</code> <code>zxf libevent-2.0.22-stable.</code><code>tar</code><code>.gz </code>
<code>cd</code> <code>libevent-2.0.22-stable</code>
<code>.</code><code>/configure</code> <code>--prefix=</code><code>/usr/local/libevent</code>
<code>make</code> <code>&& </code><code>make</code> <code>install</code>
<code>echo</code> <code>$?</code>
<code>cd</code> <code>..</code>
#接下來安裝memcached:
<code>wget http:</code><code>//www</code><code>.memcached.org</code><code>/files/memcached-1</code><code>.4.35.</code><code>tar</code><code>.gz</code>
<code>tar</code> <code>zxf memcached-1.4.35.</code><code>tar</code><code>.gz</code>
<code>cd</code> <code>memcached-1.4.35</code>
<code>.</code><code>/configure</code> <code>--prefix=</code><code>/usr/local/memcached</code> <code>--with-libevent=</code><code>/usr/local/libevent</code>
#運作memcached
[root@nginx ~]# /usr/local/memcached/bin/memcached -d -u nobody -vv
#配置nginx配置檔案nginx.conf,定位user的uri交給memcached做緩存
#添加location定位:
<code>location ~* user {</code>
<code> </code><code>set</code> <code>$memcached_key </code><code>"$uri"</code><code>; </code><code>#設定memcached的key為uri</code>
<code> </code><code>memcached_pass 192.168.146.132:11211; </code><code>#連結memcached</code>
<code> </code><code>error_page 404 </code><code>/callback</code><code>.php; </code><code>#錯誤定位</code>
<code> </code><code>}</code>
#加載nginx配置
nginx -s reload
#在memcached中寫入一條URI資料,測試整合是否成功
<code>[root@nginx ~]</code><code># telnet 192.168.146.132 11211</code>
<code>Trying 192.168.146.132...</code>
<code>Connected to 192.168.146.132.</code>
<code>Escape character is </code><code>'^]'</code><code>.</code>
<code>add </code><code>/user1</code><code>.html 0 0 7</code>
<code>iamlisi </code>
<code>STORED</code>
<code>quit</code>
#通路http://192.168.146.132/user1.html如能看到iamlisi,那麼nginx與memcache整合成功了!
2、整合PHP與memcahced
#安裝PHP擴充子產品memcache
<code>wget http:</code><code>//pecl</code><code>.php.net</code><code>/get/memcache-2</code><code>.2.7.tgz</code>
<code>tar</code> <code>zxvf memcache-2.2.7.tgz</code>
<code>cd</code> <code>memcache-2.2.7</code>
<code>/usr/local/php/bin/phpize</code>
<code>.</code><code>/configure</code> <code>--</code><code>enable</code><code>-memcache --with-php-config=</code><code>/usr/local/php/bin/php-config</code> <code>--with-zlib-</code><code>dir</code>
pkill php-fpm #殺死php-fpm程序
php-fpm #啟動php-fpm
http://192.168.146.132/test.php能看到memcache子產品就成功了
#測試PHP與memcached
<code>vim </code><code>/usr/local/nginx/html/callback</code><code>.php</code>
<code><?php</code>
<code>print_r($_SERVER);</code>
<code>?>php</code>
#通路http://1982.168.146.132/user2.html 此uri在memcached中不存在,就會回調到callback.php處理請求,結果如下:
<code>Array</code>
<code>(</code>
<code> </code><code>[USER] => nobody</code>
<code> </code><code>[HOME] => /</code>
<code> </code><code>[FCGI_ROLE] => RESPONDER</code>
<code> </code><code>[SCRIPT_FILENAME] => /usr/local/nginx/html/callback.php</code>
<code> </code><code>[QUERY_STRING] => </code>
<code> </code><code>[REQUEST_METHOD] => GET</code>
<code> </code><code>[CONTENT_TYPE] => </code>
<code> </code><code>[CONTENT_LENGTH] => </code>
<code> </code><code>[SCRIPT_NAME] => /callback.php</code>
<code> </code><code>[REQUEST_URI] => /user2.html</code>
<code> </code><code>[DOCUMENT_URI] => /callback.php</code>
<code> </code><code>[DOCUMENT_ROOT] => /usr/local/nginx/html</code>
<code> </code><code>[SERVER_PROTOCOL] => HTTP/1.1</code>
<code> </code><code>[REQUEST_SCHEME] => http</code>
<code> </code><code>[GATEWAY_INTERFACE] => CGI/1.1</code>
<code> </code><code>[SERVER_SOFTWARE] => nginx/1.12.1</code>
<code> </code><code>[REMOTE_ADDR] => 192.168.146.1</code>
<code> </code><code>[REMOTE_PORT] => 14187</code>
<code> </code><code>[SERVER_ADDR] => 192.168.146.132</code>
<code> </code><code>[SERVER_PORT] => 80</code>
<code> </code><code>[SERVER_NAME] => localhost</code>
<code> </code><code>[REDIRECT_STATUS] => 200</code>
<code> </code><code>[HTTP_HOST] => 192.168.146.132</code>
<code> </code><code>[HTTP_CONNECTION] => keep-alive</code>
<code> </code><code>[HTTP_UPGRADE_INSECURE_REQUESTS] => 1</code>
<code> </code><code>[HTTP_USER_AGENT] => Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36</code>
<code> </code><code>[HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8</code>
<code> </code><code>[HTTP_ACCEPT_ENCODING] => gzip, deflate</code>
<code> </code><code>[HTTP_ACCEPT_LANGUAGE] => zh-CN,zh;q=0.8</code>
<code> </code><code>[PHP_SELF] => /callback.php</code>
<code> </code><code>[REQUEST_TIME] => 1503552110</code>
<code>)</code>
3、使用PHP讓memcached連結MySQL查詢key與value并存入memcached,
#接下來我們寫個PHP程式,連結資料庫,讓memcached找不到的uri就回調給PHP,然後PHP去連結資料庫,查找資料後給memcached:
<code>cat</code> <code>html</code><code>/callback</code><code>.php</code>
<code>//print_r</code><code>($_SERVER);</code>
<code>//</code><code>擷取UID用來做key</code>
<code>$uri = $_SERVER[</code><code>'REQUEST_URI'</code><code>];</code>
<code>//</code><code>分析出uir中的uid号</code>
<code>$uid = substr($uri,5,strpos($uri,</code><code>'.'</code><code>)-5);</code>
<code>//echo</code> <code>$uid;</code>
<code>//</code><code>連結資料庫,查詢并寫入memcached</code>
<code>$conn = mysql_connect(</code><code>'localhost'</code><code>,</code><code>'root'</code><code>,</code><code>'123.com'</code><code>);</code>
<code>$sql = </code><code>'use test'</code><code>;</code>
<code>mysql_query($sql,$conn);</code>
<code>$sql = </code><code>'set names utf8'</code><code>;</code>
<code>$sql = </code><code>'select * from user where uid='</code><code>.$uid;</code>
<code>$rs = mysql_query($sql,$conn);</code>
<code>echo</code> <code>'from mysql query<br />'</code><code>;</code>
<code>$user = mysql_fetch_assoc($rs);</code>
<code>if</code> <code>(empty($user)) {</code>
<code> </code><code>echo</code> <code>'no this user'</code><code>;</code>
<code>} </code><code>else</code> <code>{</code>
<code>//</code> <code>print_r($user);</code>
<code> </code><code>$html = </code><code>'<h1>'</code><code>. $user[</code><code>'uname'</code><code>].</code><code>'</h1>'</code><code>;</code>
<code> </code><code>echo</code> <code>$html;</code>
<code> </code><code>$mem = new memcache();</code>
<code> </code><code>$mem->connect(</code><code>'192.168.146.132'</code><code>,11211);</code>
<code> </code><code>$mem->add($uri,$html,0,300);</code>
<code> </code><code>$mem->close();</code>
<code>}</code>
#此處我們要在資料庫中建立test庫和user表,并寫入uid和uname字段資料:
#注意:callback.php檔案調用的庫和表,字段要對應建立
<code>mysql> create database </code><code>test</code><code>;</code>
<code>mysql> use </code><code>test</code><code>;</code>
<code>mysql> create table user(</code>
<code> </code><code>-> uid int(11) not null,</code>
<code> </code><code>-> </code><code>uname</code> <code>varchar(255) not null,</code>
<code> </code><code>-> primary key (uid));</code>
<code>mysql> insert into user (uid,</code><code>uname</code><code>) values(1,</code><code>'i am memcached'</code><code>);</code>
<code>mysql> insert into user (uid,</code><code>uname</code><code>) values(2,</code><code>'dslajfflsaj;gljdaslgjlajfdalsjf'</code><code>);</code>
#此時通路uir,首先會轉發到memcached處理,memcached中沒有key就會回調給callback.php處理,然後PHP連結資料庫,查詢uri資料,然後memcached會寫入key與value,并将資料傳回給用戶端。
http://192.168.146.132/user1.html
#memcached顯示資料動态:
<code><36 new auto-negotiating client connection</code>
<code>36: Client using the ascii protocol</code>
<code><36 add </code><code>/user1</code><code>.html 1 300 122</code>
<code>>36 STORED</code>
<code><36 connection closed.</code>
<code><36 get </code><code>/user1</code><code>.html</code>
<code>>36 sending key </code><code>/user1</code><code>.html</code>
<code>>36 END</code>
4、配置memcached群架,nginx和PHP使用一緻性哈希(ip-hash)
#當使用memcached群集時,會遇到資料寫入memcached不一緻,因為nginx模式使用round-robin(輪詢)方式通路memcached伺服器,就會造成寫入和讀出資料不在同一伺服器的問題,為此nginx提供了ip-hash基于Ip的一緻性雜湊演算法,它會記錄通路IP,下次通路時同一ip會通路上次記錄的伺服器。
官方參考文檔:https://www.nginx.com/resources/wiki/modules/consistent_hash/
#下載下傳nginx hash子產品并安裝:
<code>cd</code> <code>/root/tools</code>
<code>wget https:</code><code>//github</code><code>.com</code><code>/replay/ngx_http_consistent_hash/archive/master</code><code>.zip</code>
<code>unzip master.zip</code>
#檢視nginx編譯參數
<code>[root@LNMP tools]</code><code># nginx -V</code>
<code>nginx version: nginx</code><code>/1</code><code>.8.1</code>
<code>built by gcc 4.4.7 20120313 (Red Hat 4.4.7-18) (GCC) </code>
<code>built with OpenSSL 1.0.1e-fips 11 Feb 2013</code>
<code>TLS SNI support enabled</code>
<code>configure arguments: --user=nginx --group=nginx --prefix=</code><code>/usr/local/nginx</code> <code>--with-http_ssl_module --with-http_stub_status_module --with-http_ssl_module --add-module=</code><code>/root/tools/nginx-1</code><code>.8.1</code><code>/nginx-rtmp-module</code>
#進入nginx源碼目錄,添加子產品安裝
<code>[root@LNMP tools]</code><code># cd nginx-1.8.1</code>
<code>[root@LNMP nginx-1.8.1]</code><code># ./configure --user=nginx --group=nginx --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module --with-http_ssl_module --add-module=/root/tools/nginx-1.8.1/nginx-rtmp-module --add-module=/root/tools/ngx_http_consistent_hash-master/</code>
<code>[root@LNMP nginx-1.8.1]</code><code>#make && make install</code>
#模拟memcache叢集,區分端口啟動三個memcached
<code>memcached -d -u nobody -p 11211 -vv</code>
<code>memcached -d -u nobody -p 11212 -vv</code>
<code>memcached -d -u nobody -p 11213 -vv</code>
#nginx配置檔案http段添加upstram子產品:
<code>upstream mcserver {</code>
<code> </code><code>consistent_hash $request_uri; </code><code>#指定使用雜湊演算法,針對memcached,請參考文檔</code>
<code> </code><code>server 192.168.146.132:11211;</code>
<code> </code><code>server 192.168.146.132:11212;</code>
<code> </code><code>server 192.168.146.132:11213;</code>
#并在location中反向代理到mcserver叢集:
具體參考文檔:http://nginx.org/en/docs/http/ngx_http_memcached_module.html#memcached_pass
<code>location ~* </code><code>/user</code> <code>{</code>
<code> </code><code>set</code> <code>$memcached_key </code><code>"$uri"</code><code>; </code><code>#将uri配置為memcached的key</code>
<code> </code><code>memcached_pass mcserver; </code><code>#代理到memcached叢集</code>
<code> </code><code>error_page 404 = </code><code>/callback</code><code>.php; </code><code>#memcached中找不到key将回調到此檔案</code>
#重新加載nginx配置
#修改php配置為hash查詢
#具體參考文擋:http://cn2.php.net/manual/en/memcache.ini.php#ini.memcache.hash-strategy
<code>vim </code><code>/usr/local/php/etc/php</code><code>.ini</code>
<code>memcache.hash_strategy=consistent </code><code>#添加,使用一緻性哈希</code>
#重新啟動php-fpm
<code>pkill -9 php-fpm</code>
<code>netstat</code> <code>-lntup|</code><code>grep</code> <code>9000</code>
<code>php-fpm</code>
#修改回調代碼,建立memcached叢集連結
<code>//</code><code>建立memcached叢集連結</code>
<code>$mem = new memcache();</code>
<code>$mem->addServer(</code><code>'192.168.146.132'</code><code>,11211);</code>
<code>$mem->addServer(</code><code>'192.168.146.132'</code><code>,11212);</code>
<code>$mem->addServer(</code><code>'192.168.146.132'</code><code>,11213);</code>
<code> </code><code>$mem->add($uri,$html,0,10);</code>
#測試資料,memcached會在一個端口寫入資料和查詢資料:
<code><36 add </code><code>/user1</code><code>.html 0 10 87</code>
<code><37 new auto-negotiating client connection</code>
<code>37: Client using the ascii protocol</code>
<code><37 get </code><code>/user1</code><code>.html</code>
<code>>37 END</code>
<code><37 connection closed.</code>
<code><40 new auto-negotiating client connection</code>
<code>40: Client using the ascii protocol</code>
<code><40 get </code><code>/user2</code><code>.html</code>
<code>>40 END</code>
<code><40 connection closed.</code>
<code><40 add </code><code>/user2</code><code>.html 0 10 40</code>
<code>>40 STORED</code>
<code><41 new auto-negotiating client connection</code>
<code>41: Client using the ascii protocol</code>
<code><41 get </code><code>/user2</code><code>.html</code>
<code>>41 END</code>
<code><41 connection closed.</code>
#到此nginx+PHP+memcached+MySQL并現象memcached群架一緻性雜湊演算法完成!
#途中遇到一個問題:在MySQL中寫入中文資料,php調用後第一次顯示正常,第二次存入memcached後調用就亂碼了,我用Google和Firefox浏覽器都是亂碼,而用360和IE則沒有亂碼!暫時沒找到原因,有知道的忘告知,萬分感謝!!!
本文轉自 80後小菜鳥 51CTO部落格,原文連結:http://blog.51cto.com/zhangxinqi/1961992