crontab定时任务-干货案例

Posted lewo的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了crontab定时任务-干货案例相关的知识,希望对你有一定的参考价值。

自定义需求:实现消息队列。

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 Cli\\Model;
use Think\\Model;
use Org\\Util\\String;
/*
-- ----------------------------
-- 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>\\r\\n";
    }
    /**
     * 添加测试数据
     * @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 Cli\\Controller;
use Think\\Controller;
use Cli\\Model\\MessageQueueModel;
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

最后设置完成,则可以进行定时任务了,亲测有效。

以上是关于crontab定时任务-干货案例的主要内容,如果未能解决你的问题,请参考以下文章

crontab 定时任务

Crontab定时任务

linux定时任务(crontab)

Linux定时任务调度

linux Crontab定时备份项目案例

crontab 定时任务没有响应 检测步骤