|
|
<?php
|
|
|
|
|
|
namespace Plugin;
|
|
|
|
|
|
use Hood\Cache as HoodCache;
|
|
|
|
|
|
/**
|
|
|
* 数据缓存的操作类
|
|
|
*
|
|
|
* @name Cache
|
|
|
* @package Plugin
|
|
|
* @copyright yoho.inc
|
|
|
* @version 1.0 (2015-10-10 11:23:47)
|
|
|
* @author fei.hong <fei.hong@yoho.cn>
|
|
|
*/
|
|
|
class Cache
|
|
|
{
|
|
|
|
|
|
/**
|
|
|
* 设置缓存
|
|
|
*
|
|
|
* 备注:
|
|
|
* 采用主从分布式缓存
|
|
|
* master 代表主缓存服务器
|
|
|
* slave 代表从缓存服务器
|
|
|
*
|
|
|
* 作用:
|
|
|
* 在后端的服务异常挂掉了并且主服务器缓存(master)的数据时间到期后,
|
|
|
* 能获取从服务器缓存(slave)的数据,不影响前端页面的正常访问.
|
|
|
*
|
|
|
* @param string $key 键名
|
|
|
* @param mixed $value 需要缓存的数据
|
|
|
* @param int $expire 缓存有效期(单位秒, 0表示永久)
|
|
|
* @return void
|
|
|
*/
|
|
|
public static function set($key, $value, $expire = 300)
|
|
|
{
|
|
|
try {
|
|
|
// WINDOWS
|
|
|
if (DIRECTORY_SEPARATOR === '\\') {
|
|
|
HoodCache::Memcache('master')->set(self::makeKey($key, 'master'), $value, $expire);
|
|
|
HoodCache::Memcache('slave')->set(self::makeKey($key, 'slave'), $value, 86400); // 二级缓存1天
|
|
|
}
|
|
|
// LINUX
|
|
|
else {
|
|
|
HoodCache::Memcached('master')->set(self::makeKey($key, 'master'), $value, $expire);
|
|
|
HoodCache::Memcached('slave')->set(self::makeKey($key, 'slave'), $value, 86400); // 二级缓存1天
|
|
|
}
|
|
|
} catch (Exception $e) {
|
|
|
// do nothing
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取缓存
|
|
|
*
|
|
|
* @param string $key 键名
|
|
|
* @param string $node master代表主服务器, slave代表从服务器
|
|
|
* @return mixed
|
|
|
*/
|
|
|
public static function get($key, $node = 'master')
|
|
|
{
|
|
|
$result = array();
|
|
|
|
|
|
try {
|
|
|
// WINDOWS
|
|
|
if (DIRECTORY_SEPARATOR === '\\') {
|
|
|
$result = HoodCache::Memcache($node)->get(self::makeKey($key, $node));
|
|
|
}
|
|
|
// LINUX
|
|
|
else {
|
|
|
$result = HoodCache::Memcached($node)->get(self::makeKey($key, $node));
|
|
|
}
|
|
|
|
|
|
// 当接口异常,一级缓存没取到数据的情况
|
|
|
if ($node === 'slave') {
|
|
|
$incrementKey = self::makeKey('_increment_' . $key, 'slave');
|
|
|
$incrementValue = HoodCache::Memcached('slave')->get($incrementKey);
|
|
|
// 接口调用失败累计5次之后,回填二级缓存数据到一级缓存, 重置计数值为0
|
|
|
if (is_int($incrementValue) && $incrementValue > 5) {
|
|
|
HoodCache::Memcached('master')->set(self::makeKey($key, 'master'), $result, 300);
|
|
|
HoodCache::Memcached('slave')->set($incrementKey, 0, 3600);
|
|
|
}
|
|
|
// 接口调用失败次数累加
|
|
|
else {
|
|
|
HoodCache::Memcached('slave')->increment($incrementKey, 1, 0, 3600);
|
|
|
}
|
|
|
}
|
|
|
} catch (Exception $e) {
|
|
|
$result = array();
|
|
|
}
|
|
|
|
|
|
return $result;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 清除缓存
|
|
|
*
|
|
|
* @param string $key 键名
|
|
|
* @return void
|
|
|
*/
|
|
|
public static function delete($key)
|
|
|
{
|
|
|
// WINDOWS
|
|
|
if (DIRECTORY_SEPARATOR === '\\') {
|
|
|
HoodCache::Memcache('master')->delete(self::makeKey($key, 'master'));
|
|
|
HoodCache::Memcache('slave')->delete(self::makeKey($key, 'slave'));
|
|
|
}
|
|
|
// LINUX
|
|
|
else {
|
|
|
HoodCache::Memcached('master')->delete(self::makeKey($key, 'master'));
|
|
|
HoodCache::Memcached('slave')->delete(self::makeKey($key, 'slave'));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 累加
|
|
|
*
|
|
|
* @param string $key
|
|
|
* @param int $offset
|
|
|
* @param int $initialValue
|
|
|
* @param int $expiry
|
|
|
* @return boolean
|
|
|
*/
|
|
|
public static function increment($key, $offset = 1, $initialValue = 0, $expiry = 0)
|
|
|
{
|
|
|
return HoodCache::Memcached('master')->increment(self::makeKey($key, 'master'), $offset, $initialValue, $expiry);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 递减
|
|
|
*
|
|
|
* @param string $key
|
|
|
* @param int $offset
|
|
|
* @return boolean
|
|
|
*/
|
|
|
public static function decrement($key, $offset = 1)
|
|
|
{
|
|
|
return HoodCache::Memcached('master')->decrement(self::makeKey($key, 'master'), $offset);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 生成键名
|
|
|
*
|
|
|
* @param string $key 键名
|
|
|
* @param string $prefix 前缀标识
|
|
|
* @return string
|
|
|
*/
|
|
|
public static function makeKey($key, $prefix)
|
|
|
{
|
|
|
return md5($prefix . '_' . $key);
|
|
|
}
|
|
|
|
|
|
} |
...
|
...
|
|