我应该使用什么方法来确定我是在开发系统还是在生产系统上?在Ray Camden 的这篇文章中,他展示了如何查看您所在的文件夹,这可能是一个指标。
在开发中,我希望关闭错误捕获、关闭缺少模板、调试 cfstoredproc 和 cfquery 的 debug="yes",以及始终重新加载 onRequestStart 组件。
我应该使用什么方法来确定我是在开发系统还是在生产系统上?在Ray Camden 的这篇文章中,他展示了如何查看您所在的文件夹,这可能是一个指标。
在开发中,我希望关闭错误捕获、关闭缺少模板、调试 cfstoredproc 和 cfquery 的 debug="yes",以及始终重新加载 onRequestStart 组件。
我有两种方法,这两种方法都很好。我将首先从最简单的方法开始,这就是我所说的“静态”。当我没有很多特定于环境的设置时,我会使用它……也许是少数。
我假设您的应用程序有一个 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 | LocHostName 1 | '本地主机' 2 | 'devservername' 2 | '其他开发服务器名称' 3 | 'testservername' 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 和查询打开或关闭调试。虽然我必须说,但我强烈建议不要这样做。
你可以在你的开发盒上为你的 IP 启用 CFAdmin 中的调试,然后使用 IsDebugMode() 吗?
转储#server# 范围,您会看到一些可能有帮助的密钥——例如ColdFusion 的许可模式。
我们使用的解决方案是设置当前实例的 IP,并根据我们已知的“开发”IP 检查它。简单,容易,有效。
这里有很多很好的答案 - 我想提一下使用 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 - systest 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 的组合特别适合管理环境。
Fwiw,我将根据用于存储环境特定配置的环境名称在 application.cfc 中包含 ini 文件。我发现 getProfileSections() 对此非常有用,因为配置文件非常易于使用。我有一个在所有环境之间共享的通用文件,然后是环境特定的文件,用于那些需要针对每个环境进行定制的设置。
Is it possible to get the directory of the currently running application?
Consider this directory structure for the different "instances" of your application:
/home/deploy/DevLevel.0/MyApp
Production Version
/home/deploy/DevLevel.1/MyApp
Preview or Staging Version
/home/deploy/DevLevel.2/MyApp
Development Version
If you can read the path to the current application, it's easy to find the integer after DevLevel
. With that in hand (set as a global variable/constant), use it to change settings or behavior at runtime:
DevLevel == 0 means "Production"
DevLevel >= 1 means "Development"
For example, in the credit card authorization code:
if(DevLevel > 0)
enable_test_mode();
In error handling code:
if(DevLevel == 0)
send_error_to_log();
else
print_error();
Conclusion
The primary benefit here is that the code between the versions can remain 100% identical . No more "forgetting to enable this or disable that when moving code live".
Can this be implemented in ColdFusion?