Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
LeanLanguage2019 リニューアル、こうして不具合は起こった
Search
daponta
August 24, 2019
Programming
0
740
LeanLanguage2019 リニューアル、こうして不具合は起こった
daponta
August 24, 2019
Tweet
Share
Other Decks in Programming
See All in Programming
アメ車でサンノゼを走ってきたよ!
s_shimotori
0
220
スマホから Youtube Shortsを見られないようにする
lemolatoon
27
32k
bootcamp2025_バックエンド研修_WebAPIサーバ作成.pdf
geniee_inc
0
110
バッチ処理を「状態の記録」から「事実の記録」へ
panda728
PRO
0
160
Pull-Requestの内容を1クリックで動作確認可能にするワークフロー
natmark
2
510
登壇は dynamic! な営みである / speech is dynamic
da1chi
0
330
AIと人間の共創開発!OSSで試行錯誤した開発スタイル
mae616
1
180
はじめてのDSPy - 言語モデルを『プロンプト』ではなく『プログラミング』するための仕組み
masahiro_nishimi
2
420
技術的負債の正体を知って向き合う / Facing Technical Debt
irof
0
170
uniqueパッケージの内部実装を支えるweak pointerの話
magavel
0
1k
Software Architecture
hschwentner
6
2.3k
CSC509 Lecture 03
javiergs
PRO
0
340
Featured
See All Featured
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
9.7k
YesSQL, Process and Tooling at Scale
rocio
173
14k
How To Stay Up To Date on Web Technology
chriscoyier
791
250k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.2k
GitHub's CSS Performance
jonrohan
1032
470k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
189
55k
The Illustrated Children's Guide to Kubernetes
chrisshort
49
51k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
1.7k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4k
A designer walks into a library…
pauljervisheath
209
24k
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
Gamification - CAS2011
davidbonilla
81
5.5k
Transcript
リニューアル、 こうして不具合は起こった LearnLanguage2019 @da_ponta
4/15に大規模な システムリニューアルをしました
前提 リニューアル箇所 - DB、テーブル構造 - サーバサイド - インフラ - アプリ
- UI - フロントエンド - 不要な機能の削減 ⇒ システムすべて
今回はリリース後に発覚した 不具合事例を紹介します
技術関連の詳細はTechCon2019資料をどうぞ https://bit.ly/2Z5lnqn
自己紹介 井田 祐太 @da_ponta 所属:株式会社ディー・エヌ・エー 担当サービスの開発全般を担当 - Ruby - Kubernetes
- Node.js - Android ろくろも回します
本題
リニューアルの不具合は えてしてデータで起こる
時間いっぱいまで紹介していきます - リレーション先がないデータ - 実はユニークではないカラム - nullは許容するが空文字は許容外のデータ - レコード化されていなかったデータ -
ハッシュ化ロジックの継承 - 大文字と小文字で一致しないメールアドレス - 整合性のあってないカウントカラム - 移行先のカラムの認識違いによる齟齬 - リリース直後に壊れるライブラリ - SJIS問題 まだまだあるよ★ データの更新ができない 表示に関する不整合 暗号化・ハッシュ化の闇
① 移行データの更新ができない リニューアルにおけるデータにまつわる変更 - テーブル構造・構成を変えた - カラムの方と制約を変えた - 一部マスター系のデータは削除ステータスを間引いて移行した -
バリデーションロジックは強化した
① 移行データの更新ができない 1-1 リレーション先が存在しない 例えばコメント削除, 投稿先のtopicは存在しない class Comment < ApplicationRecord
belongs_to :topic, foreign_key: :topic_id def remove! self.update!(deleted: true) end end > comment.remove! ActiveRecord::RecordInvalid: Validation failed: Topic must exist
① 移行データの更新ができない 1-2 実はユニークではなかったカラム 認証のメールアドレスは 重複登録できないという前後共通の仕様 実際に移行してみると同一のアドレスが別々のユーザに登録されている ⇒ 結果想定と異なるログイン挙動に
① 移行データの更新ができない 1-3 nullは許容するが空文字は許容外のデータ title未入力はnullであるはずが空文字で登録されているデータが存在する class Novel < ApplicationRecord validates
:title, length: { in: 1..100 }, allow_nil: true end > novel.title => “” > novel.validate! ActiveRecord::RecordInvalid: Validation failed: Title is too short (minimum is 1 character)
① 移行データの更新ができない 1-3-2 仕様の長さを超えていることもある リニューアル前後ともにタイトルは100m文字まで ⇒ 実際には数千文字のレコードは存在する ⇒ 「仕様」は信じてはいけない class
Novel < ApplicationRecord validates :title, length: { in: 1..100 }, allow_nil: true end
① 移行データの更新ができない 1-4 そもそもDBにレコードが存在しない 初期のころHTMLのみで運用されていた機能のデータは移行していなかった 例えば「運営からのお知らせ」
① 移行データの更新ができない なぜ気づかなかったのか? - 移行処理の高速化のためにデータ移行時にはバリデーションしていない - 太古のデータのみ発生する - 太古のデータの状況再現・検知は困難 ⇒
手動の検証では検知不可能 データ移行のチェックうはサンプルではなく網羅的にやりましょう
② 暗号化・ハッシュ化の闇 2 - 2 ハッシュ化ロジックの継承 パスワードなどのハッシュ値は復号できないので ロジックを引き継がなければならない かつ、社内基準に則ったハッシュ化を施す必要がある この時点で辛い
ログインフォーム ↓ 旧ハッシュ化(弱) ↓ 新ハッシュ化(強) ↓ 旧パスワードと照合 生パスワード ↓ 新ハッシュ化(強)
↓ 新パスワードレコードを登録
② 暗号化・ハッシュ化の闇 2 - 1 ハッシュ化ロジックの継承 特定のキーのときに旧ハッシュ化処理が PerlとRubyで一致しなかった ⇒Perlを呼び出すことに def
self.legacy_hash(password, key) script_path = Rails.root.join("script", "perl", "hash.pl").to_s stdout, stderr, status = Open3.capture3("perl", script_path, password, key) stdout end
② 暗号化・ハッシュ化の闇 2 - 1 大文字と小文字で一致しないメールアドレス 入力されるアドレス:
[email protected]
移行前に登録されている:
[email protected]
当然ながら暗号化後の結果が異なるため認証は通らない ⇒ 全ユーザデータ修正へ User.find_each do |users| email = decrypt(user.email) email.downcase! user.update(email: encrypt(email)) end
③ 表示に関する不整合 3 - 1 整合性のあってないカウントカラム 「小説の閲覧数」(以前から存在)と「閲覧した人一覧」(新規)が一致しない※ だいたいモバゲー時代の名残 ⇒ カウントデータ修正へ
※実際には小説の閲覧ではありません
③ 表示に関する不整合 3 - 2 移行先のカラムの認識違いによる齟齬 - レコードの更新日 - 読者向けの作品最終更新日
- 作家向けの最終保存日 これらの元のデータがない・表示される想定の値ではなかった・入れ替わってしまった ⇒ 表示側で加工 バックエンド・フロントエンド間の認識違い
④ ライブラリのバージョンが上がって壊れる 小説のエディタ機能に Vueのtiptapというライブラリを使用 → エディタ「ではない」ページのリリース → 突如iOSにてエディタが起動せず ⇒ 原因:tiptapの依存するライブラリの方でマイナーアップデート
→ バージョンをもどして解決かと思われたが …? → 全環境にて起動しなくなる ⇒ 原因:特定のエンジニアが生成した package-lock.jsonでnpm installすると壊れる バージョンの固定・管理は必須
⑤ SJIS問題 5-1 URLのパスも変更になっているためリダイレクトする必要があった 旧:/search?keyword=ファンタジー ⇒ /search?keyword=%83t%83%40%83%93%83%5E%83W%81%5B 新:/novels?keyword=ファンタジー ⇒ /novels?keyword=%E3%83%95%E3%82%A1%E3%83%B3%E3%82%BF%E3%82%B8%E3%83%BC
SJISでエンコードされたURLをリダイレクトしてもシステム側でデコードできない ⇒ 対応見送り…
まとめ - DBまで変えるとまず間違いなく不整合は発生する ⇒コア機能については事前に同等のバリデーションをかけるべき - 暗号化ハッシュ化ロジックの置き換えには注意 - 新旧の機能仕様・データ移行の実装・フロントの実装すべての認識のすり合わせは怠らず - できることなら全て一度にリニューアルしないことをおすすめします
次はあなたの番かもしれない
ありがとうございました LearnLanguage2019 @da_ponta