【问题标题】:Passing custom info to mongrel_rails start将自定义信息传递给 mongrel_rails start
【发布时间】:2011-02-05 11:01:52
【问题描述】:

我真正不明白的一件事是如何将自定义启动选项传递给一个 mongrel 实例。

我看到一种常见的方法是使用环境变量,但在我的环境中这不起作用,因为我的 rails 应用程序服务于许多不同的客户端。许多代码在客户端之间共享,但也有许多差异,我通过子类化控制器和视图来重载或扩展现有功能或引入新功能。为了使这一切正常工作,我只需将模块加载路径 ($:) 添加到客户端特定模块的路径。

为了启动特定客户端的应用程序,我现在可以使用环境变量,例如 TARGET=AMAZONE。不幸的是,在某些系统上,我运行多个 mongrel 集群,每个集群服务于不同的客户端。其中一些系统在 Windows 下运行,为了启动 mongrel,我安装了 mongrel_services。显然,这使我的环境变量不合适。

将这些额外的数据传递给应用程序被证明是一个真正的挑战。首先,mongrel_rails service_install 将拒绝任何未记录的 [自定义] 命令行参数。我不太担心使用安装程序安装服务是微不足道的。

但是,即使我设法安装 mongrel_services 以便在运行时将自定义命令行选项 --target 传递给 mongrel_rails start,我也会收到错误,因为 mongrel_rails 无法识别开关。

以下是我看过的内容:

  1. 传递一个额外的参数:

    mongrel_rails start --target XYZ ...

  2. 使用配置文件并添加目标:XYZ,然后执行:

    mongrel_rails start -C x:\myapp\myconfig.yml

  3. 修改文件:

    Ruby\lib\ruby\gems\1.8\gems\mongrel-1.1.5-x86-mswin32-60\lib\mongrel\command.rb

  4. 也许我可以使用 --script 选项,但我在上面找到的所有文档都是针对 Unix 的

1 和 2 根本不起作用。我和 4 一起玩过,但从来没有让它做任何事情。所以我别无选择,只能选择 3。虽然它相对简单,但我讨厌更改 ruby​​ 库代码。

特别令人失望的是 2 不起作用。我的意思是在配置文件中添加其他 [自定义] 选项有什么不合理的?实际上,我认为这是 Rails 中缺少的基本部分。不知何故,应用程序应该能够注册和访问它期望的命令行参数。

如果有人知道如何使用当前的基础架构更优雅地做到这一点,我有一条巧克力鱼要赠送!!!

【问题讨论】:

    标签: ruby-on-rails command-line service mongrel


    【解决方案1】:

    可能没有必要向 mongrel 传递一些东西。可以使用现有的机制来提供您所寻求的灵活性。让我们首先尝试非常清楚这些约束。

    换句话说,似乎以下条件有效。

    • 使用相同的代码库(或非常相似的代码库)为多个客户提供服务
    • 在应用程序启动时(或执行之前)需要影响应用程序执行的标识符来定义应用程序行为
    • 可以在单个系统上使用多组 mongrel 集群,每个集群专用于单个客户端
      • 这意味着一组进程都使用相同的配置值服务于相同的代码库
    • 一些客户希望在 Windows 服务器上运行,这避免了使用某些 Unix 风格的环境和脚本行为。

    应该验证的一个假设是每个代码库都在一个单独的目录中。如果是这样,那么可能会有一个非常简单的解决方案。

    如果每个客户都在自己的目录中,像这样:

    /src
      /customer1
      /customer2
      /customer3
    

    如果您使用以下内容开始您的混合进程:

    [/src/customer1]$ mongrel_rails cluster::start
    

    然后,您可以拥有一个在系统启动时读取的customer_config.yml 文件(在您的 environment.rb 中),您可以在其中放置您的客户端自定义值。因此,如果您需要传入“Amazone”作为目标值,那么您的 yaml 文件可能如下所示:

    target:
      Amazone
    

    然后,每个客户都会获得自己的 customer_config.yml 文件,该文件仅驻留在他们的目录中,您只需更改一个文件即可在添加新客户时切换行为。

    修改你的 environment.rb 来寻找一个特别命名的 YAML 文件是完全可以接受的。解析 YAML 文件相当容易,并且为管理每个客户的自定义提供了很大的灵活性。

    【讨论】:

    • 你的所有假设都是正确的,除了不是“每个客户都在自己的目录中”。我们的结构看起来更像: root/app/controllers/foo root/app/controllers/foo/Amazone root/app/controllers/foo/Nile root/app/controllers/foo/Kongo root/app/views/foo root/app /views/foo/Amazone root/app/views/foo/Nile root/app/views/foo/Kongo root/config root/config/Amazone root/config/Nile root/config/Kongo root/log root/log/Amazone root/log/Nile root/log/Kongo 等。客户特定文件夹(即 Amazone、Nile、Kongo)仅在客户确实需要自定义特定行为时才存在。
    • 重要的是,如果您为 Nile 启动 Rails 应用程序,Amazone 或 Kongo 中的所有文件都没有任何相关性,如果您删除任何文件夹,系统对于 Nile 的工作都一样途中有 Amazone 或 Kongo。显然,我们需要传递给启动代码的东西,以便它可以确定要激活哪个实现。我不在乎,如果这是通过 YAML 文件的内容(例如 -C 开关)、自定义命令行开关或 --script 参数发生的。
    • 感谢您的澄清。解决方案可能会稍微扩展 Rails 约定。我发现,在 ROR 中遇到困难通常意味着我偏离常规太远了。流量如何导向应用程序?与 Kongo 或 Nile 网站相比,希望访问 Amazone 网站的访问者如何到达那里?
    猜你喜欢
    • 2015-08-14
    • 2023-02-17
    • 2017-09-14
    • 2014-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-18
    • 2012-10-02
    相关资源
    最近更新 更多