Contents
導入と最優先アクション
運用チームが短期間でRuby 3.2の導入可否を判断できるよう、実務的な手順と閾値を整理しました。Ruby 3.2は性能改善やツールチェーン更新を含みますが、互換性リスクは環境や依存Gemで大きく変わります。まずは下の優先アクションを順に実行してください。優先順は「準備 → 検証 → 段階展開」です。
準備(環境・CI)
まずは再現性のある検証環境とCIを準備します。
- ステージングでRuby 3.2の再現イメージを用意する(例: ruby:3.2-slim)。公式ソースは署名を検証すること。
- CIマトリクス(3.0 / 3.1 / 3.2)を追加し、テストとネイティブ拡張のビルド確認を自動化する。
- 主要監視指標(リクエスト数、エラー率、p95/p99、RSS、GC pause)を収集できるように準備する。
検証(互換性・ベンチ)
ステージングで機能と性能を並列に評価します。
- テストスイートをRuby 3.2上で実行し、警告(-w)を有効にする。
- 主要Gemのrequired_ruby_versionやIssue/PRで3.2対応状況を確認する。
- ベンチはYJIT有効/無効の両方で実施し、ウォームアップ→複数回測定で中央値を使う。
導入(カナリア・昇格基準)
カナリア展開は段階的に数値基準で昇格します。
- 初期カナリア: 全トラフィックの5%を6時間運用して観測。
- 中間昇格: 25%→50%へ段階的に24〜72時間ごとに拡大。
- 最終昇格: 7日間(24/7)で閾値を満たせば本番完全切替。閾値は本文で数値化しています。
Ruby 3.2 の改廃APIと破壊的変更(一次情報リンク付)
Ruby 3.2のBreaking・Deprecated情報はプロジェクト毎の影響が異なります。ここでは一次情報への直接リンクと、現場で使える差分抽出手順を示します。必ず自プロジェクトで該当APIの有無を確認してください。
確認すべき主要カテゴリ
ひとまず優先して確認すべき領域と理由です。一つずつCIや検索で該当箇所を洗い出してください。
- キーワード引数の挙動(引数合成や警告の微修正が入りやすい)。互換性の観点で影響度は高いです。
- ネイティブ拡張(C拡張)のABIやビルド要件の変更。ビルド失敗や挙動差が起きやすいです。
- Ractor / Fiber / Scheduler のAPIや制約(スレッド・共有オブジェクト周り)。並行処理を使う部分で要確認です。
- 標準ライブラリでの非推奨・削除(OpenSSLやnet/http、JSON等の細かな変更)。
- ツールチェーン(Bundler / RubyGems / RBS / TypeProf)の互換性や出力差。
各項目の一次確認は次のリンクから行ってください。公式NEWSやリリースタグ、GitHubのPR検索で該当差分を追跡できます。
- Ruby公式リリースノート(3.2): https://www.ruby-lang.org/en/news/2023/12/25/ruby-3-2-0-released/
- GitHub: Ruby 3.2 のNEWS(ソース): https://github.com/ruby/ruby/blob/v3_2_0/NEWS
- GitHub Releases (v3_2_0): https://github.com/ruby/ruby/releases/tag/v3_2_0
- 変更差分(タグ比較を使って確認): https://github.com/ruby/ruby/compare/v3_1_0...v3_2_0
- YJIT 関連 PR 検索: https://github.com/ruby/ruby/pulls?q=is%3Apr+is%3Amerged+YJIT
- GC 関連 PR 検索: https://github.com/ruby/ruby/pulls?q=is%3Apr+is%3Amerged+GC
- Ractor 関連 PR 検索: https://github.com/ruby/ruby/pulls?q=is%3Apr+is%3Amerged+Ractor
一次情報から具体差分を抽出するコマンド例
公式NEWSやコミットログから“明確な差分一覧”を取得する簡易手順です。ローカルで実行して、該当APIを抽出してください。
- NEWS中のdeprecated/removeを抜き出す(例):
|
1 2 3 |
curl -s https://raw.githubusercontent.com/ruby/ruby/v3_2_0/NEWS \ | grep -i -nE 'deprecated|remove(d)?|obsolete' |
- タグ間コミットメッセージに“remove/deprecate”を検索する(gitが使える環境で):
|
1 2 3 4 5 |
git clone --depth 1 https://github.com/ruby/ruby.git cd ruby git fetch --tags git log --pretty=oneline v3_1_0..v3_2_0 --grep=deprecated --grep=remove -i |
- プロジェクト側で該当APIを検索する(例: キーワード引数やRactorを検索):
|
1 2 3 |
# 例: リポジトリ内で "keyword arguments" や "Ractor" を検索 rg --hidden --no-ignore-vcs -n "keyword|Ractor" path/to/your/app |
上記の出力をもとに、具体的な関数名・クラス名の一覧を自動生成し、CIで警告検出を行うテンプレートを作成してください。
パフォーマンスとベンチマーク(Ruby 3.2 の実運用影響)
Ruby 3.2 はJITやGCの改善を含みますが、効果はワークロード依存です。ここでは必須指標、再現可能なベンチ手順、期待する解釈方法を示します。必ず同一条件で比較してください。
必須指標と観測対象
ベンチ設計で必須となる観測項目です。これらを最低限揃えて初めて比較可能です。
- 起動時間(cold start)
- スループット(requests/sec)とレイテンシ(平均・p95・p99)
- エラー率(400/500系の割合)
- メモリ(RSS)とGC統計(GC.stat、GC::Profiler)
- CPU使用率とコンテキスト/スレッド状況
推奨ベンチコマンドと解釈
実行例と各オプションの意味、期待される出力の解釈を示します。まずは単純なHTTP負荷試験です。
- wrk(代表例: 高負荷計測)
|
1 2 3 |
# 基本例: 2スレッド 100コネクション 60秒 wrk -t2 -c100 -d60s http://localhost:3000/endpoint |
説明: -t はクライアントスレッド数、-c は同時接続数、-d は実行時間です。wrkはBurst的に高いレートを出します。一定レートが必要ならwrk2や-r(RPS制御)を使ってください。
- wrk2(一定RPSを狙う場合)
|
1 2 3 |
# wrk2 の例: target 1000 req/sec を60秒間 wrk -t2 -c100 -d60s -R1000 http://localhost:3000/endpoint |
期待出力(例):
- Requests/sec: 3200.50
- Latency (ms): Avg 3.5, Stdev 4.1, 50% 2.8, 95% 12.2, 99% 35.6
解釈の指針:
- スループット差は相対(%)で判断。性能劣化が5%以上なら要調査。
-
p95増加が10%未満、p99増加が20%未満なら許容の目安。ただしSLO次第で厳格化すること。
-
マイクロベンチ(benchmark-ips)
|
1 2 3 4 5 6 7 8 9 |
require 'benchmark/ips' Benchmark.ips do |x| x.config(time: 5, warmup: 2) x.report("method_a") { your_method_a } x.report("method_b") { your_method_b } x.compare! end |
測定は warmup を入れて5回程度繰り返し、中央値を取ってください。
JIT(YJIT)有効/無効比較手順
JITの効果はウォームアップやCPUバウンド性に依存します。比較手順の一例です。
- サーバ起動を2通りで行う(YJIT有効/無効)。多くの環境では
ruby --yjitオプションでYJITを有効化できます。 - ウォームアップ: 最低3回のウォームアップ(30〜60秒)を行い、その後で計測を5回以上実行する。
- 計測値はrequests/sec、p95、p99、RSS、GC回数を必ずセットで比較する。
GC観測(Ruby側)
サーバ側でのGC観測サンプル:
|
1 2 3 4 5 6 7 |
require 'json' puts JSON.dump(GC.stat) # 現在の統計を一度表示 GC::Profiler.enable # 実機動作を一定時間行った後 GC.start File.write("gc_profile.txt", GC::Profiler.result) |
GC::ProfilerのログやGC.statのスナップショットを、各バージョンで同タイミングに収集して比較してください。
互換性チェック・移行手順と数値化した昇格基準
移行の成否は「検出できるチェック」と「自動で判断できる数値基準」によります。ここでは優先度別のチェック項目、短期〜長期の移行フロー、具体的な昇格/ロールバック閾値を示します。
優先度付き互換性チェック
まず優先度高から対応してください。各項目はCI/静的解析で自動化すると効果的です。
- 高(最優先)
- キーワード引数/メソッドシグネチャの互換性。検出方法: テストを -w で実行し、警告を収集。
- ネイティブ拡張のビルド成功と動作確認。検出方法: Gemfile.lockからextensionsを持つGemを列挙してCIでビルドする。
-
required_ruby_version のチェック。
-
中(次点)
- 標準ライブラリの非推奨API使用。検出方法: NEWSの該当項目とコード検索。
-
OpenSSLやlibyamlなどのシステムライブラリ依存バージョン。
-
低(運用上の注意)
- RBS/TypeProfの型定義差分。静的にCIで型チェックする場合は確認。
Gemfile.lock中のネイティブ拡張抽出(例):
|
1 2 |
ruby -r bundler/lockfile_parser -e 'puts Bundler::LockfileParser.new(File.read("Gemfile.lock")).specs.select{|s| s.extensions.any?}.map(&:name)' |
※BundlerのバージョンによってAPIが異なるため、CI内で実行するスクリプトとして調整してください。
短期/中期/長期フロー(具体手順)
短期・中期・長期の推奨フローと期間、割合を数値化して示します。
- 短期(準備〜初期カナリア)
- ステージングでフルテスト+負荷試験(同一ベースイメージ)。
-
初期カナリアはトラフィックの5%を6時間運用。
-
中期(拡大カナリア)
- 25%環境を24時間、50%を48時間運用。ネイティブGemのビルドを全リージョンで実施。
-
問題なければ50%環境を7日間監視。
-
長期(完全展開)
- 7日間の安定性を確認後、ローリングで100%展開。モニタリングのアラートとロールバック手順を確認。
昇格・ロールバックの数値化閾値(自動判定例)
以下は実務で自動化しやすい閾値の例です。組織SLOに合わせて調整してください。
- エラー率(5xxの割合): 絶対増分が +1.0 ポイント を超えたら警告(例: 2% → 3.5% は +1.5 で失敗)。PromQL例:
|
1 2 |
(sum(rate(http_requests_total{job="app",status=~"5.."}[5m])) / sum(rate(http_requests_total{job="app"}[5m]))) > 0.01 |
- p95 レイテンシ: 相対増分が +10% を超えたら警告。比較は baseline と current の比率で判定。PromQL(offsetを利用した比較例):
|
1 2 3 4 5 |
histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le)) / histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m] offset 1d)) by (le)) > 1.10 |
- p99 レイテンシ: 相対増分が +20% を超えたら要調査。
- スループット(requests/sec): 減少が5%以上なら要調査。
- メモリ(RSS): 増加が10%以上なら要調査。
- GC pause (p95): 増加が20%以上なら要調査。
上記いずれかの閾値超過が短時間で継続する場合は自動ロールバックか段階停止を行ってください。
CI/Docker運用例とセキュリティ対策(実務向け)
本番イメージとCIは軽量かつ再現性を優先し、署名と脆弱性スキャンを組み込みます。ここでは実務向けのDockerfileとGitHub Actions例、署名/スキャン手順を示します。
Dockerfile(実務向け、マルチステージ・非root)
短い説明:ビルド依存はビルドステージに閉じ込め、本番イメージは最小化・非rootで実行します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# builder stage FROM ruby:3.2-slim AS builder RUN apt-get update \ && apt-get install -y --no-install-recommends build-essential libssl-dev libpq-dev zlib1g-dev pkg-config git ca-certificates \ && rm -rf /var/lib/apt/lists/* WORKDIR /app COPY Gemfile Gemfile.lock ./ ENV BUNDLE_PATH=/gems RUN gem install bundler --no-document \ && bundle config set without 'development test' \ && bundle install --jobs 4 --retry 3 # final stage FROM ruby:3.2-slim AS runtime RUN apt-get update \ && apt-get install -y --no-install-recommends ca-certificates libpq5 \ && rm -rf /var/lib/apt/lists/* # 非rootユーザー作成 RUN groupadd --system app && useradd --system --gid app --create-home app USER app WORKDIR /app COPY --from=builder /gems /gems ENV PATH=/gems/bin:$PATH COPY --chown=app:app . . CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"] |
ポイント: --no-install-recommends、apt-get のキャッシュ削除、非root実行、ビルド依存は builder に閉じる。
GitHub Actions(ネイティブGemビルドとセキュリティスキャン)
短い説明:マトリクスで3系を回し、ネイティブ拡張のビルド確認と脆弱性スキャンを実行します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
name: CI on: [push, pull_request] jobs: test: runs-on: ubuntu-latest strategy: matrix: ruby: [3.0, 3.1, 3.2] steps: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} bundler-cache: true - run: gem install bundler-audit --no-document - run: bundle install --jobs 4 --retry 3 - run: bundle exec rake test native-build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 with: ruby-version: 3.2 - run: | # ネイティブ拡張を持つGemを列挙してビルドを確認する簡易例 ruby -r bundler/lockfile_parser -e 'puts Bundler::LockfileParser.new(File.read("Gemfile.lock")).specs.select{|s| s.extensions.any?}.map(&:name)' - run: bundle install --jobs 4 --retry 3 security-scan: runs-on: ubuntu-latest needs: test steps: - uses: actions/checkout@v4 - name: Bundler-Audit run: | gem install bundler-audit --no-document bundle audit update bundle audit check || true - name: Container scan with Trivy (optional) run: | # Dockerを使える環境でイメージをbuildしてスキャンする例 docker build -t my-app:${{ github.sha }} . docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy:latest image --exit-code 1 my-app:${{ github.sha }} || true |
注意: Actionやツールのバージョンは固定して運用してください。脆弱性スキャンは定期実行を推奨します。
署名・CVE確認・運用上の注意
- Rubyのソース/バイナリは公開鍵署名で検証してください(公式ダウンロードページで署名と公開鍵を参照)。例: https://www.ruby-lang.org/en/downloads/
- コンテナイメージは cosign や Notary で署名・検証してください(sigstore/cosign を推奨)。https://github.com/sigstore/cosign
- Gemの脆弱性は bundler-audit や OSイメージの脆弱性はTrivyで定期スキャンします。CVEはNVDやOSベンダーのセキュリティアドバイザリを確認してください。
- 署名済バイナリ/イメージを採用することで供給経路攻撃リスクを低減できます。
まとめ
Ruby 3.2 の導入は性能改善と新機能の恩恵を得られる反面、キーワード引数・ネイティブ拡張・並行処理周りの互換性がキーになります。まずはステージングで3.2を動かし、YJITの有効/無効比較、主要Gemの互換性チェック、カナリアでの段階展開を行ってください。数値化した閾値(エラー率 +1p、p95 +10%、p99 +20%、RSS +10% 等)を用い自動化したゲートで昇格することを推奨します。一次情報(公式NEWS / GitHubリリース / PR検索)を必ず参照し、CIにネイティブビルドと脆弱性スキャン、イメージ署名検証を組み込んでください。