使用缓存或应用程序范围创建计数器

Moh*_*mad 2 architecture coldfusion hit coldfusion-9

我想为我的ColdFusion应用程序创建一个点击计数器.我不希望在每个页面命中时更新数据库命中表.理想情况下,我想在应用程序范围中聚合命中,或者在某种类型的结构中聚合缓存,然后间歇地保存它们.

到目前为止我有想法:

想法1

  1. 创建应用程序或缓存结构以存储pageId和pageHits键值对.
  2. 在每个页面点击,检查是否存在pageId/ip地址cookie.
  3. 一个.如果存在,则不执行任何操作.
  4. 湾 如果没有,请设置它并更新应用程序或缓存中的hits结构.

问题:我不知道如何在经过一段时间后间歇性地将结构数据导入数据库.预定活动?

想法2

没有饼干; 将pageId/ip地址保存在自己的缓存/应用程序结构中.

问题我不确定如何构造数据结构/数组来存储信息.看起来很复杂的数组循环和结构查找.我仍然有与想法相同的问题.

任何建议,想法,批评?特别是,我需要帮助找出想法2的数据结构.我对性能比对数据完整性更感兴趣,并且对CF9唯一解决方案感到满意.我应该添加我希望将数据非规范化为每个页面ID的页面命中列.我不需要规范化的数据表.

ora*_*ips 5

尝试以您描述的方式捕获此数据会引入缓存过期的扩展问题,以避免在您最终希望持久保存到数据库时条目数增加时的OOM或长迭代次数.您要聚合的信息已在Web服务器日志中捕获.解析这些是一项简单的活动,您只需要编写一个能够了解这些翻转方式和时间的算法.

通过周期性使用log = fileRead('log.txt', 'read')和迭代.对于每个批处理,你可以按照你已经描述的方式,然后使用任何数据库方法进行INSERT/UPDATE(通常使用MERGE关键字,但MySQL是不同的)基于IP地址,如果这就是你所追求的.如果它是一个非常高的流量站点,请考虑将IP地址列的数据类型更改为整数数据类型,以加快索引查找速度.line fileReadLine(log)<cfschedule/>

更新

使用以下代码设置文件对象引用:

<cflock name="logparser" type="exclusive" timeout="1" throwontimeout="false">
    <cfif NOT structKeyExists(application, "logFile")>
        <cfset application.logFile =
            fileOpen('/path/to/log.txt', 'read')>
    </cfif>
    <cfloop condition="NOT FileisEOF(application.logFile)">
        <!--- replace with an appropriate algorithm --->
        <cfoutput>
            #fileReadLine(application.logFile)#
            <br />
        </cfoutput>
    </cfloop>
</cflock>
Run Code Online (Sandbox Code Playgroud)

这样做可以设置一次引用(即fileOpen()),跟踪它所在的行.然后当<cfschedule/>再次点击此代码时,它使用现有的引用(如果存在)并从那里向前迭代.锁定确保只有一个线程执行算法 - 所以你不必担心时间限制,只要它需要就让它继续运行.