webサーバー、アプリケーションサーバー、Rackといった仕様や概念と、WEBrick、Unicorn、Pumaといった実装の関係が頭の中で結びつきません

投稿者: Anonymous 前置き (やや混乱しているので質問がわかりづらいかもしれません) 大昔PerlでCGIによるWebアプリを作ったときに、ApatchでPerlで書いたプログラムを呼び出していた記憶があります。 Rails Railsですが、Webサーバーとアプリケーションサーバーが分かれている印象です。 CGI 上記CGIのやり方ではWebサーバーは存在しますが、アプリケーションサーバーは存在しないと認識しています。 Webサーバーとアプリケーションサーバーで混乱 Railsですと Webサーバー 例えばRack (←回答よりこれは勘違い) アプリケーションサーバー 例えばUnicorn、Puma といったように、ソフトウェアとしてWebサーバーとアプリケーションサーバーが分かれていると認識しています。 Webサーバーとアプリケーションサーバーを同時に満たすものがある? WEBrickですが、Webサーバーとアプリケーションサーバーどちらの役目もしているような気がしていて混乱しています。(dev環境だとアプリケーションサーバーなど意識せずWEBrickだけで動いている気がする) Rackは各種アプリケーションサーバーの仕様の乱立を避けるために生まれた? 各種アプリケーションサーバーがどんどん出てきたときに、デプロイの作業がバラバラとなり、それを救うためにRackが生まれたというような内容を見かけました。 となると、アプリケーションサーバーの違いを吸収するためにWebサーバー(Rack)を用意するということでしょうか? (そもそもWebサーバーはHTTPなどのリクエストを受け取るものでアプリケーションサーバーの違いを吸収するものではないような…) 解決 webサーバー、アプリケーションサーバー、Rack、Unicorn、Puma、Railsと言った用語や概念の理解がこんがらかっているように見えたので、このあたりをきれいに説明している記事を探してみました。 おそらく以下の記事が回答にぴったりだと思います。 http://www.justinweiss.com/articles/a-web-server-vs-an-app-server/ この記事の中からnakanishiさんの理解に役立ちそうなセクションをピックアップして、ざっくり翻訳してみました。 webサーバーとは webサーバーはユーザー送られてきた自サイトへのリクエストを受け取り、なんらかの処理を加えるプログラムです。そして、場合によってはあなたのRailsアプリケーションにリクエストを投げます。NginxとApacheは最も有名なwebサーバーです。 CSSやJavaScript、画像など、頻繁に変化しないファイルへのリクエストであれば、Railsアプリケーションはそのリクエストを処理する必要がないかもしれません。webサーバーはRailsアプリケーションに処理を移譲することなく、そのリクエストを自分で処理できます。また、そうした方が通常は速く完了します。 webサーバーはSSLリクエストや静的なファイルやアセット、圧縮されたリクエスト等を処理したり、その他大半のwebサイトが必要としそうな数多くの処理をこなしたりすることができます。そしてもし、あなたのRailsアプリケーションがリクエストを処理しなければならない場合は、webサーバーはリクエストをアプリケーションサーバーにパスします。 アプリケーションサーバーとは アプリケーションサーバーはあなたのRailsアプリケーションを動かしているものです。アプリケーションサーバーはあなたのコードを読み込み、アプリケーションをメモリに保持します。アプリケーションサーバーはwebサーバーからリクエストを受け取ると、Railsアプリケーションにそのことを知らせます。アプリケーションがリクエストを処理すると、アプリケーションサーバーはそのレスポンスをwebサーバーに返します。(そのレスポンスは最終的にユーザーへ届きます。) 大半のアプリケーションサーバーはwebサーバーを使わずに単体で実行できます。これはあなたがdevelopmentモードでやっていることです!しかしproduction環境ではwebサーバーを手前に置くことが多いはずです。webサーバーは複数のアプリケーションを一度に処理したり、アセットを素早くレンダリングしたり、リクエストごと発生する多くの処理をさばいたりしてくれます。 Rails用のアプリケーションサーバーは山ほどあります。たとえば、Mongrel(ただし最近はほとんど使われていない)、Unicorn、Thin、Rainbows、Pumaなどです。それぞれに異なる長所があり、異なる設計思想を持っています。とはいえ、みんなやっていることは一緒です。つまり、どのアプリケーションサーバーもあなたのRailsアプリケーションを動かし、リクエストを処理し続けています。 Rackとは Rackは魔法です。Rackを使えばどのアプリケーションサーバーであってもあなたのRailsアプリケーションを動かすことができます。(Railsに限らず、SinatraやPadrinoであっても同じです) RackはRailsのようなRuby製のwebフレームワークとアプリケーションサーバーの両方が話せる共通言語のようなものだと考えてください。両者が共通言語を理解できるので、RailsはUnicornと話せますし、UnicronはRailsと話せます。しかも、RailsもUnicornも相手のことを知っておく必要は全くありません。 webサーバーとアプリケーションサーバーはどういう関係なのか? それでは、この話を全部まとめるとどうなるでしょうか? まず、webリクエストはwebサーバーにぶつかります。そのリクエストがRailsで処理できるものであれば、webサーバーはリクエストに簡単な処理を加えてアプリケーションサーバーに渡します。アプリケーションサーバーはRackを使ってRailsアプリケーションに話しかけます。Railsアプリケーションがリクエストの処理を終えると、Railsはレスポンスをアプリケーションサーバーに返します。そして、webサーバーはあなたのアプリケーションを使っているユーザーにレスポンスを返します。 もっと具体的に言えば、NginxはリクエストをUnicornに渡します。UnicornはリクエストをRackに渡します。RackはリクエストをRailsのrouterに渡します。routerはリクエストを適切なcontrollerに渡します。そしてレスポンスが逆の順番で返されます。 (全文訳はこちら) この内容をじっくり読んで理解すれば、疑問点の大半は解消されると思うのですがいかがでしょうか? (ちなみに僕も理解があやふやなところがあったので、翻訳してみてスッキリしました) 回答者: Anonymous

Rack app error: ActionController::UnknownHttpMethodをrescueする方法

投稿者: Anonymous Rack app error: ActionController::UnknownHttpMethodをrescueするにはどうすればいいのでしょうか? 指定されたHTTP method以外でアクセスするとこのエラーが出ます。その際に各種のバージョンなどがクライアント側に出力されるのでこれをrescueして、単純なエラーメッセージだけに変更したいと考えています。 midlewareから出されているエラーのようで app/controllers/application_controller.rb に rescue_from ActionController::UnknownHttpMethod, with: :unknown_method としても反応しません。 どうすればいいのでしょうか? エラーログ 2016-01-06 22:22:28 +0800: Rack app error: #<ActionController::UnknownHttpMethod: AAA, accepted HTTP methods are OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK, VERSION-CONTROL, REPORT, CHECKOUT, CHECKIN, UNCHECKOUT, MKWORKSPACE, UPDATE, LABEL, MERGE, BASELINE-CONTROL,…(Continue Reading)