文章点击率刷新优化
php 2022-05-09 22:14:21 1427

由于是个人的服务器,配置方面还是很低的,因此,我决定优化一下自己的博客网站的文章查看功能。

优化之前,系统的逻辑是“用户每查看一次文章详情,就会将累计点击次数保存到数据库中”,这种频繁更新数据库的方式在高并发的情况下,显然是不合理的。

为此,我决定利用redis缓存来优化网站,操作步骤如下:

1、点击率的计数值保存在redis缓存中(该方法在文章详情展示时候调用)

/**
 * 累计文章点击率
 * @param $article
 */
public function incrementHits($article)
{
    $key = $this->getHitsKey();
    $redis = RedisService::getInstance();
    $hits = $redis->zscore($key, $article['id']);
    if (!$hits) {
        $redis->zadd($key, [
            $article['id'] => $article['hits']
        ]);
    }
    $redis->zincrby($key, 1, $article['id']);
}

2、直接从缓存中查询点击率

/**
 * 获取文章点击率
 * @param $article
 * @return int
 */
public function getHits($article): int
{
    $hits = RedisService::getInstance()->zscore($this->getHitsKey(), $article['id']);
    return $hits ?: $article['hits'];
}

3、创建点击率刷新任务:HitsRefresh

php artisan make:command HitsRefresh

4、编写HitsRefresh命令,核心代码如下

/**
 * 刷新数据表中的点击率
 */
public function storeHits()
{
    $members = RedisService::getInstance()->zscan($this->getHitsKey(), 0);
    foreach ($members[1] as $id => $hits) {
        ArticleModel::query()->where('id', '=', $id)->update([
            'hits' => $hits
        ]);
    }
}

5、将执行命令添加到定时任务中(每分钟执行一次)

# larastu crontab
* * * * * www-data cd /data/www/larastu && php artisan schedule:run 2>&1

6、任务执行频率设置为每天执行一次

/**
 * Define the application's command schedule.
 *
 * @param Schedule $schedule
 * @return void
 */
protected function schedule(Schedule $schedule)
{
    // 每天凌晨刷新一次点击率
    $schedule->command('hits:refresh')
        ->daily()
        ->runInBackground()
        ->sendOutputTo(storage_path('logs/schedule.log'), true);
}
©2021-2022 larastu.com 版权所有