0

这真让我抓狂。我们尝试构建一个 CF memcached 包装器。我们有一个这样的 memcached.cfc 组件:

<cfset this.m = arraynew(1)>

<cffunction name="init" access="public" output="false">
    <cfif not isdefined("application.memcached")
    ....
            <cfscript>
            setup();
                </cfscript>
         ...
            <cfset application.memcached = this>
          </cfif>
   <cfreturn application.memcached>
</cffunction>


<cffunction name="setup" access="private" output="false">
    <cftry>
        <cfset this.m = arraynew(1)>
        <cfloop from="1" to="#this.poolSize#" index="i">
            <cfset this.m[i] = createClient()>
        </cfloop>
        <cflog application="no" file="memcached" text="Successfully set up #this.poolSize# new memcache clients">
        <cfcatch>
            <cflog application="no" file="memcached" text="Exception in setup() while setting up the pool: type: #cfcatch.type#, message: #cfcatch.message#, detail: #cfcatch.detail#">
        </cfcatch>
    </cftry>
</cffunction>


<cffunction name="createClient" access="private" output="false">
    <cfset var AU = createObject("java", "net.spy.memcached.AddrUtil").init()>
    <cfset var c = createObject("java", "net.spy.memcached.MemcachedClient").init(AU.getAddresses("127.0.0.1:11211"))>
    <cfreturn c>
</cffunction>

<cffunction name="getCache" access="public" returntype="any" output="false">
    <cfset idx = ceiling(rand() * 20)>
    <cfreturn application.memcached.m[idx]>
</cffunction>

奇怪的是,运行 30 分钟左右后,getCache 开始失败,表明 application.memcached.m 数组中的位置 idx 处没有项目。

这怎么可能发生?CF 数组是使用弱引用还是什么?当然,一旦阵列填充了 20 个客户端,阵列应该始终保持满吗?

每个新客户端都会产生一个新线程,因此一旦我们失去对客户端的引用,现在就有办法将其关闭,并且该线程永远存在于那里并占用内存。请问,我错过了什么?

4

3 回答 3

1

也许您的应用程序范围被删除。您应该为此指定适当的超时时间。无论是否出于调试目的调用 OnApplication,您还应该记录此信息。

于 2011-06-29T07:14:10.397 回答
1

什么时候使用这个 memcached CFC?每个请求?'i' 和 'idx' 变量缺少 var 作用域可能与此有关。这是我写的几篇文章,它们简单地演示了为什么这是必不可少的。

http://duncan99.wordpress.com/2009/03/12/the-importance-of-var-scoping/

http://duncan99.wordpress.com/2009/03/16/the-importance-of-var-scoping-part-2/

于 2011-06-29T09:44:25.953 回答
0

答案可能相当简单——这个类的任何实例化都会立即使应用程序范围内的数组无效,这使得这个类管理起来相当麻烦。此外,虽然 spy memcached 驱动程序本身表现为单例,并且数组 (java.util.vector) 是线程安全的,但关于此实现的其他任何内容都不是 - 不是应用程序范围,绝对不是 cfc 实例。

假设您可以在 getCache() 函数中消除 idx 的越界值(我假设您已经这样做了,如果没有,请在函数中抛出一个 try/catch 块并在抛出异常时报告 idx 是什么),您可以通过在构造函数和 getCache() 方法周围使用具有相同名称的独占 cflock 来纠正症状,而无需实际解决原因。这样,即使您的类有随机实例化,您也永远无法在尝试访问它时将数组炸毁,并且在重新创建它时您将无法尝试访问它. 这根本不是一个最佳解决方案,如果您遇到高并发,您会注意到响应时间略有增加(可以忽略不计,但取决于您服务的请求数/秒,

于 2011-07-01T03:45:07.140 回答