我是靠谱客的博主 雪白小蝴蝶,这篇文章主要介绍Ruby on rails 项目启动流程,现在分享给大家,希望可以做个参考。

众所周知,我们可以通过rails s 这个命令来启动一个rails 项目,但是这条命令都干了哪些事呢?抽时间研究了下,同时感谢tomwang1013的博客。当我们输入rails s 这个命令的时候,项目会加载项目bin/rails.rb 这个文件
#!/usr/bin/env ruby
APP_PATH = File.expand_path('../../config/application', __FILE__)
require_relative '../config/boot'
require 'rails/commands'

通过代码我们可以看到这个文件中定义了一个APP_PATH 即我们的项目文件:config/application.rb,并require了config/boot,boot文件主要是做了bundle的初始化。
然后,我们可以看到这个时候rails/commands(railties-3.2.3/lib/rails/commands.rb)文件被load进来,由于我们传入的command参数为s,也就是server,然后我们看看commands的这个文件的源码对应的部分:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
when 'server' # Change to the application's path if there is no config.ru file in current dir. # This allows us to run script/rails server from other directories, but still get # the main config.ru and properly set the tmp directory. Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exists?(File.expand_path("config.ru")) require 'rails/commands/server' Rails::Server.new.tap { |server| # We need to require application after the server sets environment, # otherwise the --environment option given to the server won't propagate. require APP_PATH Dir.chdir(Rails.application.root) server.start }

在server 这个方法中我们通过server.start这行代码可以看出最终调用了start这个方法,然后查看下start 这个方法。同时这里面也打印了我们熟悉的控制台信息

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def start url = "#{options[:SSLEnable] ? 'https' : 'http'}://#{options[:Host]}:#{options[:Port]}" puts "=> Booting #{ActiveSupport::Inflector.demodulize(server)}" puts "=> Rails #{Rails.version} application starting in #{Rails.env} on #{url}" puts "=> Call with -d to detach" unless options[:daemonize] trap(:INT) { exit } puts "=> Ctrl-C to shutdown server" unless options[:daemonize] #Create required tmp directories if not found %w(cache pids sessions sockets).each do |dir_to_make| FileUtils.mkdir_p(Rails.root.join('tmp', dir_to_make)) end puts 'server start ---' super ensure # The '-h' option calls exit before @options is set. # If we call 'options' with it unset, we get double help banners. puts 'Exiting' unless @options && options[:daemonize] end

这个start 这个方法最终会执行super 这个,super 会调用Rack::Server#start方法:代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
def start &blk if options[:warn] $-w = true end if includes = options[:include] $LOAD_PATH.unshift(*includes) end if library = options[:require] require library end if options[:debug] $DEBUG = true require 'pp' p options[:server] pp wrapped_app pp app end # Touch the wrapped app, so that the config.ru is loaded before # daemonization (i.e. before chdir, etc). wrapped_app daemonize_app if options[:daemonize] write_pid if options[:pid] trap(:INT) do if server.respond_to?(:shutdown) server.shutdown else exit end end server.run wrapped_app, options, &blk end

代码执行到server.run wrapped_app 这行代码。wrapped_app方法最终又会调用Rack::Server#app

复制代码
1
2
3
4
5
6
7
8
9
10
11
def app @app ||= begin if !::File.exist? options[:config] abort "configuration #{options[:config]} not found" end app, options = Rack::Builder.parse_file(self.options[:config], opt_parser) self.options.merge! options app end end

最终app 这个方法会加载项目config 目录下的environment.rb这个文件如:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Load the Rails application. require File.expand_path('../application', __FILE__) require 'whenever' module ProductConfig DYNAMIC_FIELDS = Hash.new end module RestConfig PRODUCT_SERVER = ENV["PHOTO_HOST"] || 'http://localhost:3001/' #CUSTOMER_SERVER = ENV["CUSTOMER_HOST"] || 'http://localhost:3001/' CUSTOMER_SERVER = ENV["CUSTOMER_HOST"] || 'http://localhost:3001/' OA_SERVER = 'http://localhost:3001/' #ELEPHANT_HOST = ENV["ELEPHANT_HOST"] || 'http://www.jiuyunda.net:90/' ELEPHANT_HOST = ENV["ELEPHANT_HOST"] || 'http://localhost:3001/' JXC_HOST = ENV["JXC_HOST"] || 'http://localhost:3001/' SETTLE_HOST = ENV["SETTLE_HOST"] || 'http://localhost:3001/' end # Initialize the Rails application. Rails.application.initialize!

Rails.application.initialize!这行代码我们可以看出
项目的初始化完成。这个时候我们代码就回到Rack::Server#start方法的最后一行 server.run wrapped_app, options, &blk 由于我们没有设定任何参数。通过代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def server @_server ||= Rack::Handler.get(options[:server]) || Rack::Handler.default(options) end def self.default(options = {}) # Guess. if ENV.include?("PHP_FCGI_CHILDREN") # We already speak FastCGI options.delete :File options.delete :Port Rack::Handler::FastCGI elsif ENV.include?("REQUEST_METHOD") Rack::Handler::CGI else begin Rack::Handler::Thin rescue LoadError Rack::Handler::WEBrick end end end

我们可以看到rack 为我们选定了默认的server.一般来说是WEBrick .然后WEBrick启动,打印如下信息

复制代码
1
2
3
4
5
6
INFO WEBrick 1.3.1 INFO ruby 1.9.3 INFO WEBrick::HTTPServer#start: pid=28371 port=3000

如果安装了其他application server的话打印的信息可能会不同如

复制代码
1
2
3
4
5
6
7
8
9
10
Booting Puma => Rails 4.2.4 application starting in development on http://localhost:3000 => Run `rails server -h` for more startup options => Ctrl-C to shutdown server "assets end:false" Puma starting in single mode... * Version 3.4.0 (ruby 2.3.0-p0), codename: Owl Bowl Brawl * Min threads: 0, max threads: 16 * Environment: development * Listening on tcp://localhost:3000

至此项目的启动已完成。

最后

以上就是雪白小蝴蝶最近收集整理的关于Ruby on rails 项目启动流程的全部内容,更多相关Ruby内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(79)

评论列表共有 0 条评论

立即
投稿
返回
顶部