【パーフェクト Ruby on Rails】を読む - その14

3-2-5 RailsとRackの関係

Railsアプリケーションはrackupで起動可能です

RailsはRackの仕様に則ったアプリケーションなので

$ bundle exec rackup

コマンド実行後、ブラウザのlocalhost:9292で起動できます。

rails newすると config.ru というファイルがあり、このファイルがあることがRackアプリケーションであるという証拠になります。

config.ruファイルに明記されていませんがどのようなRackミドルウェアを利用しているかを確認するには% bin/rails middlewareで確認できます。

私の環境では以下の通りでした。

% bin/rails middleware
use Webpacker::DevServerProxy
use Rack::MiniProfiler
use ActionDispatch::HostAuthorization
use Rack::Sendfile
use ActionDispatch::Static
use ActionDispatch::Executor
use ActiveSupport::Cache::Strategy::LocalCache::Middleware
use Rack::Runtime
use Rack::MethodOverride
use ActionDispatch::RequestId
use ActionDispatch::RemoteIp
use Sprockets::Rails::QuietAssets
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use WebConsole::Middleware
use ActionDispatch::DebugExceptions
use ActionDispatch::ActionableExceptions
use ActionDispatch::Reloader
use ActionDispatch::Callbacks
use ActiveRecord::Migration::CheckPending
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
use ActionDispatch::ContentSecurityPolicy::Middleware
use ActionDispatch::PermissionsPolicy::Middleware
use Rack::Head
use Rack::ConditionalGet
use Rack::ETag
use Rack::TempfileReaper
run AppName::Application.routes

多い…。

ミドルウェア内の記述で破壊的メソッドのgsub!が出てきたので復習しました

p "もとみち".gsub!("もと", "") #=> "肉みち"  
!は破壊的メソッドで、元あった"もと"を消し去り、""として生まれ変わります。

今回、本書で書かれていたパターンは正規表現を置き換え元にしていたので同様のコードを書き、紐解いてみました。↓

p "hoge".gsub!(/hoge/i,"肉おいしい")#=>"肉おいしい"
# /i の部分で含まれている大文字小文字関係なく変換する
p "hoge".gsub!(/Hoge/i,"肉おいしい")#=>"肉おいしい"
p "hoge".gsub!(/hoGe/i,"肉おいしい")#=>"肉おいしい"

↓paizaで検証しました。

正規表現をちゃんと言葉にできなかったので調べました

正規表現」という単語が出てきたら「曖昧な感じで指定できるんだな~」という事です。正規なのに曖昧って面白いですね。🤷‍♀️

ひとこと

正規表現/xyz/i/iって何だろう?となって、それがフラグだと知れたのが楽しかったです。うん感動した!😈

参照

本書の中にあった'gsub!'メソッド
正規表現
正規表現リファレンス

【パーフェクト Ruby on Rails】を読む - その13

Rackミドルウェアを学習している最中にinitializeメソッドを定義していたのでinitializeメソッドについて再度復習しました。

initializeとは

newのデフォルト値として設定できる(Ruby超入門p200~)

RailsのModelではActiveRecordを継承しているため、initializeメソッドを指定しなくても、例えばUser.newに引数を持たせてオブジェクトを作ることができます。

Rackミドルウェア

Rackにはアプリケーションサーバ(pumaとか)とアプリケーション(何かしら)の間に処理を追加するミドルウェアという機能が備わっています。
Rackミドルウェアというと、本書の場合で言えばアプリケーションであるRackとアプリケーションサーバであるpumaの間に処理を追加する機能です。
以下のようにuseメソッドで機能を追加できます。Runtimeを追加機能として持たせている記述です。

repuire "rack"
require_relative "app"

use Rack::Runtime run App.new

Rackミドルウェアを作るとき

Rack(インターフェース)はRubyで作られているから(RailsのようにActiveRecordは継承していないので)initializeを書いています。

Rackのアプリを起動する際はrackupコマンドで起動します。

Rackミドルウェアとは関係なく単にミドルウェアとは何なのかと疑問に感じたので学習しました。

  • ミドルウェア
    • OSさんとアプリケーションさんの間に入って、いろいろな雑用をしてくれるやつ

      です。

ひとこと

点と点が線になり、また新たな点との出会いを繰り返しています。勉強が楽しいです。🐶

参照

ミドルウェア

【パーフェクト Ruby on Rails】を読む - その12

3-2 Rack

Rackは、RubyでWebアプリケーションを開発するための、最小限でモジュール化された適応性の高いインターフェースを提供します。HTTPのリクエストとレスポンスを可能な限りシンプルな方法でラップすることで、ウェブサーバー、ウェブフレームワーク、そしてその間にあるソフトウェア(いわゆるミドルウェア)のAPIを単一のメソッドコールに統一して抽出します。

その詳細はRack仕様に記載されており、すべてのRackアプリケーションはこれに準拠する必要があります。

元々はPythonWSGI(Web Server Gateway Interface)という企画を元に提案されたものです。🥃
RackはwebサーバーとRubyで作られたフレームワークアプリケーションをつなぐ インターフェイス)です。 (Rubyで作られた、という点が大事です。Railsだけではありません)

参照のgithubの意図からすると、
例えば「PHPでもRackと呼ぶのか?🤔」という疑問に対しては「NO🙅‍♀️」と言えるでしょう。🤷‍♀️🤷‍♀️🤷‍♀️🤷‍♀️

アプリケーションサーバ

Railsを動かすためのサーバーです。webサーバーとのリクエストやレスポンスの処理が出来ます。
Railsのデフォルトのアプリケーションサーバーーは"puma" rails new したらGemfileに書いてある 他にも"webrick"などがある。但しpumaより遅い。

Rackの規約

  • callメソッドを定義する
  • callメソッドは慣例的にenvあるいはenvironmentと命名する引数を一つ受け取る
  • callメソッドは次の値を配列型で戻り値として返す必要がある
  • HTTPのステータスコードを表す数値オブジェクト
  • HTTPヘッダーを表すハッシュオブジェクト
  • レスポンスボディとなる文字列を含んだ配列風オブジェクト

Rackに対する現時点での見解

pumaとか他にもあるアプリケーションサーバrailsなどのフレームワークをつなぐインターフェースであり、もし今後、pumaより早いアプリケーションサーバが登場したとして、それをrailsにも使えるようにしてくれる、インターフェースがRackなのかなと思う。 Rackがあるおかげで相性が悪いから使えないとか発生しない。

学習した上で残る疑問点

自作のRackを作らなければならない状況がわからないです。

🤷‍♀️

ひとこと

現段階では一言で言えません🙇‍♂️

参照

Rack github
アプリケーションサーバー
Rackでwebフレームワークを自作する
【Ruby on Rails】アプリケーションサーバ「Puma」について

【図解入門 TCP/IP】を読む - その8

アプリケーション層で動作する機器

  • 次世代ファイヤーウォール
    ファイアウォールの進化版です。色々なセキュリティ機能を詰め込み、統合化を図っています。IPアドレスやポート番号だけでなく、いろいろな情報をアプリケーションレベルで解析することによって、トラディショナルファイアウォールより高次元のセキュリティ、高次元の運用管理性を実現しています。

  • WAF(ワフ)
    Web Application Fireの略。
    WAFはクライアントとサーバー間でやりとりされる情報のふるまいをアプリケーションレベルで一つ一つ検査し、必要に応じてブロックします。

  • 負荷分散装置(L7スイッチ)

負荷分散方式という決まり事に基づき、背後にいる複数のサーバーに振り分けることによって、システム全体で処理できるトラフィック量の拡張を図ります。また、ヘルスチェックと呼ばれる、定期的なサービス監視を行うことによって、障害の発生したサーバーを負荷分散対象から切り離し、サービスのサービスの可用性向上を図ります。

負荷分散対象から切り離すイメージ…?

1 2 3 4 5
🪨 🪨 🪨 🪨 🪨
🙋‍ 🙋‍ 🙋‍ 🙋‍ 🧎 <無理

1 2 3 4 5
🪨 🪨 🪨 🪨 🚧 <切り離そう
🙋‍ 🙋‍ 🙋‍ 🙋‍ 🚧 <ここは使わないで


まとめ

ここまで物理層からアプリケーション層までの機器を数珠つなぎに繋いでいけます。

参考

本書のみ

【パーフェクト Ruby on Rails】を読む - その11

第3章押さえておきたいRailsの基本機能

テストの種類と実行方法

ソフトウェアの開発において、テストを行うことで品質を一定の水準に保つことは必要不可欠です。プログラムのテストを記述する事でトータルコストを少なくするため、Rails標準のテストフレームワークのminitestを学びます。


bin/rails testでテストを実行することができます。

testディレクトリ内のファイルやディレクトリについて

ディレクト 概要
application_system_test_case.rb システムの基底クラス
channels Action Cableに対するテストディレクト
controllers コントローラーに対する機能テストディレクト
fixtures テストデータ(fixture)を管理するディレクト
helpers ヘルパークラスに対するテストディレクト
integration 複数のコントローラー間でのテストに関するテストディレクト
jobs Active Jobに対するテストディレクト
mailers Action Mailer に対するテストディレクト
models モデルに対するテストディレクト
system システムテストディレクト
test_helper.rb ユニットテストで読み込むテスト用ヘルパークラス

Active Jobというワードが初めて聞いたので少し掘り下げる(ざっくりと) - Actiive Jobという非同期通信用のフレームワークがある - sidekiq(gem)です。 - Redisはオープンソースの永続化可能なインメモリデータベース(In-memory database)で、BSDライセンスで公開されています。 特徴はインメモリ型データ構造ストアであること、そしてデータの永続化ができることといえるでしょう。 メモリ上で動作するキーバリューストア型のデータベースです。

  • スタックとキュー(例)
    • スタック…最後に積み上げた本を最初に取り出す
    • キュー…最初に並んだ人を先にサービスする
  • 大量のジョブはRailsとSidekiqを使うとよし DelayedJob(gem)とResque(gem)というのもある

ひとこと

今日は現時点で使った事がなかったActive Jobについての議論が中心でした。 🤦‍♀️

参照

Sidekiqについて
非同期処理や定期実行を行う(Jobスケジューリング)

【図解入門 TCP/IP】を読む - その7

ネットワーク層で動作する機器

ネットワーク層は、ネットワークとネットワークをつなぐ階層です。 ネットワーク層で動作する機器は、IPパケットのヘッダーに含まれる「IPアドレス」の情報をもとにパケット転送を行います。IPアドレスは、ネットワーク層における住所、つまり識別子です。

ルーター

端末から受け取ったIPパケットのIPアドレスを見て自分のネットワークを超えた所にいる端末へ届ける役割を担っています。また、そのIPパケットをえっさほいさとバケツリレーして目的地に届けます。

やってる動きはデータリンク層と同じだと感じられました!

気になって調べた海底ケーブル

やばすぎわろタンバリン
海底ケーブルgif

L3スイッチ

ざっくり言うとルーターにL2スイッチを足し合わせたような機器です。ポートをたくさん持っているので、たくさんの端末を接続できますし、IPパケットをルーティングすることもできます。L3スイッチはMACアドレステーブルとルーティングテーブルを組み合わせた情報を、FPGAやASIC書き込み、その情報をもとにスイッチングしたり、ルーティングしたりします。 FPGAASICを使用するため、高速なパケット転送処理が可能ですが、ルーターと同じような多彩な機能を備えているわけではありません。(ハイエンドのL3スイッチはルーターと同じ機能を持っていたりします)

トランスポート層で動作する機器

トランスポート層は、アプリケーションを識別し、その要件に応じた通信制御を行う階層です。

ファイアウォール🔥🚒 

ネットワークの安全を守る為に使用する機器です。
ファイアウォールは端末間でやり取りされるパケットのIPアドレスやポート番号を見て、通信を許可したり、ブロックしたりします。
この通信制御機能のことをステートフルインスペクションといいます。


現段階での見解🧐

層によって役割があってやってること(送信端末→中間機器→受信端末)の流れが一緒、名前が違うので混乱している
ただ、IPアドレスを辿れば特定できるのはイメージ出来た👮‍♂️

まとめ

ネットワーク層はその名の通り、ネットワークとネットワークを繋いでいて、ルーターによって渡しています。
トランスポート層は、通信制御を行うセキュリティ面の階層で、ファイアウォールで安全を守っています。

私たちなりの例え
ネットワーク層駅伝ルーター中継地点、そこで襷(たすき)をバトンタッチして送る。走っているのがパケット🏃‍♂️
トランスポート層は、警察👮‍♂️、ファイアウォール検問🚓

参照

IPアドレス
https://ja.wikipedia.org/wiki/IP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9
ASIC
https://ja.wikipedia.org/wiki/ASIC
FPGA
https://ja.wikipedia.org/wiki/FPGA

【図解入門 TCP/IP】を読む - その6

1.3.2 データリンク層で動作する機器

データリンク層は、物理層の信頼性を確保し、同じネットワークにいる端末と接続できるようにする階層です。 データリンク層で動作する機器は、フレームのヘッダーに含まれるMACアドレスの情報をもとにフレーム転送を行います。MACアドレスデータリンク層における住所、つまり識別子です。

ブリッジ

ポートとポートと間ののような役割です。端末から受け取ったMACアドレスMACアドレステーブルという表で管理し、転送処理を行います。この転送処理のことをブリッジングといいます。※ ブリッジは、最近はL2スイッチに置き換えられ、単体機器として見ることはありません。

L2スイッチ

たくさんポートを持ってるブリッジです。
端末から受け取ったフレームのMACアドレスをブリッジ内のMACアドレステーブルで管理し転送処理を行います。

私たちなりに例えると

ブリッジは配送会社で言えば、倉庫(MACアドレステーブル)です。送信端末から荷物(MACアドレス)をトラック1号車1番ポート(1番ポート)で倉庫まで行き、倉庫から転送しトラック2号車(2番ポート)で受信端末まで届けます。
   💻    →  🚛   →   🏬   →   🚛   →   🖥
MACアドレス1       アドレスの転送      MACアドレス2


ひとこと

運送の例えがハマりすぎて運送は通信業界なのかもしれない(迷走)

参照

MACアドレス
https://www.cman.jp/network/term/mac/