自定义需求:实现消息队列。
1.创建一张mysql表结构
2.编写php脚本,便于sh文件执行
3.编写sh脚本,便于crontab定时执行
4.crontab -e 注册定时任务,如果此步不清楚请参照:http://www.cnblogs.com/jiangxiaobo/p/8194371.html
******************************************************************************************************************************
1.创建一张mysql表结构(仅供参考)
-- ---------------------------- -- Table structure for `message_queue` -- ---------------------------- -- DROP TABLE IF EXISTS `message_queue`; -- CREATE TABLE `message_queue` ( CREATE TABLE IF NOT EXISTS `message_queue` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `type` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '消息类型', # 0-普通消息,1-邮件消息 `status` tinyint unsigned NOT NULL DEFAULT 0, # 0-未处理,1-处理完成,2-处理中 `head` text COMMENT '消息头部', `body` text COMMENT '消息主体', `createtime` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '创建时间', `updatetime` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '修改时间', PRIMARY KEY (`id`), KEY `type` (`type`), KEY `status` (`status`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT '消息队列表';
2.编写php脚本,便于sh文件执行
这里可以脱离php框架,也可以依赖php框架,看个人,为了便捷,实现,依赖thinkphp框架为例。
MessageQueueModel:
<?php /* * 消息队列模型 * 用于定时任务处理 */ namespace CliModel; use ThinkModel; use OrgUtilString; /* -- ---------------------------- -- Table structure for `message_queue` -- ---------------------------- -- DROP TABLE IF EXISTS `message_queue`; -- CREATE TABLE `message_queue` ( CREATE TABLE IF NOT EXISTS `message_queue` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `type` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '消息类型', # 0-普通消息,1-邮件消息 `status` tinyint unsigned NOT NULL DEFAULT 0, # 0-未处理,1-处理完成,2-处理中 `head` text COMMENT '消息头部', `body` text COMMENT '消息主体', `createtime` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '创建时间', `updatetime` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '修改时间', PRIMARY KEY (`id`), KEY `type` (`type`), KEY `status` (`status`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT '消息队列表'; */ class MessageQueueModel extends Model{ // protected $connection = 'MSG_QUE_DB_DSN'; // 模型表实际名称 protected $trueTableName = 'message_queue'; // 命名范围 protected $_scope = array( // 取出未处理的消息 'not_processed' => array( 'where' => array('status'=>0), 'field' => 'id,type,head,body', 'order' => 'createtime asc' ) ); /** * 架构函数 * @access public * @param string $name 模型名称 * @param string $tablePrefix 表前缀 * @param mixed $connection 数据库连接信息 */ // public function __construct($name='',$tablePrefix='',$connection=''){ // $this->trueTableName = C('TABLE_MESSAGE_QUEUE'); // parent::__construct($name,$tablePrefix,$connection); // } /** * 获取一条未处理的消息 * @access public */ public function get_message(&$msg){ // 取出最远的一条未处理的消息 $msg = $this->scope('not_processed')->fetchSql(false)->find(); $msg['head'] = json_decode(base64_decode($msg['head']),true); return $msg; } /** * 将消息状态改成处理中 * @access public */ public function lock($id){ $map['id'] = $id; $data['status'] = 2; return $this->where($map)->save($data); } /** * 将消息状态改成处理完成 * @access public */ public function unlock($id){ $map['id'] = $id; $data['status'] = 1; return $this->where($map)->save($data); } /** * 将消息转为字符串 * @access public */ public function toString(&$msg){ return date("Y-m-d H:i:s # ").C('DB_NAME').".".$this->trueTableName.".id = ".$msg['id']." Processed!<br> "; } /** * 添加测试数据 * @access public */ public function randData(){ $emails = array( '123451@qq.com', '123452@qq.com', '123453@qq.com', ); for($i=0;$i<100;$i++){ $list[$i]['type'] = mt_rand(0,1); $list[$i]['status'] = mt_rand(0,2); if($list[$i]['type'] == 1){ $head1['email'] = $emails[mt_rand(0,2)]; $list[$i]['head'] = base64_encode(json_encode($head1)); }else{ $head0['uid'] = mt_rand(1,1000000); $list[$i]['head'] = base64_encode(json_encode($head0)); } $list[$i]['body'] = String::randString(mt_rand(200,1000),4); $list[$i]['createtime'] = time(); } return $this->addAll($list); } }
MessageQueueController:
<?php namespace CliController; use ThinkController; use CliModelMessageQueueModel; class MessageQueueController extends Controller { public function index(){ $MessageQueue = new MessageQueueModel(); $MessageQueue->get_message($msg); $MessageQueue->lock($msg['id']) or die; if($msg['type'] == 0){ // 处理普通消息 file_put_contents(C("LOG_ROOT_PATH").MODULE_NAME."/message_queue.log", $MessageQueue->toString($msg), FILE_APPEND); }else if($msg['type'] == 1){ $to = $msg['head']['email']; if(empty($to)) die; // 处理邮件消息 import('Common.phpMailer.class','','.phpmailer.php'); $mail = new PHPMailer(); $mail->IsSMTP(); $mail->CharSet = 'UTF-8'; // 设置邮件的字符编码,这很重要,不然中文乱码 $mail->SMTPAuth = true; // 开启认证 $mail->Port = C('SMTP_PROT'); $mail->Host = C('SMTP_HOST'); $mail->Username = C('SMTP_USERNAME'); $mail->Password = C('SMTP_PASSWORD'); // $mail->IsSendmail(); // 如果没有sendmail组件就注释掉,否则出现“Could not execute: /var/qmail/bin/sendmail ”的错误提示 $mail->AddReplyTo(C('SMTP_REPLY_TO_ADDRESS'),C('SMTP_REPLY_TO_NAME')); // 回复地址 $mail->From = C('SMTP_FROM'); $mail->FromName = C('SMTP_FROM_NAME'); $mail->AddAddress($to); $mail->WordWrap = C('SMTP_WORD_WRAP'); // 设置每行字符串的长度 $mail->Subject = "定时任务"; $mail->Body = $msg['body']; // $mail->AltBody = "测试主体"; // 当邮件不支持html时备用显示,可以省略 // $mail->AddAttachment("f:/test.png"); // 可以添加附件 $mail->IsHTML(true); $mail->Send(); } $MessageQueue->unlock($msg['id']) or die; } }
3.编写sh脚本,便于crontab定时执行
cd /www/loveDove/www_admin_com
/usr/local/php5/bin/php index.php Cli/MessageQueue/index
或者将错误输出至相应的日志文件(error.log)
cd /www/loveDove/www_admin_com /usr/local/php5/bin/php index.php Cli/MessageQueue/index >> /www/error/error.log 2>&1
注意:如果添加 php index.php Cli/MessageQueue/index 定时任务不执行,则需要将 php 命令改为全路径的命令 (which php查看全路径命令);另外,sh脚本必须在当前环境下进行创建则最为保险,不然会出现一些格式错误(touch index.sh来创建文件),如权限不够,则需要(chmod 777 index.sh来改变sh脚本文件的权限)。
4.crontab -e 注册定时任务
# Edit this file to introduce tasks to be run by cron. # # Each task to run has to be defined through a single line # indicating with different fields when the task will be run # and what command to run for the task # # To define the time you can provide concrete values for # minute (m), hour (h), day of month (dom), month (mon), # and day of week (dow) or use '*' in these fields (for 'any').# # Notice that tasks will be started based on the cron's system # daemon's notion of time and timezones. # # Output of the crontab jobs (including errors) is sent through # email to the user the crontab file belongs to (unless redirected). # # For example, you can run a backup of all your user accounts # at 5 a.m every week with: # 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/ # # For more information see the manual pages of crontab(5) and cron(8) # # m h dom mon dow command # */1 * * * * date >> /www/loveDove/www_admin_com/App/Runtime/Logs/Cli/date.log */1 * * * * /www/aabb/ccdd/App/Cli/Sh/MessageQueue/index.sh
# 如果上诉不能执行,用标准的绝对sh命令的进行执行
*/1 * * * * /bin/sh /www/aabb/ccdd/App/Cli/Sh/MessageQueue/index.sh
最后设置完成,则可以进行定时任务了,亲测有效。