• 您好!欢迎来到金点子源码网!
  • 登录 注册

源码网_提供网站源码、discuz、wordpress主题与插件和站长教程等资源的下载服务

易优cdn阅读量不变的缓存规则

在使用 易优CMS(Youzhicms) 搭配 CDN 加速服务 时,如果遇到 文章阅读量(点击数)不增加或不变 的问题,这通常是由于 CDN 缓存机制将整个页面(包括动态的阅读统计接口)也缓存了,导致每次访问都返回缓存内容,而没有真正执行“阅读+1”的 php 动作。以下是系统解决方案:

一、问题根源分析

CDN缓存机制与阅读量冲突

<PRe class="ybc-pre-component ybc-pre-component_not-math">用户请求 → CDN返回缓存页面 → 阅读量JS不执行 → 计数不变 正常流程:用户请求 → 服务器处理 → 执行阅读量JS → 更新数据库

二、解决方案汇总

方案1:动态URL绕过缓存(推荐)

<!-- 在文章详情模板添加时间戳参数 -->
<script src="{:url('API/Article/views', ['id'=>$arcid, 't'=>time()])}"></script>

<!-- 或使用随机数 -->
<script>
var random = Math.random() * 10000;
var url = "{:url('api/Article/views', ['id'=>$arcid])}&AMP;r=" + random;
document.write('<script src="' + url + '"><\/script>');
</script>

方案2:CDN缓存规则配置

阿里云CDN配置:

<!-- 设置不缓存阅读量相关文件/URL -->
缓存规则:
1. 文件类型:不缓存 .php 动态文件
2. 目录规则:不缓存 /api/ 目录
3. URL参数:忽略特定参数(如 view、click)

具体设置:
位置:CDN控制台 → 域名管理 → 缓存配置
规则:/api/*.php?*  → 缓存时间 0秒
规则:/news/*.Html?view=* → 缓存时间 0秒

腾讯云CDN配置:

1. 目录刷新规则:
   - 文件类型:.php
   - 缓存时间:0秒
   
2. 节点缓存规则:
   - 添加规则:/api/article/views*
   - 缓存行为:不缓存

方案3:AJAX异步更新(最可靠)

// 在文章页面底部添加
<script>
$(function(){
    // 方法1:直接AJAX请求
    $.ajax({
        url: '/api/article/views',
        type: 'POST',
        data: {id: {$arcid}},
        dataType: 'json',
        success: function(res){
            console.log('阅读量已更新');
        }
    });
    
    // 方法2:图片方式(兼容性最好)
    var img = new Image();
    img.src = '/api/article/views?id={$arcid}&t=' + new Date().getTime();
});
</script>

image.png

三、易优官方阅读量机制优化

1. 修改阅读量更新逻辑

// 文件位置:application/common/model/Article.php
// 修改 getViews 方法或新增独立方法

public function updateViews($id){
    // 使用Redis或Memcached减少数据库压力
    $key = 'article_views_' . $id;
    
    // 方案A:使用Redis计数
    if(cache($key)){
        cache($key, cache($key) + 1, 3600);
    } else {
        $views = $this->where('arcid', $id)->value('click');
        cache($key, $views + 1, 3600);
    }
    
    // 定时写入数据库(如每10次更新一次)
    if(cache($key) % 10 == 0){
        $this->where('arcid', $id)->inc('click', 10)->update();
    }
}

2. 创建独立接口

// 创建 application/api/controller/Article.php
public function views(){
    $id = input('id/d', 0);
    if($id){
        // 防刷机制
        $ip = request()->ip();
        $cacheKey = 'view_ip_' . md5($ip . '_' . $id);
        
        if(!cache($cacheKey)){
            Db::name('archives')->where('arcid', $id)->inc('click')->update();
            cache($cacheKey, 1, 300); // 5分钟内不重复计数
        }
        
        return json(['code'=>1, 'msg'=>'success']);
    }
}

四、CDN缓存规则详细配置

Nginx + CDN 配置方案

# 在Nginx配置中添加
location ~* \.php$ {
    # 添加缓存头控制
    add_header Cache-Control "private, no-cache, no-store, must-revalidate";
    add_header Pragma "no-cache";
    add_header Expires 0;
    
    # 针对阅读量接口特殊处理
    if ($request_uri ~* "/api/article/views") {
        expires -1;
        add_header Cache-Control "no-cache";
    }
}

# 设置CDN缓存规则
location ~* \.(html|htm)$ {
    # 带参数的页面不缓存
    if ($args ~* "view=|update=") {
        set $no_cache 1;
    }
    
    expires 1h;
    add_header Cache-Control "public";
}

.htaccess 方案(Apache)

# 防止CDN缓存阅读量相关URL
<IfModule mod_headers.c>
    # 阅读量接口不缓存
    <FilesMatch "(views|click|update)" >
        Header set Cache-Control "no-cache, no-store, must-revalidate"
        Header set Pragma "no-cache"
        Header set Expires 0
    </FilesMatch>
    
    # 静态页面缓存
    <FilesMatch "\.(html|htm)$">
        Header set Cache-Control "max-age=3600, public"
    </FilesMatch>
</IfModule>

五、云服务商具体配置

阿里云CDN:

1. 控制台 → CDN → 域名管理 → 缓存配置
2. 添加缓存规则:
   - 规则类型:目录
   - 规则内容:/api/
   - 缓存时间:0
   - 优先级:最高
3. 添加文件类型规则:
   - 规则类型:文件后缀名
   - 规则内容:php
   - 缓存时间:0

腾讯云CDN:

1. 控制台 → CDN → 域名管理 → 缓存配置
2. 节点缓存过期配置:
   - 文件类型:.php
   - 不缓存
3. 目录刷新:
   - 刷新路径:/api/*
   - 刷新类型:刷新变更资源

又拍云CDN:

1. 服务 → 功能配置 → 缓存控制
2. 设置不缓存规则:
   - 路径:^/api/
   - 行为:不缓存
3. 设置边缘规则:
   - 匹配:$URI ~ "\.php"
   - 设置header:Cache-Control: no-cache

六、阅读量统计优化方案

1. 客户端延迟加载

// 页面加载完成后才发送阅读量请求
window.addEventListener('load', function(){
    setTimeout(function(){
        var script = document.createElement('script');
        script.src = '/api/article/views?id={$arcid}&_' + Date.now();
        document.body.appendChild(script);
    }, 3000); // 延迟3秒,确保页面被看到
});

2. 服务端聚合更新

// 定时任务批量更新阅读量
// 创建定时任务文件 application/cron/UpdateArticleViews.php

class UpdateArticleViews {
    public function run(){
        $redis = \think\facade\Cache::store('redis');
        $keys = $redis->keys('article_views_*');
        
        foreach($keys as $key){
            $id = str_replace('article_views_', '', $key);
            $views = $redis->get($key);
            
            if($views > 0){
                Db::name('archives')->where('arcid', $id)
                    ->inc('click', $views)
                    ->update();
                $redis->set($key, 0); // 重置为0
            }
        }
    }
}
// 配置定时任务每10分钟执行一次

七、验证与测试

测试步骤:

  1. 清理CDN缓存

    # 刷新CDN缓存
    curl -X POST "https://cdn.aliyuncs.com/?Action=RefreshObjectCaches" \
         -d "ObjectPath=你的域名/api/*" \
         -d "ObjectType=Directory"
  2. 测试阅读量更新

    // 控制台测试
    fetch('/api/article/views?id=文章ID')
      .then(res => console.log(res))
      .catch(err => console.error(err));
  3. 检查缓存头

    curl -I "https://你的域名/news/1.html"
    # 检查Cache-Control、X-Cache等头部

八、最佳实践建议

  1. 分离计数与内容

    • 阅读量通过独立API更新

    • 页面内容可被CDN缓存

  2. 设置合理的缓存策略

    首页:缓存1小时
    列表页:缓存30分钟
    详情页:缓存10分钟
    动态接口:不缓存
  3. 监控与报警

    • 监控阅读量增长异常

    • 设置CDN命中率报警

    • 定期检查缓存规则

  4. 备用方案

    • 准备无CDN的阅读量接口

    • 实现客户端本地计数+定时同步

    • 使用第三方统计工具(如CNZZ)作为补充

九、故障排除清单

  • [ ] CDN配置是否生效(检查响应头)

  • [ ] 阅读量接口是否可正常访问

  • [ ] 是否有防刷机制干扰

  • [ ] 数据库更新权限是否正常

  • [ ] 服务器时间是否同步

  • [ ] 防火墙是否拦截API请求

通过上述方案,可彻底解决CDN缓存导致的阅读量不更新问题。推荐使用方案3(AJAX异步更新) 配合CDN缓存规则配置,实现最优效果。

本文链接:http://www.7ov.cn/xinwendongtai/2118.html

版权声明:站内所有文章皆来自网络转载,只供模板演示使用,并无任何其它意义!

联系客服
网站客服 业务合作 在线客服QQ
294169012
微信号
微信号
微信号
返回顶部