这篇主要讲如何将数据保存回Mysql,但是里面还会涉及到如何将错误信息以及提示信息保存到文件里,方便以后的运维,再有就是如何使用PHP写进程BAT。
Redis数据刷回数据库前的知识准备
首先针对上篇提到的关于redis刷回数据库的安全性的设计模式,因为我们使用的是list来做数据索引,所以在我们将list数据提取出来的时候,一旦redis在这时候出现异常,就会导致刚提取出来的数据丢失!有些小伙伴就说,丢失就丢失呗,才一点数据。但是我们做程序,就应该以严谨为基础,所以下面就来说下Redis List这位大佬给我们提供了什么帮助。
Redis数据刷回数据库
方面文字太多?没关系。下面先来一段代码!我们的主体部分:
index.php:
- <?php
- require_once(__DIR__."/Mysql.class.php");
- require_once(__DIR__."/Redis.class.php");
- require_once(__DIR__."/Output_Log.class.php");
- $rel = true; //无限循环的变量
- $num = 0; //用来没数据时的判断依据
- date_default_timezone_set("Asia/Shanghai");
- $now = date("Y-m-d H:i:s"); //当前时间
- //file log
- $txt = dirname(__DIR__)."/Script_Log/clickgood_log.txt";
- $output = new OutputLog();
- $test = $output->open($txt,"a+");
- while($rel)
- {
- $redis = new RedisCtrl();
- //开始干活
- if($num==0){
- //这里就是将信息输出到文件里记录,下面很多地方都是一样的。
- $text = "start ".$name."\n";
- echo $text;
- $output->write($test,$text);
- }
- //获取备份队列的长度
- $copylistlength = $redis->llen("comment:uploadcopylist");
- //我这里展示的是第一数据回滚到mysql,小伙伴想批量回滚的,自己改装下就可以用了。
- //自己动手丰衣足食!
- if($copylistlength>1)
- {
- //由于是单一数据回滚,所以我要判断它是否超过我设定的值,小伙伴们最好也自己定一个阈值。
- //report error
- echo $now." ->false\n";
- $rel = false;
- return;
- }
- else if($copylistlength==1)
- {
- //这里判断防止上次redis出现错误,导致数据没有及时回到mysql
- $data = $redis->rpop("comment:uploadcopylist");
- $rel = $redis->UpdateClickGoodDataToMysql($data);
- $text = $rel."\n";
- echo $text;
- $output->write($test,$text);
- }
- else
- {
- //获取主要队列的长度
- $listlength = $redis->llen("comment:uploadlist");
- if ($listlength>0) {
- //使用之前说到的设计模式
- $data = $redis->rpoplpush("comment:uploadlist","comment:uploadcopylist");
- $rel = $redis->UpdateClickGoodDataToMysql($data);
- $text = $rel."\n";
- echo $text;
- $output->write($test,$text);
- }else{
- // 队列为空
- // 打印关闭信息,这里的写法算是维持进程窗口不关闭,需要手动关闭
- // 如果想让它执行完自动关闭的,
- // 把下面改写成$rel = false;
- if($num<=3){
- $text = $now." -> please close .\n";
- echo $text;
- $output->write($test,$text);
- $num++;
- }
- else
- {
- $output->close($test);
- }
- }
- }
- }
Redis.class.php:redis操作类
- <?php
- class RedisCtrl
- {
- //init redis
- static $redisIp = "127.0.0.1";
- static $redisPort =6379;
- static $redisPass ="";
- public $redis = null;
- //Redis
- public function __construct()
- {
- $this->redis = new Redis();
- $this->redis->connect(self::$redisIp,self::$redisPort);
- $this->redis->auth(self::$redisPass);
- }
- public function llen($key)
- {
- $rel = $this->redis->llen($key);
- return $rel;
- }
- public function rpop($key)
- {
- $rel = $this->redis->rpop($key);
- return $rel;
- }
- public function rpoplpush($source,$destination)
- {
- $rel = $this->redis->rpoplpush($source,$destination);
- return $rel;
- }
- public function UpdateClickGoodDataToMysql($data)
- {
- //get id and time from redis list
- $result = json_decode($data,true);
- $id = $result['id'];
- $time = $result['time'];
- $arr = array();
- //like
- $like = $this->redis->zscore("comment:like",$id);
- $like = $like?$like:0;
- //hate
- $hate = $this->redis->zscore("comment:hate",$id);
- $hate = $hate?$hate:0;
- $sql = "update comment_info set like_count=".$like.", hate_count=".$hate." where id=".$id;
- $arr[] = $sql;
- //update sql
- $mysql = new MysqlCtrl();
- $mysql->saveMySQL($arr);
- //更新完,将set集合里需要更新的id去掉
- $this->redis->srem("comment:uploadset",$id);
- //更新完毕,将备份队列里的数据去掉
- $this->redis->lrem("comment:uploadcopylist",$data);
- return $sql."\n";
- }
- }
Mysql.class.phpmysql类
- <?php
- //封装函数
- class MysqlCtrl
- {
- //初始化参数
- //数据库参数配置
- static $dbms = "mysql";
- static $host = Your host;
- static $user = Your user;
- static $pass = Your pass;
- static $database = Your database;
- //睡眠时间
- static $sleep = 1;
- public $dsn = null;
- public $dbh = null;
- public function __construct()
- {
- $this->dsn = self::$dbms.":host=".self::$host.";dbname=".self::$database;
- //return $dsn;
- try {
- $this->dbh = new PDO($this->dsn, self::$user, self::$pass);
- echo "Connected\n";
- } catch (Exception $e) {
- echo $this->dsn;
- die("Unable to connect: " . $e->getMessage());
- }
- }
- //保存数据到数据库
- //PDO
- public function saveMySQL($arr)
- {
- try {
- $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
- $this->dbh->beginTransaction();
- $count = count($arr);
- for ($i=0; $i < $count; $i++) {
- $this->dbh->exec($arr[$i]);
- }
- $this->dbh->commit();
- } catch (Exception $e) {
- $this->dbh->rollBack();
- echo "Failed: " . $e->getMessage()."\n";
- $json = json_encode($arr);
- echo "False-SQL: ".$json."\n";
- exit();
- }
- }
- }
Output_Log.class.php输出信息到文件的类
- <?php
- class OutputLog
- {
- public function open($name,$r)
- {
- $text = fopen($name, $r);
- return $text;
- }
- public function write($name,$title)
- {
- $rel = fwrite($name, $title);
- return $rel;
- }
- public function close($name)
- {
- fclose($name);
- }
- }
clickgood_log.txt这里是保存输出的信息,里面是空白的。
- hellO world
上面这些就是整套数据保存到mysql的操作,这是本人源码copy过来的,所以细分程度比较高,但是可扩展性也很高。有什么错误的地方希望小伙伴们能提出,谢谢。
最后就是我们的进程调用了,其实很简单
创建一个txt文件,然后改名为clickgood.bat,记得把txt后缀文件名改为bat
clickgood.bat:
1 D:\Software\wamp64\bin\php\php7.0.10\php.exe index.php
关于上面的bat注意两点,一前面那个php.exe,按照你自己的路径去找,我使用wampserver测试环境,基本就是上面的路径。第二点,后面的index.php和clickgood.bat同一目录下。
好了!终于可以收尾了!、
欢迎大家交流,上面只是本人自己的做法,希望大家能够指出错误的地方!或者提供更好的做法。
来源: http://www.cnblogs.com/sunshine-H/p/7928034.html