我们有一组Coldfusion应用程序,它们都扩展了应用程序库的各个部分。我将提供一些代码,然后解释我们遇到的问题,看看是否有人可以解决问题的最佳解决方法:
在我们的" OnRequestStart"在app.cfc中,我们有以下行来启动用户:
if(!structKeyExists(SESSION, 'user'))
SESSION.user = CreateObject("component","cfcs.ds_user");
然后在ds_user.cfc中我们这样称呼它:
component extends="cas.cas_user" displayname="basic_user"{
应用程序及其所有部分运行就像它们应该的那样。但是,在一段时间后看似随机的方式,应用程序将崩溃,我必须重新启动ColdFusion服务以使其再次运行。我得到的错误是:
Could not find the ColdFusion component or interface cas.cas_user.
因此,无论出于何种原因,我的应用程序决定它无法找到父组件的路径。该cfc的映射位于顶部的application.cfc中,如下所示:
THIS.mappings["/cas"] = "#ReplaceNoCase(currpath,ListToArray(THIS.name,'_')[1],'cas30')#assets\cfcs\";
我想确定这样说,应用程序完全按照随机时间设计工作,然后找不到父组件,直到我在服务器上重新启动ColdFusion服务后才会再找到它。
我认为这是某种内存泄漏或其他什么,但我不知道从哪里开始寻找解决问题的方法。我们有6个左右的其他应用程序以相同的方式扩展并且工作正常且永不崩溃,但是这个应用程序确实如此。
编辑:更清楚地了解映射。我们的应用程序位于:
我们使用上面的方法在app1中创建了从app2获取cfcs的映射。虽然我认为这种方法很奇怪,但它在我们所有的应用程序中都有效。
编辑:显示一段时间的正确映射是:
/cfcs - D:\www\app1\assets\cfcs
/templates - D:\www\app1\assets\templates
/cas - D:\www\app2\assets\cfcs
/common - D:\www\app3\assets\common_elements
然而,一旦应用程序进入"崩溃模式",转储显示映射如下:
/cfcs - D:\www\app1\assets\cfcs
/templates - D:\www\app1\assets\templates
/cas - D:\www\app1\assets\cfcs
/common - D:\www\app1\assets\common_elements
以下是Application.cfc开头定义这些映射的方法:
currpath = GetDirectoryFromPath(GetCurrentTemplatePath());
THIS.mappings["/templates"] = "#currpath#assets\templates";
THIS.mappings["/cfcs"] = "#currpath#assets\cfcs";
THIS.mappings["/common"] = "#ReplaceNoCase(currpath,ListToArray(THIS.name,'_')[1],'gum')#assets\common_elements\";
THIS.mappings["/cas"] = "#ReplaceNoCase(currpath,ListToArray(THIS.name,'_')[1],'cas30')#assets\cfcs\";
THIS.name = digisign_CAAAFACBFDFFE或
name_var = (arrayLen(meta_array) >= 2) ? meta_array[arrayLen(meta_array) - 1] & '_' : 'root_';
THIS.name = name_var & right(reReplace(hash(getCurrentTemplatePath()), "[^a-zA-Z]","","all"), 64 - len(name_var));
哪里可能失败。似乎替换语句不起作用,因此在设置映射时,路径中的appname不会从app1更改为app2。是否有可能这与我们目前正在解决的这个错误有关:http://forums.adobe.com/message/4657868#4657868我们尚未在生产中应用Update 4补丁。然而,我们认为这个问题发生在CF10之前。虽然我们有这个问题,但它最近才出现。这个应用程序已经像这样崩溃了很长时间。
修改
我想当我说'#34;崩溃"我的意思是应用程序进入一个状态,在重新启动Coldfusion之前它不会正确地声明映射。我假设代码中的错误导致崩溃。
2.执行SESSION.user var检查时,通常会出现问题。我相信它也发生了,它决定它找不到我们的数据源。这很少见。
起初我想是的,但实际上没有,不是那么多。在我们的应用程序中,我们有几个常见映射的名称。 cas
common
cfcs
templates
等。但D:\www\cas
是应用domain.com/cas30
所在的位置。但是,该应用的旧版本位于domain.com/cas
。映射/cas
应该转到D:\www\cas30\assets\cfcs
并且有效。
4.我们有一个开发设置,这永远不会发生。 (我认为这是一个负载问题,这就是为什么它不会发生在dev上)。但是,我们的开发环境结构如此:
D:\www\deva\app1
D:\www\deva\app2
D:\www\devb\app1
D:\www\devb\app2
我们做过的一些应用程序:
currpath = GetDirectoryFromPath(GetCurrentTemplatePath()); app_path = ListToArray(currpath,' \'); THIS.name = app_path [ArrayLen(app_path)];
这个确实:
meta_array = ListToArray(GetMetaData(this).name,'.');
name_var = (arrayLen(meta_array) >= 2) ? meta_array[arrayLen(meta_array) - 1] & '_' : 'root_';
THIS.name = name_var & right(reReplace(hash(getCurrentTemplatePath()), "[^a-zA-Z]","","all"), 64 - len(name_var));
其他一些人也这样做。不确定它是两个不同的开发人员还是其他东西,但就是这样。
一旦应用程序失败,它将失败,直到我重新启动coldfusion。该应用程序需要从domain.com/app
页面登录,因此(不要说它无法从请求更改为请求),但请求位置始终与其失败相同。
上帝,我希望这不复杂。我最近从很多疯狂的东西中删除了我们当前的CMS,但是我们有7或8个应用程序彼此交织在一起并且设计用于具有不同路径的dev / prod环境,有时很难说我可以删除什么我能做什么。
我以为我尝试从我们的错误处理程序中转储applicationname,但我认为除非传入它,否则它不起作用。我通过了映射,所以我可以看到它们我知道的digisign
是不会改变为cas30
,而不应该在"崩溃"模式。
我认为所有动态映射都是如此,原始开发人员可以使用相同的app.cfc模板而无需更改任何内容。他喜欢做var a = (b) ? (a-c) ? a-f+b : (a+b) ? d : d; : a; h;
垃圾之类的东西没有评论,所以有时很难读出该死的代码,更不用说调试它了。
修改
我觉得这个问题和stackoverflow.com/q/14300915/1229594问题可能有关。我在此处发布了更多详细信息:forums.adobe.com/message/5022377#5022377
答案 0 :(得分:1)
首先要做的事情是:为什么要在onREQUESTStart()
中初始化面向会话的内容?如果你在onSessionStart()
中提到它,你不需要检查它是否存在每个请求,这虽然是微不足道的 - 是不必要的开销,而且只是在错误的地方错误的代码。
其次......你引用你的错误,但不要说它发生在哪里。它是否发生在onRequestStart()的那一行?
如果是这样,请帮个忙:在它周围放一个try / catch,并在其中将this.mappings
的值写入日志文件,以及currPath
的值。如何导出该变量的值,btw?
那就是说,我想如果你把session.user
初始代码放在正确的地方,它就能解决你的问题。
注意:构建此问题几乎肯定不内存泄漏(即:ColdFusion的错误),但是您的代码执行了一些您没预料到的事情(所以...错误... 你的错误;-)。这将有助于更好地集中精力发现问题。我没有去找你,但“我的代码错在哪里”是比“它可能是别的东西”更好的方法。而且更可能是正确的; - )
哦......你在哪个版本的CF?
答案 1 :(得分:0)
看看这个,看看它是否与您的问题有关。 https://github.com/Mach-II/Mach-II-Framework/wiki/Application-Specific-Mapping-Workaround
如果没有,那么它可能与同一CF服务器上具有相同名称的应用程序特定映射有关,而这些应用程序具有不同的应用程序名称。
答案 2 :(得分:0)
有些问题:
您是否认为崩溃是由代码错误引起的,或者是因为崩溃导致代码错误发生?
会话用户的实例化是您看到这些路径错误的唯一代码行吗?
您的应用中是否有与映射名称同名的物理目录?
这是否会在任何其他环境(dev / test)中发生?这是一个集群环境吗?
是否有多个Application.cfc文件扩展了同样的Application.cfc?
是否有任何代码直接调用Application.cfc方法?
是否有任何代码导致应用程序重新初始化?
确定用于派生应用程序名称的meta_array
是什么?
一些观察结果:
在我看来,应用程序名称正在改变,或者其他一些应用程序正在使用相同的名称进行覆盖。这看起来并不牵强,因为这里有很多动态命名。从应用程序名称开始,它取决于当前模板的物理位置,这可能与请求请求不同,具体取决于应用程序如何路由请求。如果当前模板不同,应用程序名称会有所不同,并导致其他特定于应用程序的映射发生更改,这会对使用应用程序名称确定这些映射的物理位置的所有其他映射产生级联效应。
这引出了一个问题:为什么所有这些对应用程序名称和映射位置的动态评估都是必要的?它可以简化还是硬编码?你可以改用服务器映射吗?如果它没有 这么复杂,那么将其简化为最简单的必需品将有助于排除故障,并可能完全解决问题。
最后,您是否可以验证正常操作期间的应用程序名称是否与发生错误时引用的应用程序名称相同?
如果它们不同,则会导致应用程序在不同的上下文中执行(请参阅上面的初步问题以获取线索)。应用程序名称的突然更改将使任何现有会话无效,并强制重新运行会话用户实例化代码。由于用户组件路径部分基于应用程序名称,因此路径可能不再正确。
但是,如果正常操作和崩溃模式之间的应用程序名称相同,则很可能currpath
变量受到在与预期不同的物理路径中执行的应用程序的某些部分的影响。由于currpath
直接用于确定映射的其余部分,因此可以解释为什么意外路径可能导致组件丢失。
由于导出这些名称的变量太多,因此您可以在正常操作期间和崩溃模式期间记录这些变量。你想看看
GetCurrentTemplatePath()
GetDirectoryFromPath(GetCurrentTemplatePath())
THIS.name
meta_array
THIS.mappings
我怀疑在正常运行和发生崩溃/错误时,您会发现这些变量有显着差异,这种差异会让您更接近答案。