【问题标题】:Determining dev vs production确定开发与生产
【发布时间】:2009-11-22 20:31:35
【问题描述】:

我应该使用什么方法来确定我是在开发系统还是在生产系统上? 在this post from Ray Camden 中,他展示了如何查看您所在的文件夹,这可能是一个指标。

在开发时,我希望关闭错误捕获、关闭缺失模板、调试 cfstoredproc 和 cfquery 的 debug="yes",以及始终在 onRequestStart 上重新加载组件。

【问题讨论】:

  • 每个环境的URL是否不同?如果是这样,CGI 范围有你的答案。

标签: coldfusion application.cfc


【解决方案1】:

我有两种方法,这两种方法都很好用。我将首先从最简单的方法开始,这就是我所说的“静态”。当我没有很多特定于环境的设置时,我会使用它……也许是一小部分。

我假设您的应用程序有一个 Application.cfc 或 .cfm 文件。在那里,您可以设置一个变量,例如“application.environment”,默认情况下它会设置为“dev”。在整个应用中,您可以检查该变量以确定您所在的位置。

当您打包应用程序以进行部署时,您可以将 Application.cfc 文件更改为改为“”。

现在,这会很烦人,所以我只使用 ant。我只是在我的 build.xml 中使用这样的东西,它与 Application.cfc 位于同一目录中:

<replace file="Application.cfc" token="DEV" value="PROD" casesensitive="true" />

然后压缩应用程序进行部署:

<zip destfile="${zipdir}/MyApp-Production.zip">
<zipfileset dir="." prefix="MyApp" />           
        </zip>

然后我部署 zip。如果我正在处理一个使用 FTP 而不是一些企业企业部署的小项目,那么我将有一个 ANT 任务,将 FTP 文件发送到我的生产服务器,它还将在 Application.cfc 上执行替换并推送那个文件也是。

对于我工作的大多数应用程序,我们使用两个数据库表来管理环境。我们这样做是因为我们有很多不同的环境,每个环境都有不同的设置,通常集中在每个环境不同的文件系统和网络路径上(我们不要谈论它们为什么不同......完全单独讨论)。所以我们有一个我们称之为“AppLocations”的表:

位置 ID |地点名称 | LocDesc |设置1 |设置2 |设置 3| …… 1 |本地 | '本地主机环境' |任何..... 2 |开发 | '发展环境' |任何.... 3 |测试 | '测试环境' |随便......

等等。

然后,我们有另一个名为“AppLocationHosts”的表

位置 ID |本地主机名 1 | '本地主机' 2 | '开发服务器名称' 2 | '其他开发服务器名称' 3 | '测试服务器名称' 3 | '其他测试服务器'

等等。

然后,在 Application.cfc 中的 onApplicationStart 中,我们执行此查询

SELECT TOP 1 *
        FROM AppLocations
        WHERE LocationID IN (SELECT LocationID FROM AppLocationHosts WHERE LocHostName =  <cfqueryparam value="#CGI.HTTP_HOST#" cfsqltype="cf_sql_varchar"/>)

从那里,一旦我们根据 http_host 匹配知道我们所在的位置,我们将那些“设置”列设置到应用程序范围中:

<cfloop list="#qryAppPathLocations.ColumnList#" index="ColName">
        <cfset application[ColName] = qryAppPathLocations[ColName]>
    </cfloop>

这种方法并不适合所有人,但在我们这种不寻常的怪异环境中,这是一种非常灵活的方法。

现在,如果您实际上只有两个环境,其中一个是“localhost”,另一个是“www.myapp.com”,那么到目前为止最简单的方法就是在 onApplicationStart 中检查 http_host 和如果您在“www.myapp.com”中,那么您可以进行特定于生产的设置。也许您在这里设置了诸如“request.querydebug = true”之类的东西,然后当您投入生产时,您将其关闭。然后您的查询可以使用该标志来确定是否为 cfstoredproc 和查询打开或关闭调试。虽然我必须说,但我强烈建议不要这样做。

【讨论】:

  • 哇,马克。多么深思熟虑的回应。这里有很多事情要考虑。我不认为我喜欢使用 cgi 范围的想法。我希望 build.xml 在项目文件夹之外,这样开发和生产可能是相同的。访问数据库可能是一种选择,因为我已经访问了数据库以查看自上次 onrequeststart 以来它是否已重建。我不知道为什么我以前没有想到这一点。
  • Phil,您可以将构建文件保存在任何您想要的地方。在我上面的例子中,我在项目中有它,因此 zipfileset dir=".",因为 "."意思是“这个目录”。但是您也可以轻松地执行 ,即只需将 dir 指向您要压缩的任何目录。
【解决方案2】:

您能否在您的开发盒上为您的 IP 启用 CFAdmin 中的调试,然后使用 IsDebugMode()?

【讨论】:

  • 太棒了!但是等等:我已经开始调试,IsDebugMode() 返回“NO”。
  • 您确定您的 IP 是允许的并且您没有有效的
【解决方案3】:

转储#server# 范围,您会看到一些可能有帮助的密钥 - 例如 ColdFusion 的许可模式。

【讨论】:

  • 也许吧。不知道逻辑是什么。
【解决方案4】:

我们使用的解决方案是设置当前实例的 IP,并根据我们已知的“开发”IP 检查它。简单、轻松、有效。

【讨论】:

    【解决方案5】:

    这里有很多好的答案 - 我想提一下使用 cgi.server_name ,它可以与使用自定义 DNS 结合来指定您的开发环境。要让 localhost 正常工作,对于 Windows 上的 IIS,设置主机文件,例如这个:

    C:\Windows\System32\drivers\etc\hosts - 添加条目: 127.0.0.1 myapp.dev.mydomain.com.au

    然后在 IIS 中将您的服务器映射到此 DNS。

    您的 systest 和 uat 服务器可能已在您公司的 DNS 中正确设置,例如 myapp.systest.mydomain.com.au - 系统测试 myapp.uat.mydomain.com.au - uat myapp.mydomain.com.au - 生产

    然后,在我的 application.cfc 中,我有一个 getEnvironment(),在每次加载时都会调用它以方便使用:

    // get the environment based on cgi variables - top of application.cfc
    this.stConfig = THIS.getEnvironment();
    
    //... onApplicationStart
    
    if (!stConfig.validEnvironment) {
        writeOutput("Environment #cgi.server_name# not recognised");
        return false;
    }
    
    // ...
    public struct function getEnvironment () {
        stConfig=structnew();
        stConfig.validEnvironment = 1;
    
        switch (cgi.server_name) {
            // my dev environment
            case "myapp.dev.mydomain.com.au": {
                stConfig.env = "dev";
                // +++
            }
            // my dev environment
            case "myapp.systest.mydomain.com.au": {
                stConfig.env = "systest";
                // +++
            }
            // etc
        }
        return stConfig;
    }
    

    我还将 stConfig 复制到请求范围。

    现在,我还有很多其他的东西,并且有很多方法可以实现环境的存储,例如但基本上我发现 DNS 和 cgi.server_name 的组合特别适合管理环境。

    接下来,我将根据用于存储环境特定配置的环境名称在 application.cfc 中包含 ini 文件。我发现 getProfileSections() 对此非常有用,因为配置文件非常易于使用。我有一个在所有环境之间共享的通用文件,然后是环境特定的文件,用于那些需要针对每个环境进行定制的设置。

    【讨论】:

      【解决方案6】:

      是否可以获取当前运行应用的目录?


      为您的应用程序的不同“实例”考虑这个目录结构:

      /home/deploy/DevLevel.0/MyApp
      生产版

      /home/deploy/DevLevel.1/MyApp
      预览版或暂存版

      /home/deploy/DevLevel.2/MyApp
      开发版


      如果您可以读取到当前应用程序的路径,则很容易找到DevLevel 之后的整数。有了它(设置为全局变量/常量),使用它在运行时更改设置或行为:

      DevLevel == 0 means "Production"
      DevLevel >= 1 means "Development"
      

      例如在信用卡授权码中:

      if(DevLevel > 0)
          enable_test_mode();
      

      在错误处理代码中:

      if(DevLevel == 0)
         send_error_to_log();
      else
         print_error();
      

      结论

      这里的主要好处是版本之间的代码可以保持100% 相同。不再“在实时移动代码时忘记启用或禁用它”。

      这可以在 ColdFusion 中实现吗?

      【讨论】:

      • 是的,它可以在 ColdFusion 中完成。在我们的开发服务器上,所有内容都在 /Projects 子文件夹下,因此 /Projects 根目录的存在会告诉我我是在开发还是生产。我想我的问题是:确定它的最佳方法是什么。我是否应该在 Web 根目录之外有一个 xml 文件来设置每个条件,例如日志记录、调试、错误捕获、格式化。或者我应该只是有一个开发与生产的二元标准。在生产过程中,有时我想关闭错误捕获。
      • 如果我把它放在一个xml文件中,这是否意味着我在RequestStart上读取了xml文件?可能不是。如果我有一个应用程序范围的变量,如 Application.ErrorTrapping、Application.Logging、Application.Debugging、Application.Reinit,那么如果它们已经设置,我不需要重新读取配置文件 onRequestStart。
      猜你喜欢
      • 1970-01-01
      • 2011-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-16
      • 2015-01-04
      • 2015-04-17
      • 2012-04-03
      相关资源
      最近更新 更多