Slide 1

Slide 1 text

Railsメジャーバージョンアップを 安全にカナリアリリースする

Slide 2

Slide 2 text

⾃⼰紹介 2 松⾕ 勇史朗 株式会社スタメン CTO 愛知県出⾝ 2018年: 銀座Rails#1に登壇

Slide 3

Slide 3 text

3 事業紹介 Our Business 2つのエンゲージメント事業 この2つのRailsアプリケーションの メジャーバージョンアップを実施しました。 SaaSモデルの "社内制度運用クラウド" と "組織コンサルティング" をワンストップサービスで提 供し、顧客企業の組織課題に貢献するプラットフォーム事業です。 エンゲージメント経営プラットフォーム TUNAG コミュニティ運営に必要な機能をワンストップで提供し、コミュニティのエンゲージメント向上 と収益化を支援するプラットフォーム事業です。 オンラインサロンプラットフォーム FANTS

Slide 4

Slide 4 text

FANTS - オンラインサロンプラットフォーム オンラインサロンを開設・運営するためのプラットフォーム。SNS + サブスク をアプリで。 2つ⽬の事業として2020年5⽉にリリース。コロナ禍でのコミュニティ運営や収益化を⽀援。

Slide 5

Slide 5 text

FANTS - 主なオンラインサロン プロスポーツチーム、アイドルユニット、タレントや著名⼈、レジャー施設、YouTuber、 協同組合、スクールや習い事など、幅広いカテゴリーでオンライサロン展開が拡⼤中。

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

Railsメジャーバージョンアップを 安全にカナリアリリースする

Slide 8

Slide 8 text

㊗Rails7🎉 (今⽇は5.1 から 6.1へ上げた話です🙏)

Slide 9

Slide 9 text

● 各種プロセスのカナリアリリース ○ puma ○ sidekiq ○ delayed_job ○ cron ● 発⽣した課題 ○ カナリアリリース中のデプロイ ○ Aurora MySQLのクエリキャッシュ ○ rackの挙動変更 ○ CSRFトークンが異なる アジェンダ 最近、弊社のRailsアプリケーションをv5.1からv6.1へメジャーバージョンアップしました。 メジャーバージョンアップは⼤きな変更ですが、カナリアリリースにより安全にリリースすることができ ました。⼯夫した点について共有します。

Slide 10

Slide 10 text

各種プロセスの カナリアリリース⽅法

Slide 11

Slide 11 text

前提 ● EC2インスタンス上で動いていたRailsアプリケーションを、ECS上のDockerコンテナへ移⾏ ● capistranoによるデプロイから、ECSのローリングアップデート・Blue/Greenデプロイメン ト⽅式へ移⾏ 今回は、Railsバージョンアップだけではなく、同時に以下のような変更を⾏いました。 コンテナ化と同時に実施した理由は。。。 ⻑い間Railsバージョンアップしておらず、メジャーバージョンはじめ多くの更新が溜まっ ており、⼿動で確認が必要な部分が少なくなかった。 もともとコンテナ移⾏プロジェクトを進めており、どうせ⼿動でアプリケーション全体を 確認するなら同時にやってしまいたかった

Slide 12

Slide 12 text

カナリアリリースについて 並⾏稼働は⼀ヶ⽉ほど、以下のような形式で⾏いました。 通常のユーザーへ影響を出すこ と無く、社内ユーザーのリクエ スト(IPアドレス判定)から発生し た処理のみを検証の対象にした

Slide 13

Slide 13 text

pumaのカナリアリリース Pumaへのリクエスト振り分けは、Application Load Balancerのリスナールールで⾏いました。 ● 確認の最初期は、HTTPヘッダーに特定の⽂字列が含まれている場合のみ、 6.1環境へ振り分ける(開発者限定) ● 2週間ほど、⾃社のオフィスのIPからきたリクエストのみ6.1環境へ振り分け る(社員限定)

Slide 14

Slide 14 text

sidekiqのカナリアリリース ジョブの発⾏元となるpumaのリクエストが社内のユーザーである場合のみ、6.1環境で動くように ● ジョブの受け渡しにredisを利⽤しており、6.1環境⽤のRedisを新規で⽤意する ● 6.1環境では、ジョブを登録する側(Puma)とジョブを実⾏する側(sidekiq)も、新規 に設置したredisを参照する

Slide 15

Slide 15 text

delayed_jobのカナリアリリース ジョブの発⾏元となるpumaのリクエストが社内のユーザーである場合のみ、新環境での動くように ● delayed_jobはテーブルにJobが作成される ● 6.1環境⽤のテーブルを新規で⽤意する ● Delayed::Backend::ActiveRecord::Job.table_nameを置き換え、6.1環境と 5.1環境で別のテーブルをジョブキューとして使⽤する

Slide 16

Slide 16 text

cronのカナリアリリース cronの処理は重複して実⾏することが出来ないものが多く、⼀つのジョブが処理する範囲がユーザー単位で はないため、完全な並⾏稼働は出来ませんでした。重複して実⾏しても問題ない⼀部の処理のみ、両環境で 並⾏稼働して挙動を確認しています。 ● OSのcronから ECS Scheduled Tasks へ移⾏ ● いままで利⽤していたwhenever gemの設定ファイル を流⽤できる、elastic_wheneverを利⽤しています

Slide 17

Slide 17 text

elastic_whenever gem について余談 ● elastic_wheneverはCloudwatch EventsからECSのタスクを起動しますが、 ECSのCapacity ProviderにASGProviderを指定しているにもかかわらず、タス クがPendingにならず、無⾔で起動を諦めてしまうという問題に遭遇しました 。 ● こちらはAWSのサポートの⽅に相談しても原因がつかめず、Step Functions 経由でリトライしてみたらどうか、というアドバイスを頂いたため、Step Functionsを呼び出すように、elastic_wheneverを改造しています。 ● Step Functions経由で呼び出すと、ちゃんとクラスタのオートスケールを待っ てタスクが起動するため、結局リトライ⾃体は⼊れませんでしたが、各タスク 起動前後に共通の処理を割り込ませたりもできるため、Step Functions経由に したのは正解だったと思います。

Slide 18

Slide 18 text

発⽣した課題

Slide 19

Slide 19 text

カナリアリリース中のデプロイ運⽤ルール ● 5.1環境に新コードがデプロイされた際は、その新コードを6.1環境にもマージし、テストし てからデプロイする必要があるため、並⾏稼動中の新環境に適⽤できるまでタイムラグが発 ⽣し、実⾏される処理に差が⽣まれ危険です。 ● そのため、現⾏の5.1をリリースした場合はALBから新環境にリクエストを流すのを⾃動的 に停⽌し、新環境の6.1が現環境の5.1に追いついてから、リクエストの振り分けを再開する ようにしました。 ● マージ作業をリリースの毎に実施するのは⾯倒なので、並⾏稼働期間中の⼣⽅以降はリリー スを禁⽌し、その間に6.1環境へのマージ作業とデプロイを⾏う運⽤としました。 ❌ 旧環境へのデプロイを トリガーに新環境への 振り分けを停止 弊社は普段デプロイを⽇に数回実施しており、カナリアリリース中もデプロイを実施したい

Slide 20

Slide 20 text

Aurora MySQLのクエリキャッシュ MySQLのクエリキャッシュが有効な状態で、 Rails 5.1のアプリケーションと、Rails 6.1のア プリケーションからAurora MySQLへ全く同じ SQLを実⾏すると、クエリキャッシュが原因で エラーが発⽣します。 mysql2 gemの右issueで報告されているうちの いくつかと同じ問題ですが、最終的には、カナ リアリリース中のみ、パフォーマンスに問題が 出ないのを確認した上で、Aurora MySQLの query_cache_sizeを0としました。 本番リリース後はquery_cache_sizeをもとに戻 しました。

Slide 21

Slide 21 text

新バージョンのrackのセッションの後⽅互換性がない ● Rails5.1から6.1へのアップデートの際に、rack gem が 2.0.8 以上に変更されます ● rack(2.0.8)でセッションハイジャック対策の変更が⼊り、セッションストアにsessionを持つ 際のkeyが変更されました ● redis-rack では、新環境のrackで作成されたsessionから旧環境のバージョンの rack で⽣成し たセッションデータを取得することはできるフォールバックが提供されているが、逆はできな い。 ● 本番リリース後に旧環境に切り戻しをする場合、新環境で⽣成されたセッションが無効になっ てしまう問題がある。 ● カナリアリリース時にはrackのバージョンを固定 参考: https://qiita.com/daido1976/items/7a6f4a304d661d98a11b

Slide 22

Slide 22 text

CSRFトークンの後⽅互換性が無い ● Rails 6.1から、CSRFトークンのエンコードが変更 されました。 ● Upgrade-safe URL-safe CSRF tokensによって、 6.0以前のCSRFトークンを持ったユーザーが、6.1 環境へPOSTしてもエラーとはならないのですが、 6.1以降のCSRFトークンを持ったユーザーが6.0以 前の環境へPOSTすると、CSRF検証に失敗します 。 ● 同じユーザーからのリクエストがバージョンの異 なる新・旧環境に分散するカナリアリリースでは ⼤きな問題となります。 ● 今回は、同じユーザーであれば基本的に同じバー ジョンのサーバーでリクエストが処理されるため 、回避できました。(ただし切り戻しをした場合に 問題となる)

Slide 23

Slide 23 text

まとめ ● カナリアリリース期間中に発⾒されたアプ リケーションの問題はほとんどありません でした。 ● ただ、カナリアリリースすることで、アプ リケーションのproduction環境での挙動や 、最終的な切り替えの⼿順、切り戻しの⼿ 順をはっきり把握でき、安⼼・安全のリリ ースが⾏えたのは良かったです。 ● Rails7バージョンアップも安全にリリース するぞ🔥 ● ちなみに今回の発表内容のブログも書いて います👉 ○ https://tech.stmn.co.jp/entry/2021/11/08/144233

Slide 24

Slide 24 text

名古屋 + 鎌倉 + リモート さらなる規模拡⼤&エンジニア採⽤を⽬指し、鎌倉とリモートでの採⽤を開始。 ・名古屋オフィスは、2022年3⽉に移転予定 → コロナな時代であっても、出社する価値のあるオフィスや仲間たちを作る ・鎌倉オフィスは、鎌倉駅徒歩1分の好⽴地 → ⾃然と⽂化を感じながら⽣産⾼を意識して働く場所を作りたい ・フルリモートでの採⽤ → エンジニアを居住地を限定せずに集めたい(現在ベルギーからリモートが1⼈)

Slide 25

Slide 25 text

Railsエンジニア絶賛採⽤中です︕ Rails, React/Next.js, Swift/Kotlin, デザイナー, PdM、マネージャーを採⽤中。 エンジニア採⽤サイトにて、メンバーインタビュー、 カルチャーや技術について、エンジニアブログなどを紹介しています。