rack puma rails

本文介绍了Rack作为Ruby web服务器(如Puma)和应用程序(如Rails)之间的桥梁,阐述了Rack协议及其中间件的作用,通过示例展示了Rack协议的实现,并简要提及了Puma的高性能特点。同时,文章还探讨了Rails如何利用Rack进行web服务器集成。
摘要由CSDN通过智能技术生成

rack puma rails

背景

2021 年 五一, 突然对 web server 与 rails 之间的关系,
好奇我们的程序是如何接收到请求, 找到我们的业务程序代码, 并返回对应的结果的;

于是, 便写下这篇文章;

说明

文章所涉及到的代码已上传 GitHub rack-puma-rails

文章涉及到的程序版本

文中提到的 web server 是指的服务器软件, 而非计算机.

简述

rack 是一个 ruby web server(例如: puma, unicorn) 和 应用程序(例如: rails)之间的桥梁;

rack

在这里插入图片描述

Rack 是什么

Rack 提供了一个最小化的, 模块化, 可适配化的接口给 Ruby 的 web 应用;

通过简单的方式封装 HTTP 请求和响应, Rack 统一并提取了 API 给 web server,
web 框架以及在两者之间的中间件(middleware).

为什么要使用 Rack

在没有 Rack 之前, web server 的实现各有千秋, web 应用对接不同的 web server,
需要一个 server 对应一套逻辑; 缺乏统一的标准;
在这里插入图片描述

这些适配不同 server 的工作, 没有太大意义, 人们期望有一个统一的规范, 能够让 web server 和
web 应用可以随意组合, 且只需要简单的配置.

Rack 的出现解决了 web server 和 web 应用之间配置的问题;

复杂的程序需要分层

通过 Rack, 不同的 web server 和 不同的应用框架可以非常简单地集成;
在这里插入图片描述

接下来, 我们就来详细看一下 Rack 的协议和中间件.

Rack 协议与中间件

Rack 作为 web server 与应用框架之间的桥梁.
最为重要的就是定义一套清晰的协议(protocol).

Rack 协议

我们也可以使用 Rack 的中间件

我们先来看一下rack 协议

  • 对于 web server: 只需要在 Rack::Handler 的模块中创建一个实现了 run 方法的类就可以了
  • 对于 web 框架: 需要有一个 Ruby 的对象(注意不是类). 这个对象需要实现call方法.
    • call 方法只有一个参数 env 环境
    • 返回一个数组, 数组必须返回是三个值. 分别是 HTTP 的 status , headers, 和 body

Rack 的协议脱胎于 python 的pep-0333 Python Web Server Gateway Interface

我们可以看一个小案例, 来看一下具体的情况;

要确保已安装了 rackpuma

我们在 config.ru 简单写一个处理请求的 rack 对象

# config.ru rack的默认配置文件
# rack对象, 接收一个env参数, 且要返回一个数组
APP = ->(env) {
    [200, {
   }, [env.inspect]] }
run ->(env) {
    APP.call(env) }

执行rackup

rackup

在这里插入图片描述

我们可以看到 rackup执行之后, puma 也随之启动了!

我们可以在浏览器中看一下效果 http://localhost:9292/hello_world

在浏览器中可以看到打印的env对象

接下来, 我们看看rackup到底做了什么, 能够让 puma 运行起来;

$ which rackup
/d/env/ruby/Ruby26-x64/bin/rackup

我们来看一下对应的代码

# gem自动生成的文件, 方便使用, 省去了一些代码
version = ">= 0.a"
load Gem.activate_bin_path('rack', 'rackup', version)

我们在pry执行一下看看

[1] pry(main)> require 'rubygems'
=> false
[2] pry(main)> version = ">= 0.a"
=> ">= 0.a"
[3] pry(main)> Gem.activate_bin_path('rack', 'rackup', version)
=> "D:/env/ruby/Ruby26-x64/lib/ruby/gems/2.6.0/gems/rack-2.2.3/bin/rackup"

我们找到对应的bin/rackup的代码

require "rack"
Rack::Server.start

我们在 pry 中看一下具体执行的位置

[1] pry(main)> require "rack"
=> true
[2] pry(main)> show-source Rack::Server.start

From: D:/env/ruby/Ruby26-x64/lib/ruby/gems/2.6.0/gems/rack-2.2.3/lib/rack/server.rb @ line 167:
Owner: #<Class:Rack::Server>
Visibility: public
Number of lines: 3

def self.start(options = nil)
  new(options).start
end

我们再看一下代码lib/rack/server.rb

def self.start
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值