这让我发疯了。我们已经尝试构建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启动失败,表示位置idx的application.memcached.m数组中没有项目。
怎么会发生这种情况? CF阵列是使用弱引用还是其他什么?当阵列填充20个客户端时,阵列应该始终保持满是吗?
每个新客户端都会产生一个新线程,所以一旦我们失去了对客户端的引用,现在就可以关闭它,并且该线程永远存在于内存中。拜托,我错过了什么?
答案 0 :(得分:1)
也许您的应用范围会被删除。您应该为此指定适当的超时。无论是否调用OnApplication进行调试,您还应记录此信息。
答案 1 :(得分:1)
这个memcached CFC什么时候被使用?每个请求? “i”和“idx”变量缺乏变量范围可能很好与它有关。这里有几篇我写的文章,简单地演示了为什么这是必不可少的。
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/
答案 2 :(得分:0)
答案可能相当简单 - 这个类的任何实例化都会立即使应用程序范围内的数组无效,这使得这个类很难管理。此外,虽然间谍memcached驱动程序本身表现为单例,而数组(java.util.vector)是线程安全的,但此实现没有任何其他内容 - 不是应用程序范围,绝对不是cfc实例。
假设您可以在getCache()函数中消除idx的超出范围值(我假设您已经这样做了,如果没有,请在函数中抛出try / catch块并报告抛出异常时的idx) ),您可以通过在构造函数和getCache()方法周围使用具有相同名称的独占cflock来解决症状,而无需实际解决原因。这种方式即使您有类的随机实例化,当某些东西试图访问它时,您将永远无法将阵列吹出,并且在重新创建它时您将无法尝试访问它。这根本不是最佳解决方案,如果您遇到高并发性,您会发现响应时间略有提升(相当可以忽略不计,但根据您服务的请求数/秒数,它肯定会对最大吞吐量产生影响。< / p>