Homeland ruby-china 项目启动太慢

zzzhc · 2011年12月03日 · 最后由 huacnlee 回复于 2012年05月19日 · 5999 次阅读

$ thin start

Using rack adapter => boot app used 12.491076 seconds Thin web server (v1.2.11 codename Bat-Shit Crazy) Maximum connections set to 1024 Listening on 0.0.0.0:3000, CTRL+C to stop ^C>> Stopping ...

12.5 秒有点难以相信,加了一些日志输出,发现 Bundler.require *Rails.groups(:assets => %w(production development test)) 就用了 8 秒多,具体时间: gem capistrano 1.169389 gem mongoid 1.118448 gem cancan 0.728886 gem omniauth-openid 0.72836 gem sass-rails 0.66818 gem cells 0.50212 gem devise 0.384832 gem resque/server 0.307842 gem nokogiri 0.286475 gem pygments.rb 0.263618 gem coffee-rails 0.259578 gem omniauth-github 0.221756 gem omniauth-twitter 0.166356 gem chunky_png 0.159891 gem hpricot 0.14857 gem unicorn 0.100408 gem simple_form 0.092415 gem redis-namespace 0.089901 gem bson 0.064406 gem mail_view 0.038172 gem carrierwave 0.037699 gem redis-search 0.029822 gem mini_magick 0.020013 gem bootstrap-rails 0.018979 gem omniauth 0.017419 gem jquery-rails 0.014385 gem will_paginate 0.012338 gem omniauth-douban 0.011814 gem rails-i18n 0.010006 gem uglifier 0.009484 gem mongo-rails-instrumentation 0.008598 gem carrierwave/mongoid 0.006706 gem redcarpet 0.006556 gem settingslogic 0.006227 gem resque_mailer 0.004644 gem rspec-rails 0.00423 gem chinese_pinyin 0.003639 gem rails_autolink 0.003052 gem mongoid_auto_increment_id 0.00302 gem rails 0.000641

capistrano 可以放到另一个 group,如 deploy; mongoid, cancan 这些貌似需要 gem 作者改成 autoload 的方式减少 require gem 的时间 现在 Gemfile 里用的 gems 太多了点,hpricot,nokogiri 这种最好只要选一个就好

cap 这种 gem 我一般会加:require => false hpircot 和 nokogiri 应该是其他 gem 依赖的吧 你的日志输入后面的时间是怎么搞的?有啥方便的方法吗?

跑个题:我发现很多开发者对 gem 或插件的态度非常不同,一个极端是能自己写的就不用 gem,另外一个极端就是能用 gem 的绝不自己写,即使一行代码就搞定的需求。

Bundler.require *Rails.groups(:assets => %w(production development test)) 里的 production 照里说可以去掉的。

是有必要改善一下了。

@hooopo, 在 config.ru 里加了几行记录时间 $ cat config.ru

This file is used by Rack-based servers to start the application.

app_start_init_time = Time.now

require ::File.expand_path('../config/environment', FILE)

app_init_finish_time = Time.now if Rails.env.development? puts "=> boot app used #{app_init_finish_time - app_start_init_time} seconds" end

run RubyChina::Application

開發時也遇到這問題,要幾十秒才能啟動是太慢了

其实加载服务器需要很长时间这是非常常见的,如果不是需要一定得在浏览器下面看到结果的话,TDD 就完全可以解决这个问题了啊。

#5 楼 @soloara 加载慢的话,TDD 就更慢了

#6 楼 @Rei 如果每次跑 Rspec 都加载整个 Rails ENV 肯定慢,完全可以拆出来跑的。如果不是必须动到 Rails 方法的代码修改也不需要重启服务器啊?如果是动到 Rails 或者其他库的方法,你需要扩展类什么的,为什么不用 TDD 写好了再 merge 进来?

#7 楼 @soloara 请教怎么拆出来跑……

举个例子,Mongoid 就是一个可以独立于 rails 使用的 gem,甚至 activerecord 一样,你如果需要覆盖或者扩展他们的方法的话,完全可以将其独立出来一个 poject,写好了你的 module,test 通过之后再放进 rails 环境下,如果只是纯粹的写 MVC 的东西,那就没必要重启服务了啊,rails 本身就动态加载变化了。

#8 楼 @Rei 用 spork,spin,都可以预加载环境跑 rspec,再和 guard 组合就可以快速自动测试

#10 楼 @cqpx 受教了,还真没用过这种预加载 rails env 的方法,看了下 spork,挺靠谱的。

#11 楼 @soloara 我现在自己的项目用 spork,和别人合作的项目用 spin,spin 不需要在代码里装环境 https://github.com/jstorimer/spin

gem i spin
spin serve
spin push test/unit/product_test.rb

#12 楼 @cqpx 这东西不错~

@soloara 在做 J2EE 項目時要幾分鐘啟動很常見,但 rails 環境不應這樣,開個 rails console 或行 test 也要等許久啊

@cqpx 很不錯!回家試試

#12 楼 @cqpx 两个的源码分别读了一下,spin 的代码是 hardcode 的 rails_env,spork 支持别的框架扩展。我现在是自己写了一个基于 rack 的框架,所以 spork 的可用性对我来讲高些。

#14 楼 @siuying LZ 说的是 12.5 秒额,不是几分钟,请注意

不过我确实觉的,ruby-china 用的 gem 太多了,这个 site 以当前规模来说有必要吗?我深深怀疑,这是其他话了。

快是关键,每次等着那个载入环境就要数十秒,对测试的激情荡然无存。

补充,有人说用 spork 可以解决问题。

开发启动慢一点可以接受。

Ruby 的资源真是大爆炸。重复度怎么那么高. 刚刚 spork 用熟了,又冒出来一个 spin, 刚刚 autotest 用熟了,又冒出来一个 kicker, 看这些我都看烦了。

如果是对性能要求比较高,有些库是需要自己优化的,不是直接 require 就行的

@zzzhc 请问那些 gem 的时间是如何抓出来的? thx

看了一下楼主的 gem 加载时间,除了几个比较费时外,其他的都可以接受。 可以考虑怎么优化那几个,或者找代替品。

如果 ruby 的对 gem 的加载机制,可以像 python 那样,加载一次,就预编译一下,下次加载不直接解释代码,效率可能会更高吧。一点渴望而已。

source 'http://ruby.taobao.org'

gem "rails", "3.2.2"
gem "rails-i18n","0.1.8"
gem "jquery-rails", "1.0.16"
gem "rails_autolink", ">= 1.0.4"
gem "jquery-atwho-rails", "0.1.3"

group :assets do
  gem 'sass-rails', "  ~> 3.2.3"
  gem 'coffee-rails', "~> 3.2.1"
  gem 'uglifier', '>= 1.0.3'
end

# 上传组件
gem 'carrierwave', '0.6.2'
gem 'carrierwave-mongoid', '0.2.0', :require => 'carrierwave/mongoid'
gem 'carrierwave-upyun', '0.1.3'
gem 'mini_magick','3.3'

# Mongoid 辅助插件
gem "mongoid", "2.4.8"
gem "bson_ext", "1.6.2"
gem 'mongo-rails-instrumentation','0.2.4'
gem 'mongoid_auto_increment_id', "0.4.0"
gem 'mongoid_rails_migrations', '~> 0.0.14'
gem "mongoid_colored_logger", "0.1.1"

# 用户系统
gem 'devise', '1.5.2'

# 分页
gem 'will_paginate', '3.0.2'
gem 'bootstrap-will_paginate', '0.0.3'

# 三方平台 OAuth 验证登陆
gem "omniauth", "~> 1.0.1"
gem 'omniauth-openid', "~> 1.0.1" # 没用了,可以去掉
gem "omniauth-github", "~> 1.0.0"
gem "omniauth-twitter", "~> 0.0.7" # 没用了,可以去掉
gem "omniauth-douban", :git => "git://github.com/ballantyne/omniauth-douban.git" # 没用了,可以去掉

# permission
gem "cancan", "~> 1.6.7"

# Redis 命名空间
gem 'redis-namespace','~> 1.0.2'

# 将一些数据存放入 Redis
gem "redis-objects", "0.5.2"

# Markdown 格式
gem "redcarpet", "~> 2.0.0"
gem 'hpricot', '~> 0.8.5'
gem "pygments.rb", '~> 0.2.4'

# YAML 配置信息
gem "settingslogic", "~> 2.0.6"

gem "cells", "3.7.1"

# 队列
gem "resque", "~> 1.20.0", :require => "resque/server"
gem "resque_mailer", '2.0.2'

# AWS Simple Email Server
gem "aws-ses", "~> 0.4.3"
gem 'mail_view', :git => 'git://github.com/37signals/mail_view.git' # 没用了,可以去掉

# 用于组合小图片
gem "sprite-factory", "1.4.1"

# 分享功能
gem "social-share-button", "~> 0.0.3"

# 表单 last commit: 2011-12-03
gem 'simple_form', :git => "git://github.com/plataformatec/simple_form.git"
gem 'bootstrap-rails', :require => 'bootstrap-rails', :git => 'git://github.com/xdite/bootstrap-rails.git'

# 全文搜索
gem 'sunspot_rails',  "~> 1.3.2"
gem 'sunspot_solr'

gem 'daemon-spawn' # 没用了,可以去掉

# 禁用 assets 日志
gem 'quiet_assets', :git => 'git://github.com/AgilionApps/quiet_assets.git'

# Github API
gem 'ruby-github'

# API
gem 'grape', :git => 'git://github.com/intridea/grape.git', :branch => 'frontier'

group :development, :test do
  gem 'capistrano', '2.9.0'
  gem 'chunky_png', "1.2.5"
  gem "memcache-client", "1.8.5"
  gem 'rspec-rails', '~> 2.8.1'
  gem 'factory_girl_rails'
  gem 'thin'
  gem "simplecov", :require => false # 没用了,可以去掉
  gem "rspec-cells"
  gem "capybara"
  gem "sunspot-rails-tester"
end

group :production do
  gem "unicorn"
  gem 'dalli', '1.1.1'
end

以上有几个 gem 确实是可以去掉的,其他的都是必要的。 我的看法是,Gem 多少和站的大小没有大大关系,Ruby China 现在用这些都是必要的。当然,可以去掉,但既然有现成的东西,就没必要重复开发了。

我今天来整理一下

去了几个 Gem

➜  ruby-china git:(master)time bundle exec rake environment
# 之前的数据:
bundle exec rake environment  5.69s user 1.28s system 92% cpu 7.547 total

# 之后:
bundle exec rake environment  5.01s user 0.99s system 99% cpu 6.026 total
需要 登录 后方可回复, 如果你还没有账号请 注册新账号