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