20210730_出張!Railsウォッチ in 銀座Rails#35
by
Masato Mori
×
Copy
Open
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Slide 1
Slide 1 text
出張!Railsウォッチ in 銀座Rails#35 森 雅智 / @morimorihoge 2021/07/30 1 特集:~何かと便利なActiveSupport::Instrumentation~
Slide 2
Slide 2 text
About Me ● 森 雅智: @morimorihoge ● BPS株式会社でRailsの受託開発チームをやってたり、週1大学非常勤で Web開発を教えてたりします ● Ruby/Rails歴は11年くらい。Web開発は17年くらい ● 銀座Ralis #10でActiveRecordでVIEWを使おうという話をしました ● 銀座Rails #27でアプリケーションコンフィグの話をしました About BPS & TechRacho ● Web受託開発や電子書籍製品開発をやっている会社です ● TechRachoという自社技術Blogを運営しています ○ 5年ほど前から平日毎日更新してます ○ https://techracho.bpsinc.jp/ ● お仕事相談、転職相談、TechRachoへのご意見など気軽にどうぞ ○ https://www.bpsinc.jp/ 2
Slide 3
Slide 3 text
Railsウォッチとは? 技術ブログTechRachoで毎週連載しているRails / Ruby界隈を中 心とした雑多な情報を提供する技術雑談マガジン 3
Slide 4
Slide 4 text
これまでの出張Railsウォッチのピックアップテーマ ● 銀座Rails#12: 複数DB対応 ● 銀座Rails#13: ActionText、Trix ● 銀座Rails#14: ActionMailbox ● 銀座Rails#15: production、development、staging環境について ● 銀座Rails#16: 機能開発の設計レビューについて ● 銀座Rails#17: リソース管理スコープについて ● 銀座Rails#19: 開発チームの冗長化について ● 銀座Rails#20: Excelと仲良くしよう ● 銀座Rails#21: 標準仕様を読むためのABNF ● 銀座Rails#22: CLIプログラムにOptionParserを使う ● 銀座Rails#23: ActiveRecordのSELECTベンチマーク ● 銀座Rails#24: 令和Devise事情 ● 銀座Rails#28: 2020年の銀座Railsを振り返る ● 銀座Rails#29: Serverless Railsを試す ● 銀座Rails#30: Railsインフラ環境Overview ● 銀座Rails#31: Railsプロジェクトあるある ● 銀座Rails#32: MimeMagic騒動を振り返る ● 銀座Rails#33: Rails 7.0で入る予定の新機能(暫定版) ● 銀座Rails#34: もっとDBコメントを書こう 4 各回資料に興味がある方はこちらからどうぞ:https://speakerdeck.com/morimorihoge
Slide 5
Slide 5 text
何かと便利なActiveSupport::Instrumentation 5
Slide 6
Slide 6 text
ActiveSupport::Instrumentation ● Rails標準のPubSub(publisher/subscriber)ライブラリ ● パフォーマンス計測やデバッグ中心に使われている ● 便利な割に思ったより有効に活用されていない気がするので紹介 6
Slide 7
Slide 7 text
PubSubとは? ● 基本の役割 ○ Publisher: Event配信する人 ○ Subscriber: Eventを受信したい人 ○ Event: やり取りしたい情報。メッセージと呼ぶこともある ● PublisherはいつでもEventを配信できる ○ 購読しているSubscriberはいないかもしれないし、複数いるかもしれないが気にしない ● SubscriberはいつでもEventを受信開始・解除できる ○ 流れてくるEventはないかもしれないが、気にしない 7 Redis、AWS SNS、Google Cloud Pub/Subなど色々な所で使われている設計モデル
Slide 8
Slide 8 text
トピック型PubSubシステム(AS::Instrumentation) ● トピック型ではPublisherがEventをどのchannelに流すかを決める ● Subscriberはchannelを指定してsubscribeし、流れてきたEventを受信する 8 ※コンテンツ型の場合はEventの仕分けをSubscriberが行う点が異なる
Slide 9
Slide 9 text
AS::Instrumentsの利用例 9 channel名 channel名 eventのpayload
Slide 10
Slide 10 text
ActiveSupport::Notifications::Event AS::Notifications.subscribeのブロック引数に渡されるオブジェクト 10 元々パフォーマンス計測に使われている機能のため、instrumentにかかった時間を #durationで高精度に取ることもできる
Slide 11
Slide 11 text
Regex指定によるchannel subscribe 11 ginza35で始まる全てのchannelを受信 正規表現でchannel subscribe
Slide 12
Slide 12 text
AS::Instrumentationの使い方まとめ ● AS::Notifications.subscribe(channel)で購読したいchannelを指定 し、ブロックにやらせたい処理を仕込んでおく ○ channelには正規表現も指定可能 ● AS::Notifications.instrument(channel, payload)でイベントを送 信する 12 これだけ!とてもシンプル 👍
Slide 13
Slide 13 text
ここから本編 Railsにはあちこちにinstrumentが仕込んである ● [Edge Guide] https://edgeguides.rubyonrails.org/active_support_instrumentation.html#rails-framework-hooks ● [日本語Guide] https://railsguides.jp/active_support_instrumentation.html 13 眺めてみるとRailsのログに出ているような情報が取れることがわかる ※実際にはAS::LogSubscriberを使ってEventをログ出力用に整形している。詳しくは Railsのソースコードを読もう
Slide 14
Slide 14 text
例:でかい処理の中で実行されているSQLだけ取り出す このサービスクラス、何やってるかよくわからんのでとりあえず実行されてるSQLだけで も眺めてみるか・・・ 14 ※sql.activerecord Eventのsqlはプレースホルダ化されているので、実際には:bindsも見ない とクエリ内に埋め込まれた値は分からないのに注意 unsubscribeすればそれ以後は受信しない
Slide 15
Slide 15 text
例:特定のメール送信時にSlack通知したい 15 ※同期実行されるので、フロントから#deliver_now送信している場合などにはパフォーマンス に影響が出る可能性あり slack-notifier gemについては略
Slide 16
Slide 16 text
Gemの例:Rack::Attack IPアドレスやAPIコール数制限などで良く使われるRack::AttackはInstrumentation対応 16 APIコール数制限に達したログを記録したい 、などのケースをカバーすることができる
Slide 17
Slide 17 text
自分でinstrumentを定義して使う ● 今すぐは使わないけど、後々このイベントは取得できるようにしたくなりそう ● デバッグの時だけ簡単に情報を拾えるようにしたいけど、普段はOFFにしておきたい ● Loggerに出すと他の大量のログと混じってしまうので、個別にイベントとして取得したい ● Datadog他のAPMツールで扱うアプリケーションイベントを定義・出力したい 17 それAS::Instrumentationでできるよ(ドヤァ ロジックコードの中にprintデバッグコードを入れると入れたり消したりが大変だが、 AS::Instrumentationならsubscriberを付け外しするだけで良い ※環境変数によってON/OFFするようなコードもsubscribeするところだけでOK
Slide 18
Slide 18 text
AS::Instrumentation使用上の注意点 ● channel名はRailsアプリケーション全体でglobalなので、名前の衝突に注意 ● instrumentメソッドの呼び出しはsubscriberの有無によらず発生するので、payload に渡すオブジェクト整形処理はパフォーマンスに悪影響を与える可能性がある ● subscriberブロックの呼び出しは同期処理なので、重い処理を書くのは危険 ○ 非同期系クラウド系Pub/Subサービスのつもりで使うと危険 ○ きちんとやるならsubscriberブロックで非同期Jobを投入するような工夫が必要 ● あくまで1プロセス内でのpubsubなので、リクエストを跨いだ処理には使えない ○ ActionCableでは複数WebSocketを跨いだpub/subにRedisのpubsub機能を使うように推奨されてい る 18
Slide 19
Slide 19 text
まとめ ● ActiveSupport::Instrumentationを使うとRails標準搭載の機能でPub/Subすることが できる ● あらかじめHookしておきたいような処理に#instrumentを仕込んでおくことで、必要 になったときに#subscribeして利用することができる ● どこで何回呼び出される分からない処理に対して予めHookを仕込んでおくような使 い方ができるので、コードのデバッグや障害調査に有用 19
Slide 20
Slide 20 text
次回以降もブラッシュアップしていきます 感想・リクエストなどあればTwitter #ginzarails @morimorihoge @hachi8833 までお声かけください 20