【问题标题】:Rails local server sending and receiving requests at the same timeRails本地服务器同时发送和接收请求
【发布时间】:2016-11-11 17:46:31
【问题描述】:

所以也许这不是一个好的做法,但此时我的 Web 应用程序与其 API 共存于同一应用程序/同一服务器下。我想知道在这种情况下是否有任何方法可以加快服务器处理请求的速度?

例如,当我向同一服务器下的API发送请求时,我使用:

require 'rest-client'

tasks = RestClient.get 'localhost:8000/tasks', 
{
  content_type: :json,
  accept: :json, 
 "X-User-Email" => "blahblah@gmail.com", 
 "X-User-Token" => "blahblah"
}

但是,有时需要很长的时间才能得到结果。否则会导致“从服务器读取数据超时”错误。我想知道这是否是因为服务器正在向自己发送请求并同时从自己接收请求。我尝试在端口 8000 上打开另一台服务器,向端口 3000 服务器发送请求,它的速度要快得多。 Rails 在多线程方面有那么糟糕吗?

$ rails s -p 8000 -P 42323

另外,如果我先刷新8000端口的服务器页面再发送请求,那么刷新3000端口的服务器页面也会快很多。是不是因为响应已经被 Rack 缓存了?

P.S 如果我错误地使用了不同的术语,我深表歉意。

编辑

我已尝试从 API 和应用程序控制器进行调试。似乎最大的延迟发生在实际到达 API 控制器之前。如果将请求从端口 8000 发送到端口 8000 API,则服务器输出:

Started GET "/" for 127.0.0.1 at 2016-11-11 17:37:14 +0800
  User Load (0.7ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1  ORDER BY "users"."id" ASC LIMIT 1  [["id", 1234567]]
Processing by TasksApplicationController#index as HTML


Started GET "/tasks" for 127.0.0.1 at 2016-11-11 17:38:14 +0800
Processing by APIController#index as JSON

所以在它开始为 API 加载路由之前,已经过了一分钟!

所以如果我尝试让两个本地服务器运行并将请求从端口 3000 发送到端口 8000 服务器,这是更快版本的输出:

Started GET "/tasks" for 127.0.0.1 at 2016-11-11 17:42:25 +0800
Processing by APIController#index as JSON

不同的是,这部分输出没有了,也就没有了1分钟的延迟。

Started GET "/" for 127.0.0.1 at 2016-11-11 17:37:14 +0800
  User Load (0.7ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1  ORDER BY "users"."id" ASC LIMIT 1  [["id", 1234567]]
Processing by TasksApplicationController#index as HTML

为什么如果我从 8000 服务器向端口 8000 服务器发送请求,我有这个额外的部分会导致这么多的时间延迟?

【问题讨论】:

    标签: ruby-on-rails http concurrency puma


    【解决方案1】:

    这个问题很可能是因为您在开发模式下运行 Webrick。虽然 Webrick 是多线程服务器,Rails 也是多线程的,但在开发模式下,Rails 使用 Rake::Lock 中间件来阻止并发请求。

    要使 Webrick 在开发模式下完全多线程,您需要对中间件进行猴子补丁并通过创建以下初始化程序来删除 Rake::Lock:

    config/initializers/multithreaded_webrick.rb:

    # Remove Rack::Lock so WEBrick can be fully multi-threaded.
    require 'rails/commands/server'
    
    class Rails::Server
      def middleware
        middlewares = []
        middlewares << [Rails::Rack::Debugger] if options[:debugger]
        middlewares << [::Rack::ContentLength]
    
        Hash.new middlewares
      end
    end
    

    编辑我找到了该信息的原始来源:

    How rails resolve multi-requests at the same time?

    除了初始化器,你可能还需要设置:

    config.cache_classes = true
    config.eager_load = true
    

    【讨论】:

    • 我正在运行 puma 作为 rails 的服务器。我以为 puma 是为并发而生的?
    • 嗯是的 puma 应该是并发的开发。我没有时间实际检查一下-需要急于工作xD。但就您的问题而言 - rails 是并发的,是的,它可以在开发中运行多线程而没有任何问题 - 可能只是某个地方的配置问题。
    • 可能值得从 API 端输出调试信息,以尝试隔离问题是否首先出现在 API 中,或者 API 调用中的某些内容是否导致锁定。
    • @whales 你确定你正在运行 puma 作为服务器吗?从你的问题中我可以看出你不是 - 根据他们的页面你需要做rails s Puma
    • 也许这是可选的?当我刚刚运行“rails s”时,服务器启动输出类似于:“Booting Puma”等。而且即使我运行“rails s Puma”,问题仍然存在。
    猜你喜欢
    • 2022-09-23
    • 1970-01-01
    • 2019-04-19
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多