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

Troubleshooting Delayed Cache Updates on the Industry News Page

After editing an article, its update time is now in the Beijing timezone

1. The industry news page cache was not updating in time. When a new article was added in the backend, the frontend list page did not update immediately; it always took a 5-minute wait before updating, making it seem like the page cache dependency was not taking effect. The two latest articles in the backend were not synced to the frontend for update. See Figure 1.

The industry news page cache was not updating in time. When a new article was added in the backend, the frontend list page did not update immediately; it always took a 5-minute wait before updating, making it seem like the page cache dependency was not taking effect. The two latest articles in the backend were not synced to the frontend for update.
Figure 1

2. However, the same program works normally in the local environment. Upon closer analysis of the differences, I found that the article update time in the production environment’s backend was 8 hours earlier than Beijing Time. If updated_at stores UTC time (which is 8 hours behind Beijing Time) and you use Beijing Time for the check (for example, when seeing that the page hasn’t updated), the following occurs:

The data has actually been updated (Beijing Time 15:30),

but updated_at is 2025-06-05 07:30:25 (UTC),

so the MAX(updated_at) that the cache check relies on hasn’t changed, and the page continues to use the old cache.

PHP

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. I checked the timezone setting in php.ini, which is equivalent to date.timezone = Asia/Shanghai. I decided to change it to date.timezone = Asia/Shanghai.

PHP

date.timezone = PRC

4. Set the MySQL connection timezone to ensure that your PHP database connection uses the +08:00 timezone. In Yii2, you can do this as follows:

PHP

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

5. After editing an article, its update time is now in the Beijing timezone. See Figure 2.

After editing an article, its update time is now in the Beijing timezone
Figure 2

关于作者 · 持续学习与技术实践

我是一名拥有 15 年以上开发经验的技术从业者,自 2013 年起持续运营个人技术博客,记录工作与个人项目中遇到的真实问题,以及解决问题过程中的探索、实践和思考。

除了技术写作,我也在持续开发和维护自己的独立项目,探索新技术和新工具在实际场景中的应用。我始终相信,没有不值得去解决的问题,也没有不值得去学习的技术。

如果这篇文章对你有所帮助,欢迎浏览博客中的其他文章,也欢迎交流技术经验与想法。

关于我  ·  GitHub  ·  邮件联系