站点高并发写问题的一个解决实践
我负责一个基于Yii的lamp站点维护和优化,其中有一个表的并发写很高,导致用户体验差,甚至写失败造成数据丢失,分析后发现这个表其实并发读要求很低,所以计划将写记录到log中,定期将log写入mysql。
log4php在yii中使用
log4php是Apache的一个log框架,下载下来的库,放在与yii中protected一个目录下。修改配置log4php/config.php,这个是php数组格式的配置信息,我们希望将记录写入文件,并按照小时来切分,如:
<?php
return array(
‘rootLogger‘ => array(
‘appenders‘ => array(‘default‘),
),
‘appenders‘ => array(
‘default‘ => array(
‘class‘ => ‘LoggerAppenderDailyFile‘,
‘layout‘ => array(
‘class‘ => ‘LoggerLayoutSimple‘
),
‘params‘ => array(
‘datePattern‘ => ‘Y-m-d.H‘,
‘file‘ => ‘./history_log/history-%s.log‘,
)
)
)
);
很简单吧,当然,要在yii的index.php中对库引用:
// history_log
$log4php=dirname(__FILE__).‘/log4php/Logger.php‘;
$log4phpconfig=dirname(__FILE__).‘/log4php/config.php‘;
require_once($log4php);
Logger::configure($log4phpconfig);
使用上,在业务处举个栗子:
Logger::getRootLogger()->info(json_encode($item));
这样,数据就记录在日志中,举个栗子:
周期将log写入数据库
我使用shell和yii的commands支持相结合来做定期脚本,意识流,为了省事。
shell来获取时间并调用yii command:
logTime=$(date --date=‘1 hour ago‘ +%Y-%m-%d.%H)
/home/qec/qss/www/protected/yiic UpdateHistory $logTime
yii php用来读log,写mysql,一个继承yii的CConsoleCommand类就好:
class UpdateHistoryCommand extends CConsoleCommand
{
const LOGPATH=‘/home/qec/qss/www/history_log/‘;
public function __construct()
{
}
public function run($args)
{
if(count($args) != 1){
echo "need one time arg","\n";
return false;
}
$logTime = $args[0];
$logFileName = ‘history-‘.$logTime.‘.log‘;
echo "logFileName: ",$logFileName,"\n";
echo self::LOGPATH.$logFileName,"\n";
$path= self::LOGPATH.$logFileName;
$logFd = fopen($path, ‘r‘);
if($logFd == 0){
echo "Open logFile ",self::LOGPATH,$logFileName," failed!\n";
return false;
}
$this->addLogToHistory($logFd);
}
...
最后,crontab里面加入定时任务:
5 * * * * source /home/qec/.bash_profile;cd /home/qec/qss/www/protected/commands; sh hourlyJobs.sh >> ../runtime/hourlyJobs.log
就可以了。
PS:第一次使用markdown,感觉不错。
时间: 2024-10-13 20:37:05