打印 上一主题 下一主题

Discuz帖子查看数及附件下载数延迟更新详解

跳转到指定楼层
楼主
SetYun 发表于 2018-10-20 10:15:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
基于版本:Discuz! X 1.5 GBK Release 20110121
帖子查看数及附件下载数延迟更新,可明显降低访问量很大的站点的服务器(主要针对 MySQL 的压力)负担,建议开启本功能。但对其中的程序流程和功能细节,可能有很多站长不是很清晰,在这里码点文字给大家串一串,希望在这个地方以后遇到问题,可以为大家提供一些思路。

一、如何开启延迟更新

涉及的文件:source\admincp\admincp_setting.php
搜索关键字:delayviewcount

开启延迟更新在论坛后台的“全局 » 优化设置 » 服务器优化”中,按照需要在“点击数延迟更新”下勾选复选框就OK了,这个地方很简单。
在“点击数延迟更新”下有“主题浏览量”和“附件下载量”两项设置,但他们却是保存在同一个设置项目 delayviewcount 中的,所以这里从程序上做了点小处理。提交过来的两个选项,如果勾选其值即为1,不勾选其值即为0,将其拼接成二进制的字符,然后再将其转换为十进制后存到数据库中的。即为:
附件下载量关闭值为0,主题浏览量关闭值为0,拼接为二进制的数字为00,转换为十进制为0;
附件下载量关闭值为0,主题浏览量开启值为1,拼接为二进制的数字为01,转换为十进制为1;
附件下载量开启值为1,主题浏览量关闭值为0,拼接为二进制的数字为10,转换为十进制为2;
附件下载量开启值为1,主题浏览量开启值为1,拼接为二进制的数字为11,转换为十进制为3。

所以在数据表(pre_common_setting 表)中存储的值(skey = 'delayviewcount' 时,svalue 对应的值)即为0、1、2、3。

二、主题浏览量延迟更新的实际使用

涉及的文件:source\module\forum\forum_viewthread.php
搜索关键字:function viewthread_updateviews

涉及的文件:source\function\function_misc.php
搜索关键字:function updateviews

主题的浏览量即为查看数,在浏览一个主题时(访问 forum_viewthread.php 文件),则会给该主题的查看数加1,这个动作在 viewthread_updateviews 这个函数(forum_viewthread.php 文件的 695 行附近)中进行。如果没有开启延迟更新,则会直接在 pre_forum_thread 表的对应的主题记录中的 views 字段上加1。根据后台设置中的值($_G['setting']['delayviewcount'] 的值,请参照上述对应值的开启关系)可以看出,值为1和3时均代表开启了主题浏览量的延迟更新,此时会进入延迟更新的流程。
延迟更新点击数会在 data/cache 目录下产生以 forum_threadviews 开头的 .log 文件,所以服务器上必须赋予这个目录可读可写的权限。每一个需要增加点击数的主题的 tid 都会写入这个文件中,并独自占一行,此时不会对 pre_forum_thread 表有任何写操作,达到延迟更新的目的。
当任意一个用户访问到主题浏览页(访问 forum_viewthread.php 文件)时,系统的时间戳的值的末尾两位为 00 时,便会触发将缓存的点击数一次性更新进数据库中。前面所讲的系统的时间戳如果大家不理解不要紧,就理解为 00 等于 100 秒,即每隔 100 秒就会触发一次更新,此处的 100 秒代表一个整点秒数的时间点,而不是时间间隔为 100 秒,所以触发更新必须在某一个时间点发生,而不是过 100 秒必定会发生一次更新。
举例:当前是午夜 00:00:00,100 秒之后是 00:01:40,则只有在 00:01:40 这一个时间点上有用户访问主题页面才会触发更新,如果刚巧没人访问则不会触发更新,便要等到下一个 100 秒后的时间点  00:03:20 的到来。
更新触发后,会调用 function_misc.php 文件中的 updateviews 函数(function_misc.php 文件的 299 行附近)执行批量的更新,将所有主题缓存的点击数一次性更新到数据库中。此过程需要 rename 函数的支持,所以要确保 data/cache 目录可读可写,并且在 PHP 的配置文件 php.ini 中不能禁止此函数,即 disable_functions 后面没有 rename 字样。

三、附件下载量延迟更新的实际使用

涉及的文件:source\module\forum\forum_attachment.php
搜索关键字:updateviews

涉及的文件:source\function\function_misc.php
搜索关键字:function updateviews

附件下载量,在下载一个附件时(访问 forum_attachment.php 文件),则会给该附件的下载数加1,这个动作在 updateviews 这个函数执行的周围(forum_attachment.php 文件的 178 行附近)进行。如果没有开启延迟更新,则会直接在 pre_forum_attachment 表的对应的附件记录中的 downloads 字段上加1。根据后台设置中的值($_G['setting']['delayviewcount'] 的值,请参照上述对应值的开启关系)可以看出,值为2和3时均代表开启了附件下载量的延迟更新,此时会进入延迟更新的流程。
延迟更新点击数会在 data/cache 目录下产生以 forum_attachviews 开头的 .log 文件,所以服务器上必须赋予这个目录可读可写的权限。每一个需要增加下载量的附件的 aid 都会写入这个文件中,并独自占一行,此时不会对 pre_forum_attachment 表有任何写操作,达到延迟更新的目的。
当任意一个用户下载附件(访问 forum_attachment.php 文件)时,系统的时间戳的值的末尾一位为 0 时,便会触发将缓存的下载量一次性更新进数据库中。前面所讲的系统的时间戳如果大家不理解不要紧,就理解为 0 等于 10 秒,即每隔 10 秒就会触发一次更新,此处的 10 秒代表一个整点秒数的时间点,而不是时间间隔为 10 秒,所以触发更新必须在某一个时间点发生,而不是过 10 秒必定会发生一次更新。
举例:当前是午夜 00:00:00,10 秒之后是 00:00:10,则只有在 00:00:10 这一个时间点上有用户去下载一个附件才会触发更新,如果刚巧没人下载则不会触发更新,便要等到下一个 10 秒后的时间点  00:00:20 的到来。
更新触发后,会调用 function_misc.php 文件中的 updateviews 函数(function_misc.php 文件的 299 行附近)执行批量的更新,将所有主题缓存的点击数一次性更新到数据库中。此过程需要 rename 函数的支持,所以要确保 data/cache 目录可读可写,并且在 PHP 的配置文件 php.ini 中不能禁止此函数,即 disable_functions 后面没有 rename 字样。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|SetYun ( 辽ICP备16005250号

GMT+8, 2024-5-4 05:17 , Processed in 0.037393 second(s), 4 queries , File On.

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表