Rack:Ruby Web服务器的瑞士军刀
Rack是什么?
Rack为使用Ruby开发Web应用程序提供了一个最小化、模块化且可适应的接口。它作为Web服务器和Web应用程序之间的标准接口,允许开发者无缝地使用不同的Web服务器和框架。
Rack应用
要使用Rack运行应用服务,你可以使用rackup命令,这是一个启动Web服务的强大工具。以下是如何实现一个简单的Web服务:
class Hello
def call(env)
[200, {"Content-Type" => "text/html"}, ["你好!"]]
end
end
将这段代码保存在一个文件中,比如config.ru,然后你可以使用rackup启动服务器。
Rack应用结构
以下是组件如何相互作用的可视化表示:
状态图
方向 TB
config.ru --> Rackup
Rackup --> Rack
Rackup --> Webrick
Rackup --> Puma
Rack --> Rails
Rack --> Sinatra
Rack --> Hanami
数据流
Rack应用程序中的数据流很简单:
状态图
方向 LR
[*] --> 请求
请求 --> Rackup
状态 Rackup {
方向 LR
Webrick --> Rack
Rack --> 应用
}
调用序列
Rack应用程序中请求处理的顺序:
序列图
盒子 green HTTP服务器
参与者 WH 作为 WEBrick::HTTPServer
结束
参与者 RHW 作为 Rackup::Handler::WEBrick
盒子 rgb(33,66,99) Rack中间件
参与者 RC 作为 Rack::ContentLength
参与者 RCL 作为 Rack::CommonLogger
参与者 RL 作为 Rack::Lint
结束
盒子 Blue应用
参与者 Hello
结束
WH->>WH: 运行(socket)
WH->>WH: 服务(请求, 响应)
WH->>RHW: 服务(请求, 响应)
RHW->>RC: 调用(env)
RC->>RCL: 调用(env)
RCL->>RL: 调用(env)
RL->>Hello: 调用(env)
Hello->>RL: [状态, 头部, 正文]
RL->>RCL: [状态, 头部, 正文]
RCL->>RC: [状态, 头部, 正文]
RC->>RHW: [状态, 头部, 正文]
RHW->>WH: [状态, 头部, 正文]
启动
启动过程涉及多个步骤,从Rackup::Server.start开始,到使用中间件构建应用程序堆栈。
运行应用
使用Rack::Builder#run方法来运行应用程序:
Rack::Builder#run(app=#<Hello:0x000000011e0d49d0>, block=nil)
应用俄罗斯套娃
Rack应用程序可以与中间件嵌套,创建一个“俄罗斯套娃”结构:
def build_app(app)
middleware[options[:environment]].reverse_each do |middleware|
klass, *args = middleware
app = klass.new(app, *args)
end
app
end
中间件
Rack中的中间件可以被看作是一系列层次:
状态图-v2
状态 ContentLength {
状态 CommonLogger {
状态 Lint {
Hello
}
}
}
默认中间件
Rack附带了一系列默认中间件,可以在不同环境中使用:
def default_middleware_by_environment
m = Hash.new {|h, k| h[k] = []}
m["deployment"] = [
[Rack::ContentLength],
logging_middleware,
[Rack::TempfileReaper]
]
m["development"] = [
[Rack::ContentLength],
logging_middleware,
[Rack::ShowExceptions],
[Rack::Lint],
[Rack::TempfileReaper]
]
m
end
服务器
服务器可以使用Rackup::Handler进行配置和启动:
def server
@_server ||= Handler.get(options[:server]) || Handler.default
end
WEBrick类用于处理服务器端操作:
模块 Rackup
模块 Handler
类 WEBrick < ::WEBrick::HTTPServlet::AbstractServlet
def self.run(app, **选项)
...
@server = ::WEBrick::HTTPServer.new(选项)
@server.mount "/", Rackup::Handler::WEBrick, app
如果给定块 yield @server
@server.start
end
end
end
end
结论
Rack以其简单灵活的设计,允许开发者轻松地在Ruby中构建Web应用程序。无论你是使用Rails、Sinatra还是任何其他框架,Rack都提供了一个一致的接口来处理请求和响应。链式中间件的能力以及设置Web服务器的简单性,使Rack成为Ruby Web开发者工具箱中不可或缺的工具。