前言:
前几篇文章,我们搭建的lnmp的最基础部分,客户端可以请求我们的资源,请求数少的时候,觉得可以;但如果说我们的的网站的访问量增大之后,那么我们搭建的lnmp就不符合我们的需求了,因为这样的lnmp没有办法处理这么多的请求,性能会下降,响应给客户端的时间也会越来越长。
我们知道,客户端在发送请求到收到响应,这期间当中,什么占时间呢?有网络I/O,和服务器端的磁盘的I/O。那么我们现在从服务器的磁盘I/O入手,对我们的lnmp进行完善。
cpu从内存拿数据比从磁盘拿数据要快很多,所以我们来看整个lnmp中那些地方可供我们加缓存。
我们先来看lnmp的整个框架是怎样的,以便于我们找到加缓存的地方。
如上图所示,
当客户端请求静态数据,nginx自己处理,这里会有磁盘I/O;
当客户端请求动态数据,nginx通过fastcgi把请求转交给后面的应用程序服务器,当这些应用程序拿数据就需要去后面的MySQL去拿,这里就又有一个磁盘I/O。
所以我们可以在这两个地方加缓存,那什么可以用来做缓存呢?
一、缓存系统
1.memcache
memcache是一套分布式的高速缓存系统,目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的、需要频繁访问数据库的网站访问速度提升效果十分显著[1] 。这是一套开源软件,以BSD license授权发布。
2.Redis
二、PHP添加memcache模块
操作前提:已安装配置好php,
1.下载memcache安装包,并且将memcache解压
# wget http://pecl.php.NET/get/memcache-2.2.3.tgz
# tar -zxvf memcache-2.2.3.tgz
2.将php安装路径下的bin的绝对路径添加到环境变量当中
# vim ~/.bash_profile
PATH=$PATH:$HOME/bin:/usr/local/lnmp/mysql/bin:/usr/local/lnmp/php/bin
# source ~/.bash_profile
3.在memcache的解压目录下执行phpize
# cd memcache-2.2.3/
# phpize #phpize是用来扩展php扩展模块的,通过phpize可以建立php的外挂模块
4.安装php-devel,如果已经安装过了就不用了
# yum install -y php-devel
5.编译安装memcached
# ./configure
# make install
# install
6.在配置文件中添加memcached模块
# vim php.ini
在第851行后面任意一行添加 extension=memcache.so
# /etc/init.d/php-fpm reload #重启php-fpm
# php -m | grep memcache #这回可以显示出来memcache,代表php已经成功安装上了动态模块memcache
7.安装memcached,开启memcached服务
# yum install memcached -y
# /etc/init.d/memcached start
memcached是监听在11211端口上的
/etc/sysconfig/memcached文件:
文件中内容如下
PORT=”11211″ #监听端口
USER=”root” #使用的身份
MAXCONN=”1024″ #同时最大连接数
CACHESIZE=”64″ #使用的内存大小
OPTIONS=”" #附加参数,例如:OPTIONS=”-l 127.0.0.1″,只能本机访问,不对公网开放
实验:从网页上测试并查看memcache的命中率
将解压目录下的example.php,memcache.php放到nginx的发布目录里面
example.php:用来连接memcache并发起请求
memcache.php:能显示memcache的命中率
访问memcache.php,通过访问example.php来对memcache发起连接
这里要添的就是上图的用户memcache和密码westos
我们可以看到当没有访问memcache时,他的命中率和未命中率都是50%
其实除了这种安装memcached的安装包的方法,其实还有一种办法是直接重新编译php,编译的时候加上参数–enable-memcache[=DIR] 选项
当php添加了memcache模块之后的请求处理流程:
1.客户端发来请求
2.如果是静态的nginx自己就处理了,如果是动态的,nginx会将请求向后转发给php/tomcat,
3.此时php/tomcat会先去memcache中找,如果找到就直接返回
4.如果找不到,就会去数据库中查找,
5.如果查找到之后,就给memcache保存一份,
6.然后返回给php/tomcat
7.php/tomcat整合好资源之后就返回给nginx
8.nginx响应给客户端
三、nginx+memcache
1.下载安装包openresty-1.11.2.3.tar.gz,解压
# wget https://openresty.org/download/openresty-1.11.2.3.tar.gz
# tar zxf openresty-1.11.2.3.tar.gz
2.编译安装
进入解压后目录
# ./configure
# gmake
# gmake install
3.安装后配置
# /etc/init.d/memcached start # 启动memcached
# /etc/init.d/php-fpm start #启动php-fpm
# cd /usr/local/openresty/
# ls
bin luajit lualib nginx pod resty.index site
我们可以发现openresty自带有nginx ,修改nginx的配置文件
启动openresty 自带的nginx,并且编写一个php的测试页
4.进行压力测试
命令ab:
ab是Apache的Web服务器的性能测试工具,它可以测试安装Web服务器每秒种处理的HTTP请求。
其中-n代表每次并发量,-c代表总共发送的数量
测试结果的意义:
从上面的信息来看,我们现在服务器的性能还是很差的,我们来继续配置
upstream memcacheds {
server 127.0.0.1:11211; ##memc-nginx是一个标准的upstream模块,因此首先需要定义memcache的upstream。这里我在本机上启动了一个memcache服务,端口为默认的11211
keepalive 512; ##keepalive指令是http-upsteram-keepalive-module提供的功能,这里我们最大保持512个不立即关闭的连接用于提升性能。
}
location /memc {
internal;
memc_connect_timeout 100ms;
memc_send_timeout 100ms;
memc_read_timeout 100ms;
set $memc_key $query_string;
set $memc_exptime 300;
memc_pass memcacheds;
}
上为memc-nginx-module配置location,我们配置为/memc,所有请求都通过请求这个location来操作memcache,memc-nginx-module存取memcache是基于http method语义的,使用http的GET方法表示get、PUT方法表示set、DELETE方法表示delete。这里我们将/memc设为internal表示只接受内部访问,不接收外部http请求,这是为了安全考虑,当然如果需要通过http协议开放外部访问,可以去掉internal然后使用deny和allow指令控制权限。比较重要的是$memc_key这个变量,它表示以什么作为key,这里我们直接使用Nginx内置的$query_string来作为key,$memc_exptime表示缓存失效时间,以秒记。这里统一设为300(5分钟),在实际应用中可以根据具体情况为不同的内容设置不同的过期时间。
location ~ \.php$ {
set $key $uri$args; ##设置key的值是
srcache_fetch GET /memc $key;
srcache_store PUT /memc $key;
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
#fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
include fastcgi.conf;
}
,
最后我们为“~ \.php$”这个location配置了缓存,这表示所有以“.php”结尾的请求都会结果被缓存,当然这里只是示例需要,实际中一般不会这么配,而是为特定需要缓存的location配置缓存。
srcache_fetch表示注册一个输入拦截处理器到location,这个配置将在location进入时被执行;而srcache_store表示注册一个输出拦截器到location,当location执行完成并输出时会被执行。注意srcache模块实际可以与任何缓存模块进行配合使用,而不必一定是memc。这里我们以$uri$args作为缓存的key。
经过上述配置后,相当于对Nginx增加了如下逻辑:当所请求的uri以“.php”结尾时,首先到memcache中查询有没有以$uri$args为key的数据,如果有则直接返回;否则,执行location的逻辑,如果返回的http状态码为200,则在输出前以$uri$args为key,将输入结果存入memcache。
进行压测:
这回性能还不错
添加了nginx+memcache之后,请求处理流程:
1.客户端发来请求
2.如果是静态的nginx自己处理,若是动态的nginx会先去memcache中查找,找到就直接返回
3.如果没找到,再将请求转发给后端
4.后端去数据库中查找,如果没有找到返回错误信息给nginx
5.如果找到的话就放到memcache一份,
6.返回给nginx
7.nginx响应客户端
推荐阅读文章:
Memcache缓存系统原理:http://www.cnblogs.com/WuNaiHuaLuo/p/5225330.html