PHP cache应用
来源:互联网 发布:海知智能 王宇 编辑:程序博客网 时间:2024/06/12 01:01
PHP cache应用
作者:Wucl
时间:2014-12-08
章节内容:基础背景、实际应用、个人心得(这个人非常没品德,想到什么就写什么。)。
1. 基础背景:
在我们的网站项目中综合性页面的业务逻辑渐渐健全,随之数据接口也日渐增加,举个例子:综合性首页的数据接口已达到87个。然而,获取中间件接口数据是经过http协议,每个接口访问时间在20ms左右。为解决数据访问时间过长的问题项目组决定引入缓存的概念。
2. 实际应用:
1) PHP项目中常见的缓存有memcache和redis,下面的内容围绕redis展开(两者的API:http://my.oschina.net/cniiliuqi/blog/67423 ; http://php.net/manual/zh/book.memcache.php)。
2) 连接缓存服务器:由于连接次数频繁,我们选择使用了持久化连接方式,并把连接存放于静态变量。
获得一个cache连接:
/**
* 获得一个cache连接
* @param string $actionType
*/
public function _getConn() {
// 处理连接信息
$cacheConn = null;
switch ($this->_cacheType) {
case "memcached" :
if(!empty(static::$memInstance['memcached'] ) && static::$memInstance['memcached'] instanceof Memcached) {
$cacheConn = static::$memInstance['memcached'];
}else{
$cacheConn = $this->memcachedConn();
static::$memInstance['memcached'] = $cacheConn;
}
break;
case "redis" :
if(!empty(static::$memInstance['redis'] ) && static::$memInstance['redis'] instanceof Redis) {
$cacheConn = static::$memInstance['redis'];
try{
$cacheConn->ping(); //如果链接关闭则重新连
}catch(\RedisException $e){
$cacheConn = $this->redisConn();
static::$memInstance['redis'] = $cacheConn;
}
}else{
$cacheConn = $this->redisConn();
static::$memInstance['redis'] = $cacheConn;
}
break;
}
return $cacheConn;
}
redis服务器连接:
/**
* redis服务器连接
* @return Ambigous <NULL, \Redis>
*/
private function redisConn(){
$cacheConn = null;
$tryI = 0;
while ( $cacheConn == null && $tryI < 10 ) {
try {
$cacheConn = new Redis ();
$serverSetting = Config::$redis;
if (! $cacheConn->pconnect ( $serverSetting[$this->_serverType]['ip'], $serverSetting[$this->_serverType]['port'])) {
$this->_serverType = "default";
$cacheConn->pconnect ( $serverSetting[$this->_serverType]['ip'], $serverSetting[$this->_serverType]['port']);
}
$cacheConn->setOption ( Redis::OPT_SERIALIZER, Redis::SERIALIZER_NONE );
// 选择DB
$redisDB = $serverSetting[$this->_serverType]['redisDb'];
if ($redisDB > 0 && $redisDB <= 16) {
$cacheConn->select ( $redisDB );
} else {
$cacheConn->select ( 0 );
}
} catch ( \Exception $e ) {
sleep ( $tryI * 0.3 );
$tryI ++;
$cacheConn = null;
}
}
return $cacheConn;
}
memcached服务器连接:
/**
* memcached服务器连接
* @return multitype:
*/
private function memcachedConn(){
$cacheConn = null;
$tryI = 0;
while ( $cacheConn == null && $tryI < 10 ) {
try {
$cacheConn = new Memcached ();
$serverSetting = Config::$memcached;
if (is_array ( $serverSetting [$this->_serverType] )) {
foreach ( $serverSetting [$this->_serverType] as $vals ) {
$cacheConn->addServer ( $vals['ip'], $vals['port']);
}
}
if (! empty ( $cacheConn )) {
$cacheConn->setOption ( Memcached::OPT_CONNECT_TIMEOUT, 3000 );
$cacheConn->setOption ( Memcached::OPT_RECV_TIMEOUT, 3000 );
$cacheConn->setOption ( Memcached::OPT_SEND_TIMEOUT, 3000 );
$cacheConn->setOption ( Memcached::OPT_SERVER_FAILURE_LIMIT, 3 );
}
} catch ( \Exception $e ) {
sleep ( $tryI * 0.3 );
$tryI ++;
$cacheConn = null;
}
}
return $cacheConn;
}
配置文件结构:
static $redis = array(
'default' => array(
'ip' => '***',
'port' => ***,
'redisDb' => ***
),
'db0' => array(
'ip' => '***',
'port' => ***,
'redisDb' => ***
),
'db2' => array(
'ip' => '***',
'port' => ***,
'redisDb' => ***
)
);
3)获取和设置值注意序列化和压缩以及缓存时间:
/**
* 取得缓存
* @param $key 缓存关键词
* @param $compress 是否要解压缩
*/
public function get($key, $compress = true) {
$conn = $this->_getConn ();
if (empty ( $conn )) {
return false;
}
$result = false;
try {
if (! empty ( $conn )) {
if ($this->_cacheType == "memcached") {
$conn->setOption ( Memcached::OPT_COMPRESSION, false );
}
$result = $conn->get ( $key );
if ($this->_cacheType == 'redis') {
//$conn->close ();
unset ( $conn );
}
}
} catch ( \Exception $e ) {
}
if ($result !== false && $compress) {
$result = FormatClass::unserialize ( $result, $compress );
}
return $result;
}
/**
* 设置缓存
*
* @param $key
* @param $content
* @param $expire
* @param $compress
*/
public function set($key, $content, $expire = -1, $compress = true) {
$conn = $this->_getConn ();
if (empty ( $conn )) {
return false;
}
if ($compress) {
$data = FormatClass::serialize ( $content, $compress );
} else {
$data = $content;
}
try {
// 一定要有过期时间。避免缓存有增无减
if ($expire < 0) {
$expire = 86400;
}
switch ($this->_cacheType) {
case "memcached" :
$conn->setOption ( Memcached::OPT_COMPRESSION, false );
$result = $conn->set ( $key, $data, $expire );
break;
case "redis" :
$result = $conn->setex ( $key, $expire, $data );
break;
}
if ($this->_cacheType == 'redis') {
$conn->close ();
//unset ( $conn );
}
} catch ( \Exception $e ) {
error_log ( 'Cache set error' );
}
return $result;
}
}
4)删除和清空缓存不多做介绍。
3. 个人心得:
刚开始我们的缓存机制是使用普通链接,在上线时出现由于链接数剧增而导致服务器奔溃的问题。改用持久化连接并做了单例之后,这种情况大为改善。
- PHP cache应用
- Cache 应用
- Cache应用
- APC(Alternative PHP Cache)
- php cache类
- php Cache 类
- PHP Cache-control
- php apc cache 缓存
- PHP Caching / Cache || FILTERS
- PHP的realpath cache
- 用好Cache,优化应用
- cache单点登陆应用
- 用好Cache,优化应用
- shark应用cache
- java cache 简单应用
- Spring4.1 cache 应用
- 应用缓存(Application Cache)
- Guava Cache应用
- linux 下升级python版本
- jena构建本体,读取owl文件,输出owl文件相关知识
- 腾讯2013校园招聘笔试题
- 懈怠
- ibatis配置log4j输出sql日志信息
- PHP cache应用
- java保留两位小数
- HOG特征(毕业论文节选)
- SpringMVC使用@ResponseBody输出字符串时遇到的乱码问题及解决办法
- Apache Pig的一些基础概念及用法总结
- PHP使用curl实现put请求
- 第7周 热身(1)
- ibatis实战之OR映射
- java在数字前面自动补零的方法