2

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

我到目前为止的想法:。

理念一

  1. 创建一个应用程序或缓存结构来存储 pageId 和 pageHits 键值对。
  2. 在每个页面点击时,检查 pageId/ip 地址 cookie 是否存在。
  3. 一种。如果存在,什么也不做。
  4. 湾。如果没有,请设置它并更新应用程序或缓存中的 hits 结构。

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

想法 2

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

问题我不确定如何构建数据结构/数组来存储信息。数组循环和结构查找似乎很复杂。而且我仍然遇到与想法一相同的问题。

有什么建议、想法、批评吗?特别是,我需要一些帮助来确定想法 2 的数据结构。我对性能比数据完整性更感兴趣,并且对仅 CF9 的解决方案感到满意。我应该添加我希望将数据非规范化到每个页面 id 的页面点击列中。我不需要规范化的数据表。

4

2 回答 2

5

尝试以您描述的方式捕获此数据会引入缓存过期的扩展问题,以避免OOM或较长的迭代时间,因为当您最终想要持久保存到数据库时条目数量会增加。您要汇总的信息已在 Web 服务器日志中捕获。解析这些是一项简单的活动,您只需要编写一个知道这些翻转的方式和时间的算法。

通过 . 定期使用log = fileRead('log.txt', 'read')和迭代。对于每个批次,您可以按照您已经描述的方式,然后根据 IP 地址使用任何数据库方法进行 INSERT/UPDATE(通常使用 MERGE 关键字,但 MySQL 不同),如果那是您所追求的。如果它是一个非常高流量的站点,请考虑将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>

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

于 2011-05-31T17:42:46.017 回答
1

想法1:是的,<cfschedule>是你的朋友

思路二:保存pageId/ip地址?我想这更好地使用 Java 中的 Set,但是如果你给它分配一个空值,struct 也可以工作......

pageIDs["1"]["192.0.0.1"] = "";
hitsOfPage1 = structCount(pageIDs[1]));

但是,如果我再次访问该页面 tmr,我会不会被计算在内?

于 2011-05-31T17:23:50.060 回答