Ruby on Rails中Rack中介軟體的基礎學習教程_ruby專題

來源:互聯網
上載者:User

rack是ruby伺服器和rack應用程式之間的一個架構,rails,sinatra都是基於rack構建的,都屬於rack應用程式。

rack提供了一個標準的介面,用於與伺服器進行互動。標準的rack程式是一個可以響應call的對象,可以是對象、Proc、lambda甚至是method,它接收env參數(環境對象),返回一個數組,數組包括:

  • 狀態(status),http響應狀態代碼
  • 可以是hash,為http的header資訊
  • 擁有each方法的對象,each返回字串

rack通過中介軟體來進行擴充,即對原始的rack程式進行裝飾,在原有返回數組的基礎上進一步處理,並返回rack對象

簡單的rack程式

require 'rack'app = lambda{|env|[200,{},["hello from rack"]]}Rack::Handler::WEBrick.run app

使用中介軟體的rack程式:
require 'rack'

class Decorator def initialize(app)  @app = app end def call(env)  status, headers, body = @app.call(env)  new_body = "from middleware input <br/>"  body.each{|str| new_body << str}  headers['Content-Length'] = new_body.bytesize.to_s  [status, headers, [new_body]] endendapp = lambda{|env|[200,{},["hello from rack"]]}Rack::Handler::WEBrick.run Decorator.new(app)

上面使用中介軟體的方法在使用多個時容易混亂,rack有一個Builder類可以有效管理
使用如下
require 'rack'

require 'decorator'app = Rack::Builder.new{ use Rack::ContentLength use Decorator run lambda {|env| [200, {"Content-Type"=>"text/html"}, ["hello world"]]}}.to_appRack::Handler::WEBrick.run app

使用Rack::Builder的map方法,可以建立有路由的rack程式
require 'rack'

app = Rack::Builder.new { map '/hello' dorun lambda {|env| [200, {"Content-Type" => "text/html"}, ["hello"]] } endmap '/world' dorun lambda {|env| [200, {"Content-Type" => "text/html"}, ["world"]] }endmap '/' dorun lambda {|env| [200, {"Content-Type" => "text/html"}, ["all"]] } end}.to_appRack::Handler::WEBrick.run app, :Port => 3000

由於rails的全棧性,rack中介軟體很多,在一些高並發但業務簡單的網站或api使用時
回應時間過長,在這種情況下可以考慮使用rack或者sinatra。

啟動一個rack程式有兩種方式:

1.直接使用ruby運行.rb檔案,預設在8080啟動服務,無記錄檔
2.使用rackup,預設在9292 啟動服務,有記錄檔,rackup可使用 -o 指定ip, -p 指定連接埠號碼

require 'rack'app = lambda{|env| [200,{},["hello world"]] }Rack::Server.new.server.run appruby xxx.rb

#test.rurun lambda{|env| [ 200,{},["rackup start"] ]}rackup test.ru

rack會在啟動時預設載入一些中介軟體:

def logging_middleware    lambda { |server|     server.server.name =~ /CGI/ || server.options[:quiet] ? nil : [Rack::CommonLogger, $stderr]    }   end    m = Hash.new {|h,k| h[k] = []}    m["deployment"] = [     [Rack::ContentLength],     [Rack::Chunked],     logging_middleware,     [Rack::TempfileReaper]    ]    m["development"] = [     [Rack::ContentLength],     [Rack::Chunked],     logging_middleware,     [Rack::ShowExceptions],     [Rack::Lint],     [Rack::TempfileReaper]    ]    m   end

包括body長度錯誤提示訪問記錄等。

rack有一個Directory的中介軟體,可以為目錄檔案產生一個web服務。
使用很簡單一句話:

#test.rurun Rack::Directory.new "~/"rackup test.ru

這樣就會把home目錄下的所有檔案、檔案夾在瀏覽器中顯示

rails應用中使用rake middleware即可顯示所有的middleware(中介軟體)

** **rake middlewareuse Rack::Sendfileuse ActionDispatch::Staticuse Rack::Lockuse #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x007feef1563b90>use Rack::Runtimeuse Rack::MethodOverrideuse ActionDispatch::RequestIduse Rails::Rack::Loggeruse ActionDispatch::ShowExceptionsuse WebConsole::Middlewareuse ActionDispatch::DebugExceptionsuse ActionDispatch::RemoteIpuse ActionDispatch::Reloaderuse ActionDispatch::Callbacksuse ActiveRecord::Migration::CheckPendinguse ActiveRecord::ConnectionAdapters::ConnectionManagementuse ActiveRecord::QueryCacheuse ActionDispatch::Cookiesuse ActionDispatch::Session::CookieStoreuse ActionDispatch::Flashuse ActionDispatch::ParamsParseruse Rack::Headuse Rack::ConditionalGetuse Rack::ETagrun Fool::Application.routes

rails使用了rack定義的一些中介軟體,自訂了一些中介軟體,其中自訂的routes為rack程式,routes 把rails controller的action變為lambda並作為rack程式運行,在rails console裡輸入

2.2.1 :001 > QuestionsController.action(:new) => #<Proc:0x007fbe482ee0b0@/Users/killman/.rvm/gems/ruby-2.2.1/gems/actionpack-4.2.1/lib/action_controller/metal.rb:237 (lambda)>

在config/application.rb可添加、刪除、修改中介軟體

config.middleware.use(new_middleware, args)#:把新中介軟體添加到列表末尾;config.middleware.insert_before(existing_middleware, new_middleware, args)#:在 existing_middleware

 之前添加新中介軟體;

config.middleware.insert_after(existing_middleware, new_middleware, args)#:在 existing_middleware

 之後添加新中介軟體;

config.middleware.swap ActionDispatch::ShowExceptions, Lifo::ShowExceptions #替換中介軟體config.middleware.delete "Rack::Lock"#刪除中介軟體

中介軟體的作用:

  • Rack::Sendfile :設定伺服器上的 X-Sendfile 前序。通過 config.action_dispatch.x_sendfile_header選項設定。
  • ActionDispatch::Static :用來服務靜態資源檔案。如果選項 config.serve_static_assets為 false,則禁用這個中介軟體。
  • Rack::Lock :把 env["rack.multithread"]旗標設為 false,程式放入互斥鎖中。
  • ActiveSupport::Cache::Strategy::LocalCache::Middleware :在記憶體中儲存緩衝,非安全執行緒。
  • Rack::Runtime :設定 X-Runtime 前序,即執行請求的時間長度,單位為秒。
  • Rack::MethodOverride :如果指定了 params[:_method]參數,會覆蓋所用的要求方法。這個中介軟體實現了 PUT 和 DELETE 方法。
  • ActionDispatch::RequestId :在響應中設定一個唯一的 X-Request-Id 前序,並啟用 ActionDispatch::Request#uuid方法。
  • Rails::Rack::Logger :請求開始時提醒日誌,請求完成後寫入日誌。
  • ActionDispatch::ShowExceptions :補救程式拋出的所有異常,調用處理異常的程式,使用特定的格式顯示給使用者。
  • ActionDispatch::DebugExceptions :如果在本地開發,把異常寫入日誌,並顯示一個調試頁面。
  • ActionDispatch::RemoteIp :檢查欺騙攻擊的 IP。
  • ActionDispatch::Reloader :提供“準備”和“清理”回調,協助開發環境中的代碼重新載入功能。
  • ActionDispatch::Callbacks :在處理請求之前調用“準備”回調。
  • ActiveRecord::Migration::CheckPending :檢查是否有待啟動並執行遷移,如果有就拋出 ActiveRecord::PendingMigrationError異常。
  • ActiveRecord::ConnectionAdapters::ConnectionManagement :請求處理完成後,清理活躍的串連,除非在發起請求的環境中把 rack.test設為 true。
  • ActiveRecord::QueryCache :啟用 Active Record 查詢快取。
  • ActionDispatch::Cookies :佈建要求的 cookies。
  • ActionDispatch::Session::CookieStore :負責把會話儲存在 cookies 中。
  • ActionDispatch::Flash :設定 Flash 訊息的鍵。只有設定了 config.action_controller.session_store選項時才可用。
  • ActionDispatch::ParamsParser :把請求中的參數出入 params。
  • ActionDispatch::Head :把 HEAD 請求轉換成 GET 請求,並處理。
  • Rack::ConditionalGet :添加對“條件 GET”的支援,如果頁面未修改,就不響應。
  • Rack::ETag :為所有字串類型的主體添加 ETags 前序。ETags 用來驗證緩衝。
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.