没有不值得去解决的问题,也没有不值得去学习的技术!

行业资讯页面缓存未及时更新的排查分析

编辑一篇文章后,其更新时间已经是北京时区
1、行业资讯页面缓存未及时更新 。当后台添加了新的文章后,前台的列表页面未及时更新,总是需要等上 5 分钟后才更新,感觉页面缓存的依赖未生效。后台的最新的两篇文章未同步在前台更新。如图1
行业资讯页面缓存未及时更新 。当后台添加了新的文章后,前台的列表页面未及时更新,总是需要等上 5 分钟后才更新,感觉页面缓存的依赖未生效。后台的最新的两篇文章未同步在前台更新。
图1
2、但是同样的程序在本地环境是正常可用的。仔细分析差异,发现生产环境的后台的文章的更新时间要较之北京时间 早 8 小时。如果 updated_at 存的是 UTC 时间(即比北京时间晚 8 小时),而你用的是北京时间做判断(比如看页面没更新),会出现: 数据实际已更新(北京时间 15:30), 但 updated_at 是 2025-06-05 07:30:25(UTC), 所以缓存判断依赖的 MAX(updated_at) 没变化,页面继续用旧缓存。


public function behaviors()
    {
        $request = Yii::$app->request;
        $alias = $request->get('alias');
        $id = $request->get('id');
        $categoryId = (int)$request->get('c', 0);
        $keyword = trim($request->get('k'));
        $tag = $request->get('tag');
        $page = (int)$request->get('page', 1);

        $detect = new MobileDetect();
        $isMobile = $detect->isMobile() ? PageElementType::DEVICE_TYPE_MOBILE : PageElementType::DEVICE_TYPE_PC;

        $behaviors = [];

        // view 页面缓存
        if (!empty($alias)) {
            $dependency = new DbDependency([
                'sql' => 'SELECT updated_at FROM articles WHERE alias = :alias LIMIT 1',
                'params' => [':alias' => $alias],
            ]);
        } elseif (!empty($id)) {
            $dependency = new DbDependency([
                'sql' => 'SELECT updated_at FROM articles WHERE id = :id LIMIT 1',
                'params' => [':id' => $id],
            ]);
        } else {
            $dependency = null;
        }

        $behaviors['pageCacheView'] = [
            'class' => PageCache::class,
            'only' => ['view'],
            'duration' => 300,
            'variations' => [$id, $alias, $isMobile],
            'dependency' => $dependency,
            'cache' => 'fileCache',
        ];

        // index 页面缓存,仅当无关键词和标签时启用
        if ($keyword === '' && empty($tag)) {

            $category = null;
            if (!empty($alias) && UrlHelper::isValidAlias($alias)) {
                $category = Yii::$app->db->cache(fn() => ArticleCategory::find()
                    ->where(['alias' => $alias, 'status' => CommonArticleCategory::STATUS_NORMAL])
                    ->limit(1)
                    ->one(), 300);
            } elseif (!empty($categoryId)) {
                $category = Yii::$app->db->cache(fn() => ArticleCategory::find()
                    ->where(['id' => $categoryId, 'status' => CommonArticleCategory::STATUS_NORMAL])
                    ->limit(1)
                    ->one(), 300);
            }

            if ($category !== null) {
                // 有分类筛选,仅依赖该分类的文章更新时间
                $indexDependency = new DbDependency([
                    'sql' => 'SELECT MAX(updated_at) FROM articles WHERE status = 1 AND category_id = :categoryId',
                    'params' => [':categoryId' => $category->id],
                ]);
            } else {
                // 无分类筛选,才依赖全表(不建议再进一步切分,否则复杂度会上升)
                $indexDependency = new DbDependency([
                    'sql' => 'SELECT MAX(updated_at) FROM articles WHERE status = 1',
                ]);
            }

            $behaviors['pageCacheIndex'] = [
                'class' => PageCache::class,
                'only' => ['index'],
                'duration' => 300,
                'variations' => [
                    $categoryId,
                    $alias,
                    $page,
                    $isMobile,
                ],
                'dependency' => $indexDependency,
                'cache' => 'fileCache',
            ];
        }

        return $behaviors;
    }


3、查看 php.ini 中的时区设置,其与 date.timezone = Asia/Shanghai 是等效的。决定修改为 date.timezone = Asia/Shanghai


date.timezone = PRC


4、设置 MySQL 连接时区,确保你的 PHP 连接数据库时设置了时区为 +08:00。在 Yii2 中可以这样做:


'components' => [
    'db' => [
        // ... 其他配置
        'on afterOpen' => function($event) {
            $event->sender->createCommand("SET time_zone = '+08:00'")->execute();
        },
    ],
],


5、编辑一篇文章后,其更新时间已经是北京时区。如图2
编辑一篇文章后,其更新时间已经是北京时区
图2

PHP / Laravel / Yii2 老项目维护与长期技术支持

如果你的 PHP / Laravel / Yii2 项目已经上线,但遇到原开发离职、Bug 长期无人修复、接口不稳定、性能下降、代码难以接手等问题,可以联系我做一次远程技术排查。

适合以下情况:
✅ 老旧 PHP 系统无人维护
✅ Laravel / Yii2 项目 Bug 修复
✅ 后台管理系统小功能迭代
✅ RESTful API 接口排查
✅ MySQL / Redis / Nginx 性能问题
✅ 长期远程兼职维护

可先从一次小问题开始:
✅ 线上报错排查
✅ 接口异常分析
✅ 慢查询与性能瓶颈定位
✅ 代码结构初步评估
✅ 部署环境与日志检查

如需咨询,请联系我,并注明:PHP 维护咨询

联系方式:
Telegram:@shuijingwan
微信:13980074657
邮箱:shuijingwanwq@gmail.com

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理