• 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 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

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

  • 相关阅读:
    golang实现单链表
    koa中间执行机制
    vuex源码简析
    从浏览器渲染过程看重绘回流
    javascript的this
    js 设计模式:观察者和发布订阅模式
    H5 移动端 键盘遮挡焦点元素解决方案
    webpack4 css modules
    Daily,一个入门级的 React Native 应用
    javascript: 类型转换
  • 原文地址:https://www.cnblogs.com/jiangxiaobo/p/8206184.html
Copyright © 2020-2023  润新知