3

我们有一组 Coldfusion 应用程序,它们都扩展了应用程序库的各个部分。我将提供一些代码,然后解释我们遇到的问题,看看是否有人可以阐明解决此问题的最佳方法:

在 app.cfc 中的“OnRequestStart”中,我们有以下行来启动用户:

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 个左右的其他应用程序以相同的方式扩展并且工作正常且永不崩溃,但这个确实如此。

编辑:为了更清楚地了解映射。我们的应用程序位于:

  • root.com/app1
  • root.com/app2

我们在 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_CAAAFACBBFDFFE 或

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 我们尚未在生产中应用更新 4 补丁。然而,我们认为这个问题发生在 CF10 之前。虽然我们有这个问题,但它最近才出现。这个有问题的应用程序已经像这样崩溃了很长时间。

编辑: 1. 我想当我说“崩溃”时,我的意思是应用程序进入一种状态,在我重新启动 Coldfusion 之前它不会正确声明映射。我假设我们代码中的错误会导致崩溃。2.这通常是问题发生的地方,在对 SESSION.user var 进行此检查时。我相信它也发生了,它决定它找不到我们的数据源。这是罕见的。3. 一开始我以为是的,但实际上没有,没有那么多。在我们的应用程序中,我们有几个常见映射的名称。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
  1. 我们所做的(我认为这很愚蠢)是我们有一个文件位于与当前应用程序不同的目录中。此文件称为 application_base.cfc。其他应用程序中的所有 application.cfcs 都是从这个 application_base.cfc 扩展而来的。它们不是从其他 Application.cfc 文件扩展而来的。(希望有意义)在 application_base 中有一个 init、onrequeststart 和一个 onerror。我将在下面发布 App.cfc。此外,一些设置是从应用程序库(以确定环境内容)和应用程序级别的 XML 文件中读取的。但是我们认为这可能是导致问题的原因,因此之前的开发人员在应用程序级别删除了 xml 文件。6.是的。我将发布 app.cfc 和 appbase.cfc,以便您查看两者。
  2. 通过重新初始化,您的意思是调用 onapplicationstart 或其他东西。从来没听说过。
  3. 我们做的一些应用程序:

    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 个应用程序相互交织在一起,旨在在具有不同路径的开发/生产环境中工作,有时很难说出我可以删除什么而我不能。

我以为我尝试从我们的错误处理程序中转储应用程序名称,但我认为除非传入它,否则它不起作用。我通过了映射,所以我可以看到它们,这就是我知道在“崩溃”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

4

3 回答 3

1

首先要做的事情:你为什么要初始化面向会话的东西onREQUESTStart()?如果您在 中启动它onSessionStart(),您就不需要在每个请求中检查它的存在,这 - 虽然微不足道 - 是不必要的开销,并且只是错误位置的错误代码。

其次......你引用你的错误,但不要说它发生在哪里。它发生在 onRequestStart() 的那一行吗?

如果是这样,请帮我一个忙:在它周围放一个 try/catch,然后在其中将 的值this.mappings以及 . 的值写入日志文件currPath。顺便说一句,该变量的值是如何得出的?

也就是说,我认为如果您将session.user初始化代码放在正确的位置,它将解决您的问题。

注意:几乎可以肯定这个问题不是内存泄漏(即:ColdFusion 的错),而是你的代码做了你没有预料到的事情(所以......错误......你的错;-)。这将有助于更好地专注于发现问题。我没有对你动手,但是“我的代码哪里错了”是比“它可能是别的东西”更好的方法。而且更有可能是正确的;-)

哦……你用的是什么版本的CF?

于 2013-01-11T22:02:35.390 回答
0

一些问题:

  1. 您是假设崩溃是由代码错误引起的,还是由于崩溃而发生代码错误?

  2. 会话用户的实例化是您看到这些路径错误的唯一代码行吗?

  3. 您的应用程序中是否有与映射名称同名的物理目录?

  4. 这是否发生在任何其他环境(开发/测试)中?这是集群环境吗?

  5. 是否有多个 Application.cfc 文件扩展同一个 Application.cfc?

  6. 是否有任何代码直接调用 Application.cfc 方法?

  7. 是否有任何代码导致应用程序重新初始化自身?

  8. 是什么确定meta_array用于派生应用程序名称的?

几点观察:

在我看来,应用程序名称正在更改,或者其他一些应用程序正在用相同的名称覆盖。这似乎并不牵强,因为这里正在进行大量的动态命名。从应用程序名称开始,它取决于当前模板的物理位置,这可能因请求而异,具体取决于应用程序路由请求的方式。如果当前模板发生变化,则应用程序名称将发生变化,并导致其他特定于应用程序的映射发生变化,这将对使用该应用程序名称来确定这些映射的物理位置的所有其他映射产生级联效应。

这就引出了一个问题:为什么所有这些对应用程序名称和映射位置的动态评估甚至是必要的?它可以简化或硬编码吗?您可以改用服务器映射吗?如果不必如此复杂,将其简化为最基本的要素将有助于故障排除并可能完全解决问题。

最后,您能否验证正常操作期间的应用程序名称是否与发生错误时引用的应用程序名称相同?

  • 如果它们不同,则某些原因导致应用程序在不同的上下文中执行(有关线索,请参阅我上面的初始问题)。应用程序名称的突然更改将使任何现有会话无效并强制会话用户实例化代码重新运行。并且由于用户组件路径部分基于应用程序名称,因此路径可能不再正确。

  • 但是,如果应用程序名称在正常操作和崩溃模式之间相同,则很可能该currpath变量受到应用程序的某些部分的影响,该应用程序的某些部分在与预期不同的物理路径中执行。由于currpath直接用于确定其余映射,这当然可以解释为什么意外路径会导致组件丢失。

  • 因为派生这些名称有很多变量,所以在正常操作和崩溃模式期间记录这些变量会很好。你会想看看

    GetCurrentTemplatePath()
    GetDirectoryFromPath(GetCurrentTemplatePath())
    THIS.name
    meta_array
    THIS.mappings
    

我怀疑在正常运行和发生崩溃/错误时,您会在这些变量中发现一些明显不同的东西,而这种差异应该会让您更接近答案。

于 2013-01-18T22:54:43.247 回答
0

看看这个,看看它是否与你的问题有关。 https://github.com/Mach-II/Mach-II-Framework/wiki/Application-Specific-Mapping-Workaround

如果不是,那么它可能与相同名称的应用程序特定映射有关,在同一个 CF 服务器上,这些应用程序具有不同的应用程序名称。

于 2013-01-11T22:03:30.897 回答