View on GitHub

yii2-cookbook-chinese

Yii Application Development Cookbook(Third Edition)中文翻译

加速session处理

在PHP中原生的session处理在大部分情况下已经非常好了。但至少有两个可能原因,你希望改变session的处理方式:

准备

按照官方指南http://www.yiiframework.com/doc-2.0/guide-start-installation.html的描述,使用Composer包管理器创建一个新的yii2-app-basic应用。并安装Memcache服务器和memcache PHP扩展。

如何做…

我们使用apache的ab工具对网站做压力测试。它是和apache二进制文件一起发布,所以如果正在使用apache,你将会在bin文件夹中找到它。

  1. 运行如下命令,并将网址替换成你的正在使用的网站的网址:
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处理速度感兴趣。

  1. 现在添加如下代码到/config/web.php组件部分:
'session' => array(
    'class' => 'yii\web\CacheSession',
    'cache' => 'sessionCache',
),
'sessionCache' => array(
    'class' => 'yii\caching\MemCache',
),
  1. 再次以相同的设置运行ab。这次,你应该能得到更好的结果。在我的例子中,QPS是139.07。这意味着Memcache,作为一个session处理器,相对于基于文件的session处理器提升了52%的性能。

注意:不要依赖于这里提供的精确的结果。它依赖于软件版本、设置和使用的硬件。经常尝试在你即将部署应用的环境中,运行所有的测试。

  1. 通过选择正确的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();

参考

欲了解更多关于性能和缓存的信息,参考如下地址: