前段时间由于一个控制方法要实现的逻辑任务太多了,无论怎么优化都还是有瓶颈。网上介绍可以使用任务队列的机制,把一些不是立即需要相应的逻辑处理放在队列中,让某个程序时时去执行。举个例子:用户上来我的网站注册,注册完后,我需要给用户的邮箱帐号推送一些邮件,这个推送邮件所发的时间可能远比注册保存用户资料所花的时间多些,也不是立即就需要响应到前端给客户知道。所以,是可以把推送邮件这一动作作为一个任务添加到队列中。
说明下我测试调试的环境是在Ubuntu12.04下的,安装redis和添加crontab命令是通过终端命令的,我测试的项目是基于yii框架,调用redis是通过框架提供的yiiredis插件,可能不太符合你的环境,但其中的思路或许还是可以借鉴的。
1、安装Redis
进入终端命令窗口(快捷键Ctrl+Alt+T)切换至/usr/local/src(命令:cd /usr/local/src)下,下载并安装redis:
$ wget http://redis.googlecode.com/files/redis-2.6.12.tar.gz $ tar xzf redis-2.6.12.tar.gz $ cd redis-2.6.12 $ make进入redis-2.6.12(命令:cd redis-2.6.12)目录,修改redis.conf:
daemonize yes启动服务端:
$ src/redis-server redis.conf进入命令行验证服务是否启动:
$ src/redis-cli redis> set foo bar OK redis> get foo "bar"
return array(
‘components‘ => array(
…
‘cache‘=>array(
‘class‘=>‘ext.redis.CRedisCache‘, //对应protected/extensions/redis/CredisCache.php
‘servers‘=>array(
array(
‘host‘=>‘127.0.0.1‘,
‘port‘=>6379,
),
),
),
),
…
);编写一个读写缓存的控制器IndexController进行测试。
class IndexController extends CController{
public function actionSetRedisValue() {
$key = $_POST[‘key‘];
$value = $_POST[‘value‘];
if ( !empty( $key ) && !empty( $value ) ) {
try {
$redis = Yii::app()->cache;
$data = ( array ) $redis->get( ‘test‘ );
$data[$key] = $value;
$redis->set( ‘test‘, $data );
die( json_encode( array( ‘status‘ => 1, ‘msg‘ => ‘set ok!‘ ) ) );
} catch ( Exception $e ) {
die( json_encode( array( ‘status‘ => 0, ‘msg‘ => ‘set faile!‘ ) ) );
}
} else {
die( json_encode( array( ‘status‘ => 0, ‘msg‘ => ‘must input!‘ ) ) );
}
}
public function actionGetRedisValue() {
try {
$redis = Yii::app()->cache;
$data = ( array ) $redis->get( ‘test‘ );
$log_file = Yii::app()->runtimePath . ‘\redis_log.txt‘;
if ( file_exists( $log_file ) ) {
$handle = fopen( $log_file, "a+" );
$log = "----" . date( ‘Y-m-d H:i:s‘ ) . "-----" . "\n";
foreach ( $data as $key => $value ) {
$log .= ‘->‘ . $key . ‘ = ‘ . $value . "\n";
}
fwrite( $handle, $log );
fclose( $handle );
}
} catch ( Exception $e ) {
echo $e->getMessage();
}
}
}
视图文件index内容。<?php Yii::app()->clientScript->registerCoreScript( ‘jquery‘ ); ?>
<p>Redis</p>
<form id="redis_form" action="<?php echo $this->createUrl( ‘/cata/index/setRedisValue‘ ); ?>" method="post">
Key:<input id="key" type="text" value=""/>
Value:<input id="val" type="text" value=""/>
<input id="set" type="button" value="set"/>
<input id="get" type="button" value="get"/>
<span></span>
</form>
<script>
$(document).ready(function() {
$(‘#redis_form #set‘).on(‘click‘, function() {
var redisForm = $(‘#redis_form‘);
var action = redisForm.attr(‘action‘);
var key = redisForm.children(‘#key‘);
var value = redisForm.children(‘#val‘);
$.post(action, {key: key.val(), value: value.val()}, function(data) {
redisForm.find(‘span‘).html(data.msg);
setTimeout(function() {
redisForm.find(‘span‘).html(‘‘);
}, 3000);
}, ‘json‘);
});
$(‘#redis_form #get‘).on(‘click‘, function() {
$.post(‘<?php echo $this->createUrl( ‘/cata/index/getRedisValue‘ ); ?>‘, {}, function(data) {
}, ‘json‘);
});
});
</script>
现在访问:http://helloyii.com/app/index.php?r=cache/fetch&key=a&value=b
然后通过redis-cli命令行客户端查看下缓存的变化:
可以通过redis-cli客户端查看缓存:
$ src/redis-cli redis> keys ‘*‘
4、添加crontab命令,每10秒获取redis缓存数据进行处理
很多时候,我们计划任务需要精确到秒来执行,但linux最小只支持分钟,很多linux自带的版本都不直接支持以秒来执行,根据以下方法,可以很容易地以秒执行任务。
进入终端编辑crontab(命令:crontab -e)
* * * * * /usr/bin/wget -q http://localhost/suixingv3/index.php/cata/index/getRedisValue * * * * * sleep 10; /usr/bin/wget -q http://localhost/suixingv3/index.php/cata/index/getRedisValue * * * * * sleep 20; /usr/bin/wget -q http://localhost/suixingv3/index.php/cata/index/getRedisValue * * * * * sleep 30; /usr/bin/wget -q http://localhost/suixingv3/index.php/cata/index/getRedisValue * * * * * sleep 40; /usr/bin/wget -q http://localhost/suixingv3/index.php/cata/index/getRedisValue * * * * * sleep 50; /usr/bin/wget -q http://localhost/suixingv3/index.php/cata/index/getRedisValue
$ ./redis-cli输入:
config set stop-writes-on-bgsave-error no
官方安装手册
http://redis.io/download
Yii的Redis插件1:rediscache
http://www.yiiframework.com/extension/rediscache/
Yii的Redis插件2:yiiredis
https://github.com/phpnode/YiiRedis
Yii CCache接口的API
http://www.yiichina.com/api/CCache#get-detail
Redis在YiiFramework中的使用
http://denghai260.blog.163.com/blog/static/726864092012323101628773/
Linux下Redis+crontab实现任务队列,布布扣,bubuko.com
原文:http://blog.csdn.net/zyb_icanplay7/article/details/20689873