加速session处理
在PHP中原生的session处理在大部分情况下已经非常好了。但至少有两个可能原因,你希望改变session的处理方式:
- 当使用多个服务器时,需要有统一的session存储。
- 默认的PHP session使用文件,所以最大的性能瓶颈在磁盘I/O上。
- 默认的PHP session是阻塞并发的session存储。在这个小节中,我们将会看到如何使用Yii做高效的session存储。
准备
按照官方指南http://www.yiiframework.com/doc-2.0/guide-start-installation.html的描述,使用Composer包管理器创建一个新的yii2-app-basic
应用。并安装Memcache服务器和memcache
PHP扩展。
如何做…
我们使用apache的ab
工具对网站做压力测试。它是和apache二进制文件一起发布,所以如果正在使用apache,你将会在bin
文件夹中找到它。
- 运行如下命令,并将网址替换成你的正在使用的网站的网址:
ab -n 1000 -c 5 http://yii-book.app/index.php?r=site/contact
这将会发送1000次请求,一次发送5个,并会得到如下输出统计:
This is ApacheBench, Version 2.3 <$Revision: 1528965 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd,
http://www.zeustech.net/
Licensed to The Apache Software Foundation,
http://www.apache.org/
...
Server Software: nginx
Server Hostname: yii-book.app
Server Port: 80
Document Path: /index.php?r=site/contact
Document Length: 14866 bytes
Concurrency Level: 5
Time taken for tests: 10.961 seconds
Complete requests: 1000
Failed requests: 0
Total transferred: 15442000 bytes
HTML transferred: 14866000 bytes
Requests per second: 91.24 [#/sec] (mean)
Time per request: 54.803 [ms] (mean)
Time per request: 10.961 [ms] (mean, across all
concurrent requests)
Transfer rate: 1375.84 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 18 55 324.9 29 4702
Waiting: 15 41 255.1 24 4695
Total: 18 55 324.9 29 4702
我们对每秒请求次数指标(requests-per-second,简称QPS)感兴趣。这个值意味着这个网站在并发数为5的情况下,每秒可以处理91.24次请求。
注意:注意调试并没有关闭,因为我们对修改session处理速度感兴趣。
- 现在添加如下代码到
/config/web.php
组件部分:
'session' => array(
'class' => 'yii\web\CacheSession',
'cache' => 'sessionCache',
),
'sessionCache' => array(
'class' => 'yii\caching\MemCache',
),
- 再次以相同的设置运行
ab
。这次,你应该能得到更好的结果。在我的例子中,QPS是139.07。这意味着Memcache
,作为一个session处理器,相对于基于文件的session处理器提升了52%的性能。
注意:不要依赖于这里提供的精确的结果。它依赖于软件版本、设置和使用的硬件。经常尝试在你即将部署应用的环境中,运行所有的测试。
- 通过选择正确的session处理后端,你可以得到一个显著的性能提升。Yii支持更多的缓存后端out-of-the-box,包括WinCache、XCache和Zend Data Cache,它来自于Zend Server。而且,你可以实施你自己的缓存后端,来使用快速的noSQL存储,例如Redis。
工作原理…
默认情况下,Yii使用原生PHP session;这意味着大部分情况下使用文件系统。文件系统并不能高效的处理高并发请求。
Memcache或者其它平台在如下情况下,能很好的执行:
'session' => array(
'class' => 'yii\web\CacheSession',
'cache' => 'sessionCache',
),
'sessionCache' => array(
'class' => 'yii\caching\MemCache',
),
在先前的配置部分,我们在Yii中使用CacheSession
作为一个session处理器。使用这个组件,我们可以委托session处理器为cache
中指定的缓存组件。这次我们使用MemCache
。
当使用一个memcached后端,你应该考虑到这个事实,当使用这些解决方案时,当缓存达到最大存储容量时,应用用户可能丢失session。
注意:注意到,当为一个session使用一个缓存后端时,你不能依赖于一个session作为一个临时数据存储,因为在memcached中将不会有更多内存来存储更多数据。在这个例子中,只需要清理所有的数据,并清除其中的一部分。
如果你在使用多个服务器,你不能使用文件存储。没有办法来分享多个服务器之间的session数据。在memcached的例子中,这非常容易,因为它可以被多个服务器访问。
此外,对于分享session数据,你可以使用DbSession
:
return [
// ...
'components' => [
'session' => [
'class' => 'yii\web\DbSession',
],
],
];
现在,在你的数据库中创建一个张新表:
CREATE TABLE session (
id CHAR(40) NOT NULL PRIMARY KEY,
expire INTEGER,
data BLOB
)
更多…
尽可能关闭session是一个好主意。如果你不想在当前的请求中在session中存储任何数据,你甚至可以在你的控制器动作一开始就关闭它。这样,在你的应用中即使是使用文件作为存储也是没关系的。
使用如下命令:
Yii:$app->session->close();
参考
欲了解更多关于性能和缓存的信息,参考如下地址: