php实现redis消息队列将数据保存到mysql

需求:
将消息先保存到redis,然后将redis中的数据定时保存到mysql中

分析:
redis保存为list,然后使用系统的定时任务调用脚本程序,通过脚本调用php文件进行处理。

windows脚本(live.bat):

"D:\Program Files\phpStudy\php\php-5.6.27-nts\php.exe" -f "D:\My\Program\live.gtarcade.com\redis_to_mysql.php"

php代码(redis_to_mysql.php):

<?php

/**
* 连接redis
*/
class Conn_Redis
{

    var $redis;

    private static $_instance;

    private function __construct($host, $password, $port){


        $this->redis = new Redis();

        /*$this->redis->connect('127.0.0.1', 6379);

        $auth = $this->redis->auth('123456');*/

        $this->redis->connect($host, $port);

        $auth = $this->redis->auth($password);

        return $this->redis;
    }

    static public function getInstance($host, $password, $port){

        if (FALSE == (self::$_instance instanceof self)) {
             self::$_instance = new self($host, $password, $port);
         }

        return self::$_instance;
    }

    private function __clone(){}

    public function lPop($key)
    {
        return $this->redis->lPop("call_log");
    }

    public function rPush($key, $value)
    {
        return $this->redis->rPush($key, $value);
    }

    public function close()
    {
        return $this->redis->close();
    }

}

/**
* 连接mysql
*/
class Conn_Mysql
{

    var $conn;

    var $redis_study;

    private static $_instance = null;

    private function __construct($host, $username, $password, $db_name){

        // $conn = mysql_connect($host, $username, $password);
        $this->conn = @new mysqli($host, $username, $password, $db_name);

        if ($this->conn->connect_errno) {
            die("could not connect to the database:\n" . $this->conn->connect_error);//诊断连接错误
        }

        $this->conn->query("set names 'utf8';");//编码转化

        /*$select_db = $conn->select_db($db_name);

        if (!$select_db) {
            die("could not connect to the db:\n" .  $conn->error);
        }*/

        return $this->conn;
    }

    static public function getInstance($host, $username, $password, $db_name){

        // if (is_null(self::$_instance) || isset(self::$_instance)) {
        if (FALSE == (self::$_instance instanceof self)) {

            self::$_instance = new self($host, $username, $password, $db_name);
        }

        return self::$_instance;
    }

    private function __clone(){}


    /**
    * 查询
    */
    public function query($sql, $link = '') {

        $this->result = $this->conn->query($sql) or $this->conn->err($sql);

        return $this->result;
    }

    public function close()
    {
        $this->conn->close();
    }

}


class RedisToMysql{

    var $redis;

    var $prefix;

    var $redis_study;

    var $db_prefix;

    public function __construct($redis_host, $redis_password, $mysql_host, $mysql_username, $mysql_password, $mysql_db_name, $db_prefix, $redis_port=6379, $mysql_port=3306)
    {

        $this->redis_host = $redis_host;
        $this->redis_password = $redis_password;
        $this->redis_port = $redis_port;

        $this->mysql_host = $mysql_host;
        $this->mysql_username = $mysql_username;
        $this->mysql_password = $mysql_password;
        $this->mysql_port = $mysql_port;
        $this->mysql_db_name = $mysql_db_name;

        $this->db_prefix = $db_prefix;

        $this->redis = Conn_Redis::getInstance($redis_host, $redis_password, $redis_port);

        $this->mysql = Conn_Mysql::getInstance($mysql_host, $mysql_username, $mysql_password, $mysql_db_name);

    }

    public function insert_redis()
    {

        /*$redis = new Redis();
        $redis->connect('127.0.0.1', 6379);
        $auth = $redis->auth('123456');
        echo "<BR>Connection to server sucessfully";*/

        $redis = $this->redis;

        // 加上时间戳存入队列
        $now_time_fir = date("Y-m-d H:i:s");
        $now_time_sec = date("Y-m-d H:i:s", time()+300);

        $title_fir = '今天是个好天气';
        $title_sec = '今天是个好日子';
        // $redis->rPush("call_log", [$title_fir . "%" . $now_time_fir, $title_sec . "%" . $now_time_sec]);
        $redis->rPush("call_log", [$title_fir . "%" . $now_time_fir, $title_sec . "%" . $now_time_sec]);
        // $redis->close();
    }

    public function redis_to_mysql($table)
    {
        $redis = $this->redis;

        // 获取现有消息队列的长度
        $count = 0;

        // 获取消息队列的内容,拼接sql
        $insert_sql = "insert into " . $this->db_prefix . $table . " (`title`, `create_time`) values ";

        // 回滚数组
        $roll_back_arr = array();

        while ($log_info = $redis->lPop("call_log")){

            $roll_back_arr = $log_info;

            if ($log_info == 'nil' || !isset($log_info)) {

                $insert_sql .= ";";

                break;
            }

            // 切割出时间和info
            $log_info_arr = explode("%",$log_info);

            $insert_sql .= " ('".$log_info_arr[0]."','".$log_info_arr[1]."'),";

            $count++;
        }


        // 判定存在数据,批量入库
        if ($count != 0) {

            $insert_sql = rtrim($insert_sql,",").";";

            // $res = mysql_query($insert_sql);
            // $res = $GLOBALS['db']->query($insert_sql);
            $res = $this->mysql->query($insert_sql);

            // 输出入库log和入库结果;
            /*echo '<BR><BR>'.date("Y-m-d H:i:s")."insert ".$count." log info result:";
            echo json_encode($res);*/

            // 数据库插入失败回滚
            if(!$res){
               foreach($roll_back_arr as $k){
                   $redis->rPush("call_log", $k);
               }
            }
        }
    }

    public function close()
    {

        $this->redis->close();

        $this->mysql->close();
    }

}


$db_prefix = 'fanwe_';
$redis_host = '127.0.0.1';
$redis_password = '123456';
$redis_port = 6379;

$mysql_host = 'localhost';
$mysql_username = 'root';
$mysql_password = 'root';
$mysql_port = '3306';
$mysql_db_name = 'live';
$table = 'study';

$redis_to_mysqls = new RedisToMysql($redis_host, $redis_password, $mysql_host, $mysql_username, $mysql_password, $mysql_db_name, $db_prefix);

$redis_to_mysqls->redis_to_mysql($table);

$redis_to_mysqls->close();

Author:leedaning
本文地址:http://blog.csdn.net/leedaning/article/details/78288386

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【课程简介】 消息队列是个高大上的名词儿,本质上就是如何业务进行排队处理,最常的使用场景就是发送短信的时候使用短信队列。但消息队列可以做的不止是这一类场景,它在解耦、消峰、异步、一致性等方面都有很大的用武之地。因此如何合理使用消息队列来处理一些特殊的业务需求,这就是我们这节课要解决的内容。 【课程目录】 第1章 消息队列的概念、原理和场景 详细介绍消息队列的概念,以及他合用的一些场景,并归纳了一下其中会用到的技术点的优缺点。 1-1 消息队列.mp4 (09:59) 第2章 解耦案例:队列处理订单系统和配送系统 讲解消息队列用于解耦的案例,使用mysql的一个表,做为队列存储,来实现成中间件来解耦订单系统和配送系统。使用订单系统实时写入,并用定时任务启动配送系统的处理程序,对队列进行处理并标记结果,使两个业务系统相互独立,以便分离部署,防止某一系统故障引起的连锁故障。 2-1 消息队列配置和准备工作 (06:00) 2-2 .Mysql订单队列 (19:27) 第3章 流量削峰案例:Redis的List类型实现秒杀 讲解一个秒杀时间点高流量的消峰的案例,使用Redis的List类型来做队列存储,并利用Redis的高速度,对秒杀时的大量流量进行处理,然后使用处理程序将缓存的结果放置到数据库中。利用内存数据库缓存机制将巨大的流量挡在了数据库之前,有效减少了对服务器I/O的负荷。 3-1 Redis (07:28) 3-2 Redis队列秒杀实现 (14:29) 第4章 RabbitMQ:更专业的消息系统实现方案 以RabbitMQ为例讲解了一些专业消息系统的原理,并使用官方的DEMO,演示其中的一个模块的使用方法。了解这类消息系统使用的步骤和应用场景。 4-1 RabbitMQ (13:41) 第5章 总结 综述消息队列在各种场景使用的方法和注意事项。 5-1 总结.mp4 (02:48)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值