zoukankan      html  css  js  c++  java
  • Cache应用/任务Mutex,用于高并发任务处理经过多个项目使用

    <?php
    /**
     * Class Cache redis 用于报表的缓存基本存储和读写 2.0
     * <pre>
     *  Cache::read("diamond.account",$nick);
     *  Cache::readSync("diamond.account",$nick);
     *  $finder = Cache::createFinder("diamond.account",$nick);
     *  $finder->read();
     *  $finder->readSync();
     *
     *  Cache::save("diamond.account",$nick,$data);
     *  $storage = Cache::createStorage("diamond.account",$nick);
     *  $storage->save($data);
     *  $storage->save($data,7200);
     * </pre>
     * @category cache
     * @package cache
     * @author oShine <oyjqdlp@126.com>
     * @version 2.0.0.0
     * @copyright oShine 2015/08/07
     */
    class Cache {
    
        /**
         * 非安全读取的数据
         * @param $key
         * @param string $nick
         * @return array|null
         */
        public static function read($key,$nick = "sys"){
            $finder = self::createFinder($key,$nick);
            return $finder->read();
        }
    
        /**
         * 同步读取数据
         * @param $key
         * @param string $nick
         * @return mixed
         */
        public static function readSync($key,$nick = "sys"){
            $finder = self::createFinder($key,$nick);
            return $finder->readSync();
        }
    
        /**
         * 创建Finder
         * @param $key
         * @param string $nick
         * @return Finder
         */
        public static function createFinder($key,$nick = "sys"){
            $key = Generate::key($key,$nick);
            return new Finder($key);
        }
    
        /**
         * 创建Storage
         * @param $key
         * @param string $nick
         * @return Storage
         */
        public static function createStorage($key,$nick = "sys"){
            $key = Generate::key($key,$nick);
            return new Storage($key);
        }
    
        /**
         * 保存数据
         * @param $key
         * @param string $nick
         * @param array $data
         * @param int $expired
         * @return bool
         */
        public static function save($key,$nick = "sys",$data = array(),$expired=7200){
            $storage = self::createStorage($key,$nick);
            return $storage->save($data,$expired);
        }
    
        /**
         * @param string $nick
         */
        public static function clear($nick = "sys"){
            $redis = CacheFactory::create();
            $redis->del($redis->keys(md5($nick).".data.*"));
        }
    
    }
    
    
    
    /**
     * Class Finder  数据读取
     * @category cache
     * @package cache
     * @author oShine <oyjqdlp@126.com>
     * @version 2.0.0.1
     * @copyright oShine 2015/08/07
     */
    class Finder {
    
        /**
         * @var string $key
         */
        public $key;
    
        /**
         * @param string $key
         */
        public function __construct($key){
            $this->key = $key;
        }
    
        /**
         * 非安全读取数据
         * @return mixed
         */
        public function read(){
            $data = $this->readData();
            if($data->isRead === true && !$data->isExpired()) {
                return json_decode(json_encode($data->data), true);
            }
            return null;
        }
    
        /**
         * @return Data
         */
        protected function readData(){
            $redis =  CacheFactory::create();
            $rptData = new Data();
            $data = json_decode($redis->get($this->key));
            if(false == $data){
                $rptData->isRead = false;
                $rptData->expiredTime = time();
                $rptData->expired = 24*3600;
            }else{
                $rptData->expired = $data->expired;
                $rptData->isRead = isset($data->isRead) && $data->isRead === true?true:false;
                $rptData->expiredTime = $data->expiredTime;
                $rptData->data = $data->data;
            }
            return $rptData;
        }
    
        /**
         * 同步读取数据
         * @return mixed
         */
        public function readSync(){
            while(true){
                $rptData = $this->readData();
                if($rptData->isRead && !$rptData->isExpired())
                    return $this->read();
                sleep(1);
            }
        }
    }
    
    /**
     * Class Storage  数据存储
     * @category cache
     * @package cache
     * @author oShine <oyjqdlp@126.com>
     * @version 2.0.0.0
     * @copyright oShine 2015/08/07
     */
    class Storage {
    
        /**
         * @var string key
         */
        public $key;
    
        /**
         * @param string $key
         */
        public function __construct($key){
          $this->key = $key;
        }
    
        /**
         * @return bool
         */
        public function flush(){
            $rptData = new Data();
            $rptData->data = null;
            $rptData->expiredTime = time();
            $rptData->isRead = false;
            $rptData->expired = 1;
            $redis =  CacheFactory::create();
    
            return $redis->setex($this->key, $rptData->expired,json_encode($rptData));
        }
    
        /**
         * 写入数据
         * @param $data
         * @param int $expired
         * @return bool
         */
        public function save($data,$expired=7200){
    
            $rptData = new Data();
            $rptData->data = $data;
            $rptData->expiredTime = time();
            $rptData->isRead = true;
            $rptData->expired = $expired;
            $redis = CacheFactory::create();
    
            return $redis->setex($this->key, $rptData->expired,json_encode($rptData));
        }
    }
    
    /**
     * Class Data redis存储数据实体
     * @category cache
     * @package cache
     * @author oShine <oyjqdlp@126.com>
     * @version 2.0.0.0
     * @copyright oShine 2015/08/07
     */
    class Data {
        /**
         * @var int $expired 失效间隔时长
         */
        public $expired;
        /**
         * @var int
         */
        public $expiredTime;
        /**
         * @var mixed 存储的具体数据
         */
        public $data;
        /**
         * @var bool 是否可以读取
         */
        public $isRead;
    
        /**
         * 是否失效
         * @return bool
         */
        public function isExpired(){
            if(time()-$this->expiredTime > $this->expired)
                return true;
            return false;
        }
    }
    
    /**
     * Class Generate key生成
     * @category cache
     * @package cache
     * @author oShine <oyjqdlp@126.com>
     * @version 2.0.0.0
     * @copyright oShine 2015/08/07
     */
    class Generate {
        /**
         * @static
         * @param $key
         * @param $nick
         * @return string
         */
        public static function key($key,$nick){
            return md5($nick).".data.".$key;
        }
    }

    CacheFactory:

    <?php
    /**
     * @category cache
     * @package cache
     * @author oShine <oyjqdlp@126.com>
     * @version 2.0.0.0
     * @copyright oShine 2015/08/07
     */
    class CacheFactory {
    
        /**
         * @var Redis $instance
         */
        private static $instance = null;
    
        /**
         * @return Redis
         */
        public static function create(){
    
            if(self::$instance == null){
                self::$instance = new Redis();
                self::$instance->connect(Yii::app()->params["RedisServerIP"]);
            }else{
                try{
                    if(preg_match("/PONG/",self::$instance->ping())){
                        return self::$instance;
                    }
                }catch (Exception $e){
                    self::$instance = new Redis();
                    self::$instance->connect(Yii::app()->params["RedisServerIP"]);
                }
            }
            return self::$instance;
    
        }
    
    }

    Mutex:用于任务锁,辅助任务处理,使用Cache记录任务状态,告别表锁任务标记

    <?php
    
    /**
     * Class Mutex 用于任务锁
     * @category mutex
     * @package cache
     * @author oShine <oyjqdlp@126.com>
     * @version 2.0.0.0
     * @copyright oShine 2015/08/07
     * @example
     * Mutex::create($nick)->init("download")->wait()
     * Mutex::create($nick)->init("download")->doing()
     * Mutex::create($nick)->init("download")->done()
     * Mutex::create($nick)->init("download")->error()
     */
    class Mutex {
    
        /**
         * @var string
         */
        private $nick;
    
        /**
         * @param string $nick
         */
        public function __construct($nick){
            $this->nick = $nick;
        }
    
        /**
         * @param $nick
         * @return Mutex
         */
        public static function create($nick){
            return new self($nick);
        }
    
        /**
         * @param $nick
         */
        public static function clear($nick){
            $redis =  CacheFactory::create();
            $redis->del($redis->keys(md5($nick).".mutex.*"));
        }
    
        /**
         * @param $key
         * @return MutexStorage
         */
        public function init($key){
            $key = md5($this->nick).".mutex.".$key;
            return new MutexStorage($key, CacheFactory::create());
        }
    
    }
    
    /**
     * Class MutexStorage
     * @category mutex
     * @package cache
     * @author oShine <oyjqdlp@126.com>
     * @version 2.0.0.0
     * @copyright oShine 2015/08/07
     */
    class MutexStorage {
    
        private $key;
    
        /**
         * @var Redis $redis
         */
        private $redis;
    
        public function __construct($key,$redis){
            $this->key = $key;
            $this->redis = $redis;
        }
    
    
        /**
         * @return $this
         * @throws Exception
         */
        public function wait(){
            $this->save("WAIT");
            return $this;
        }
    
        /**
         * @return $this
         * @throws Exception
         */
        public function doing(){
            $this->save("DOING");
            return $this;
        }
    
        /**
         * @return $this
         * @throws Exception
         */
        public function done(){
            $this->save("DONE");
            return $this;
        }
    
        /**
         * @return $this
         * @throws Exception
         */
        public function error(){
            $this->save("ERROR");
            return $this;
        }
    
        /**
         * @param $data
         * @return $this
         * @throws Exception
         */
        protected function save($data){
    
            $data = json_encode(array("status"=>$data,"date"=>date("Y-m-d"),"timestamp"=>time()));
    
            $flag = $this->redis->setex($this->key,3*24*2400,$data);
            if(!$flag)
                throw new Exception("SAVE Error!");
            return $this;
        }
    
        /**
         * @return string|null
         */
        protected function get(){
    
            $data = json_decode($this->redis->get($this->key),true);
            if(strtotime(date("Y-m-d")) == strtotime($data["date"])){
                return $data["status"];
            }
            return null;
        }
    
    
        /**
         * @return bool
         */
        public function isDoing(){
            $data = json_decode($this->redis->get($this->key),true);
            if(isset($data) && isset($data["status"]) && $data["status"] == "DOING" && isset($data["timestamp"]) && (time()-$data["timestamp"])<60)
                return true;
            return false;
        }
    
        /**
         * @return bool
         */
        public function isDone(){
            $status = $this->get();
            if(isset($status) && $status == "DONE")
                return true;
            return false;
        }
    
        /**
         * @return bool
         */
        public function isError(){
            $status = $this->get();
            if(isset($status) && $status == "ERROR")
                return true;
            return false;
        }
    }
  • 相关阅读:
    Entity Framework 数据并发访问错误原因分析与系统架构优化
    项目中如何使用EF
    Entity Framework版本历史概览
    Entity Framework 6 预热、启动优化
    jQuery EasyUI Datagrid性能优化专题(转)
    jQuery EasyUI Datagrid VirtualScrollView视图简单分析
    用JS判断IE版本的代码
    【转】编写高质量代码改善C#程序的157个建议——建议56:使用继承ISerializable接口更灵活地控制序列化过程
    【转】编写高质量代码改善C#程序的157个建议——建议55:利用定制特性减少可序列化的字段
    【转】编写高质量代码改善C#程序的157个建议——建议54:为无用字段标注不可序列化
  • 原文地址:https://www.cnblogs.com/oshine/p/4761279.html
Copyright © 2011-2022 走看看