众所周知,我们可以通过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的这个文件的源码对应的部分:

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
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

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

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

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

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
  • 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
  • 35
  • 36
  • 37
  • 38

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

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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

# 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!
  • 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

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

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

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

INFO  WEBrick 1.3.1
INFO ruby 1.9.3
INFO WEBrick::HTTPServer#start: pid=28371 port=3000
  • 1
  • 2
  • 3

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

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

至此项目的启动已完成。

Ruby on rails 项目启动流程的更多相关文章

  1. [Ting's笔记Day4]将Ruby on Rails项目部署到Heroku

    今天想笔记的是把自己写的Ruby on Rails项目部署(Deploy)到Heroku! Heroku是Salesforce公司旗下的云端服务商,支持多种程序语言像是Ruby,PHP,Python等 ...

  2. web项目启动流程探索

    在web项目的启动过程中,我们希望知道它的一般流程是什么,这样我们就可以在各个流程中加入相应的功能,或者对于我们排错也有帮助. 我们知道,当我们启动tomcat容器以后,容器首先初始化一些必要的组件, ...

  3. 用VirtualBox和vagrant在win7×64上搭建ruby on rails 开发环境

    下载准备 1.vagrant 官方  WINDOWS Universal (32 and 64-bit) http://www.vagrantup.com/downloads.html 2.Virtu ...

  4. 利用最新版的RubyMine2016.2开发Ruby On Rails 程序

    经过我的前两篇博文 ”Ruby On Rails环境搭建“ 和”Ruby On Rails 环境搭建MySQL数据库连接“ 我们已经具备了开发Ruby On Rails程序的一切要素,但是天天对着do ...

  5. Spring基础系列-容器启动流程(2)

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9503210.html 一.概述 这里是Springboot项目启动大概流程,区别于SSM ...

  6. [Ting's笔记Day5]在部署到Heroku之前,将Rails项目从SQLite设定为PostgreSQL

    前情提要: Paas(平台及服务)公司Heroku是个可以把我们写好的App部署到网际网络的好地方.而本篇是我从自己的上一篇文章:将Ruby on Rails项目部署到Heroku遇到的问题,当时困扰 ...

  7. vue启动流程

    继上一篇vue环境的搭建(在D盘新建文件夹vue_cli,把(我已经上传到了文件下)资料下tpls解压完后的所有文件都复制到D盘vue_cli下) 目录如图: 1.webstorm设置为了提高webS ...

  8. Spring MVC启动流程分析

    本文是Spring MVC系列博客的第一篇,后续会汇总成贴子. Spring MVC是Spring系列框架中使用频率最高的部分.不管是Spring Boot还是传统的Spring项目,只要是Web项目 ...

  9. [技术博客] 软工-Ruby on Rails前端工具链的配置以及对Web应用结构设计的一点思考

    一.相关工具链简介 HAML HAML是专门面向Ruby on Rails模版语法设计的一门标记语言,其结合RoR的views部分模版语法的特点,对原来的*.html.erb(嵌入Ruby代码的HTM ...

随机推荐

  1. [NOIP2017] 逛公园 【最短路】【强连通分量】

    题目分析: 首先考虑无数条的情况.出现这种情况一定是一条合法路径经过了$ 0 $环中的点.那么预先判出$ 0 $环中的点和其与$ 1 $和$ n $的距离.加起来若离最短路径不超过$ k $则输出$ ...

  2. POJ 2245 Addition Chains(算竞进阶习题)

    迭代加深dfs 每次控制序列的长度,依次加深搜索 有几个剪枝: 优化搜索顺序,从大往下枚举i, j这样能够让序列中的数尽快逼近n 对于不同i,j和可能是相等的,在枚举的时候用过的数肯定不会再被填上所以 ...

  3. HDU2204 Eddy's爱好

    题意:给你一个正整数N,确定在1到N之间有多少个可以表示成M^K(K>1)的数. 解析:一个数N 开K次根后得到M  则小于M的所有数的K次方一定小于N 因为任何一个合数都能分解为素数的乘积 所 ...

  4. C#解决方案生成工具

    实验环境  VS2017 C# .NET4.6 项目都是.net framework框架 目的: 用程序生成解决方案和项目. 思路:手动建一个方案和项目,分析其中的文件内容,做成模板后,由程序调用.最 ...

  5. 使用unittest单元测试框架对加法做单元测试

    import unittest from parameterized import parameterized def cacl(a, b): return a+b class MyCacl(unit ...

  6. LOJ#6282. 数列分块入门 6

    一个动态的插入过程,还需要带有查询操作. 我可以把区间先分块,然后每个块块用vector来维护它的插入和查询操作,但是如果我现在这个块里的vector太大了,我可能的操作会变的太大,所以这时候我需要把 ...

  7. Docker部署SonarQube

    依赖 CentOS 7.2+ docker 1.13+ docker-compose 1.20+ 将下面文件内容另存为docker-compose.yml文件,执行docker-compose up ...

  8. 洛谷P1731 生日蛋糕

    李煜东太神了啊啊啊啊啊! 生日蛋糕,著名搜索神题(还有虫食算). 当年的我30分.... 这哥们的程序0ms... 还有他的树网的核也巨TM神. 疯狂剪枝! DFS(int d, int s, int ...

  9. A1043. Is It a Binary Search Tree

    A Binary Search Tree (BST) is recursively defined as a binary tree which has the following propertie ...

  10. Windows 10 配置系统环境变量

    首先在桌面找到此电脑(或我的电脑)右击找到属性 点击进入 之后进入到系统详情窗口找到高级系统设置 点击进入 找到环境变量 点击进入 找到Path 点击进入 找到新建点击 将你要为那个应用设置环境的绝对 ...