Ruby on rails 如何在rails应用程序中处理重用对象 注意:请注意,确定这是否是问题的最佳标题/可供编辑的建议,以备将来参考*

Ruby on rails 如何在rails应用程序中处理重用对象 注意:请注意,确定这是否是问题的最佳标题/可供编辑的建议,以备将来参考*,ruby-on-rails,postgresql,design-patterns,activerecord,architecture,Ruby On Rails,Postgresql,Design Patterns,Activerecord,Architecture,我有一个多租户rails应用程序,它允许客户端使用自己的定制TLD。因此,我可以: www.clientA.com www.clientB.com www.clientC.com 等等 不管是好是坏,my database(postgres)有一个tenants表,该表大约有60列,其中包含每个租户的各种设置和配置。有些只是标志,有些是大文本值 在application\u controller.rb中,我有一些逻辑来解析URL,根据域查询租户表,并实例化一个@current\u tenant对

我有一个多租户rails应用程序,它允许客户端使用自己的定制TLD。因此,我可以:

www.clientA.com

www.clientB.com

www.clientC.com

等等

不管是好是坏,my database(postgres)有一个tenants表,该表大约有60列,其中包含每个租户的各种设置和配置。有些只是标志,有些是大文本值

application\u controller.rb
中,我有一些逻辑来解析URL,根据域查询租户表,并实例化一个
@current\u tenant
对象。该
@current_tenant
对象在页面的整个生命周期中都可用。这在每一天都会发生。单身。页我的应用程序

虽然我有一些重缓存,但这种设计对我来说仍然感觉非常错误,我相信它可以改进


这方面有最佳实践吗?处理@current\u租户对象的最佳模式是什么?我关心内存管理。

您还可以使用Rails缓存来缓存
@current\u tenant
对象,即:

def current_tenant( host = request.host )
  Rails.cache.fetch(host, expires_in: 5.minutes) do
    Tenant.find_by(tld: host)
  end
end

您还可以使用Rails缓存来缓存
@current\u tenant
对象,即:

def current_tenant( host = request.host )
  Rails.cache.fetch(host, expires_in: 5.minutes) do
    Tenant.find_by(tld: host)
  end
end
(注意:我已经3年没有接触过Rails了,所以请用适当的一把盐来回答这个问题。)

这方面有最佳实践吗?处理@current\u租户对象的最佳模式是什么

我见过的实现这种东西的最好方法是用PHP,而不是RubyonRails。更具体地说,在Symfony框架中

简而言之,Symfony应用程序的布局如下:

/app    <-- app-specific Kernel, Console, config, cache, logs, etc.
/src    <-- app-specific source files
/vendor <-- vendored source files
/web    <-- public web folder for the app
。。。然后将每个域指向不同的/web文件夹

据我所知,可以将Rail项目的目录结构重新组织为或多或少等效的结构。请特别参阅此相关答案:

从那里,理论上讲,您可以为每个租户启动一个应用程序实例,每个实例都有各自的资源、硬编码默认值等,同时继续使用共享代码库

在我看来,下一个最好的选择是你目前正在做的事情。使用memcached或等效工具快速将特定域名映射到租户,并根据需要返回到数据库查询。我想您已经在做这件事了,因为您已经“准备了一些重缓存”

另一方面,你可能会发现这个相关的问题,以及其中的相关问题,很有趣:

(和FWIW一样,我最终没有坚持使用PHP开发多租户应用程序。上次我玩Ruby或Rails时没有灵丹妙药。)

关于内存使用情况,我认为不用太担心:严格地说,每个请求只需查找和创建租户对象一次。即使这样做的速度非常慢,但粗略地监测一下你的应用程序实际花费的时间将发现,与每个请求运行数百万次的看似无害的代码相比,这是微不足道的。

(注意:我已经3年没有接触过Rails了,所以请对此答案保持谨慎。)

这方面有最佳实践吗?处理@current\u租户对象的最佳模式是什么

我见过的实现这种东西的最好方法是用PHP,而不是RubyonRails。更具体地说,在Symfony框架中

简而言之,Symfony应用程序的布局如下:

/app    <-- app-specific Kernel, Console, config, cache, logs, etc.
/src    <-- app-specific source files
/vendor <-- vendored source files
/web    <-- public web folder for the app
。。。然后将每个域指向不同的/web文件夹

据我所知,可以将Rail项目的目录结构重新组织为或多或少等效的结构。请特别参阅此相关答案:

从那里,理论上讲,您可以为每个租户启动一个应用程序实例,每个实例都有各自的资源、硬编码默认值等,同时继续使用共享代码库

在我看来,下一个最好的选择是你目前正在做的事情。使用memcached或等效工具快速将特定域名映射到租户,并根据需要返回到数据库查询。我想您已经在做这件事了,因为您已经“准备了一些重缓存”

另一方面,你可能会发现这个相关的问题,以及其中的相关问题,很有趣:

(和FWIW一样,我最终没有坚持使用PHP开发多租户应用程序。上次我玩Ruby或Rails时没有灵丹妙药。)


关于内存使用情况,我认为不用太担心:严格地说,每个请求只需查找和创建租户对象一次。即使这样做的速度非常慢,但粗略地监控你的应用程序实际花费的时间将发现,与每个请求运行数百万次的看似无害的代码相比,它是微不足道的。

我设计了一个应用程序,它基本上正是你所描述的。由于您正在加载单个对象(即使是在每个页面请求上),因此只需确保查询只返回一行(当前租户),并且不会进行大量的连接。一个应用了限制的单行查询不会使您的站点崩溃,即使每秒请求数百次。不管怎样,如果你得到了这种类型的流量,你无论如何都必须扩展你的服务器

有一件事可以帮到你,那就是确保你的搜索列在数据库中被编入索引。如果要按url查找当前租户,请为url列编制索引

这是我所做的一个例子。我对变量进行了全球化处理,以便在所有控制器/模型/视图中都可以使用此信息

在我的应用程序控制器中:

before_filter :allocate_site


private

def allocate_site

  url = request.host_with_port
  url.slice! "www."

  # load the current site by URL
  $current_site = Site.find_by({:url => url, :deleted => false})

  # if the current site doesn't exist, we are going to create a placeholder
  # for the URL hitting the server. 
  if $current_site.nil?
    $current_site = Site.new
    $current_site.name = 'New Site'
    $current_site.url = url

    $current_site.save

  end
end

我设计了一个应用程序,它基本上就是您描述的那样。由于您正在加载单个对象(即使是在每个页面请求上),所以只需确保查询只返回一行(当前租户),而不执行疯狂的amo