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
680
LeanLanguage2019 リニューアル、こうして不具合は起こった
daponta
August 24, 2019
Tweet
Share
Other Decks in Programming
See All in Programming
GitHubで育つ コラボレーション文化 : ニフティでのインナーソース挑戦事例 - 2024-12-16 GitHub Universe 2024 Recap in ZOZO
niftycorp
PRO
0
120
快速入門可觀測性
blueswen
0
410
20年もののレガシープロダクトに 0からPHPStanを入れるまで / phpcon2024
hirobe1999
0
820
アクターシステムに頼らずEvent Sourcingする方法について
j5ik2o
4
360
歴史と現在から考えるスケーラブルなソフトウェア開発のプラクティス
i10416
0
140
Zoneless Testing
rainerhahnekamp
0
120
テストコード書いてみませんか?
onopon
2
210
Асинхронность неизбежна: как мы проектировали сервис уведомлений
lamodatech
0
990
バグを見つけた?それAppleに直してもらおう!
uetyo
0
180
開発者とQAの越境で自動テストが増える開発プロセスを実現する
92thunder
1
200
毎日13時間もかかるバッチ処理をたった3日で60%短縮するためにやったこと
sho_ssk_
1
360
数十万行のプロジェクトを Scala 2から3に完全移行した
xuwei_k
0
350
Featured
See All Featured
Being A Developer After 40
akosma
87
590k
Build your cross-platform service in a week with App Engine
jlugia
229
18k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
28
2.1k
Faster Mobile Websites
deanohume
305
30k
Stop Working from a Prison Cell
hatefulcrawdad
267
20k
Git: the NoSQL Database
bkeepers
PRO
427
64k
The Invisible Side of Design
smashingmag
298
50k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
132
33k
Gamification - CAS2011
davidbonilla
80
5.1k
GitHub's CSS Performance
jonrohan
1031
460k
Statistics for Hackers
jakevdp
796
220k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
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