Upgrade to Pro — share decks privately, control downloads, hide ads and more …

新卒2ヶ月目で起こしたインシデントの話

 新卒2ヶ月目で起こしたインシデントの話

人生初の登壇!

2023年ヒヤリハット大反省会@新宿 で発表した

Toranosuke Ujike

December 07, 2023
Tweet

Transcript

  1. © 2023 Wantedly, Inc.
    新卒2ヶ月目で起こした
    インシデントの話
    2023年ヒヤリハット大反省会 @新宿
    Toranosuke Ujike / @tora_tora_bit

    View full-size slide

  2. 自己紹介
    氏家 虎之介 (Ujike Toranosuke)
    フロントエンドエンジニアとして、
    Wantedly Visitを主にUI
    面から改善することで、ユーザー、企業への提供価値を向
    上させている。
    © 2023 Wantedly, Inc.
    所属: Wantedly, inc.
    X: @tora_tora_bit
    ある特定の技術領域に縛られないことをモットーに、
    現在は優秀な同期と共にバックエンドについて学習中。

    View full-size slide

  3. インシデントの内容
    メッセージ機能を修正する施策を担当
    © 2023 Wantedly, Inc.

    View full-size slide

  4. やばい
    Wantedlyのメッセージ送信機能を壊した
    © 2023 Wantedly, Inc.

    View full-size slide

  5. ステージング環境での検証や
    テストを書いて確認したのになぜ
    © 2023 Wantedly, Inc.

    View full-size slide

  6. 根本原因
    RubyのHashから値を取得する際の
    Key指定を間違えていた
    © 2023 Wantedly, Inc.

    View full-size slide

  7. Ruby
    Rubyには文字列とシンボルの
    2つの異なるデータ型がある
    © 2023 Wantedly, Inc.

    View full-size slide

  8. シンボルを使ったHash
    © 2023 Wantedly, Inc.
    user = {
    name: "Tora",
    age: 26,
    city: "Kyoto"
    }
    result = user["name"]
    result.inspect # nil
    ruby 文字列で指定した場合
    キーとして使われているのはシンボル
    文字列で "name" を指定しても
    対応するキーが存在しないため nil が返される

    View full-size slide

  9. 正しくはこう
    © 2023 Wantedly, Inc.
    user = {
    name: "Tora",
    age: 26,
    city: "Kyoto"
    }
    result = user[:name]
    result.inspect # "Tora"
    ruby シンボルで指定した場合
    要素へのアクセスにはHashのキーとして
    使用されているデータ型を正確に指定する必要がある

    View full-size slide

  10. 実際に何が起こっていたのか
    © 2023 Wantedly, Inc.
    user = UserHashService.compose!( # hashを作成
    name: name,
    age: age,
    city: city,
    )
    # user hashのkeyはシンボルで宣言されているため文字列で指
    定できない
    name = user["name"]
    age = user["age"]
    city = user["city"]
    let(:user) { # モックデータ
    {
    "name" => "Tora",
    "age" => 26,
    "city" => "Kyoto",
    }
    }

    allow(UserHashService).to
    receive(:compose!).and_return(user)

    it "user test" do
    name = { user["name"] }
    expect(name).to eq("Tora")
    # モックデータのキーとして扱われているのは文字列なのでテストが通る
    end
    例) user_message_service.rb 例) user_message_service_spec.rb

    View full-size slide

  11. 根本原因
    都合の良いモックデータを与えてしまっていた
    © 2023 Wantedly, Inc.

    View full-size slide

  12. マージまでの流れ
    1. PRを作成
    2. ステージング環境で検証
    3. 問題ないことを確認してレビュー依頼
    4. レビューを受けて修正
    5. テストが通ることを確認
    6. PRのレビューを再依頼
    7. Approveをもらう
    8. マニュアルテストをせずに翌日にマージ インシデント発生
    © 2023 Wantedly, Inc.

    View full-size slide

  13. レビューを貰ったあとに
    ステージング環境で検証を行っていない
    © 2023 Wantedly, Inc.

    View full-size slide

  14. PRマージ後
    1. インシデント発生
    ○ Honeybadgerがエラーを拾ってSlackで通知
    2. 上司が出社
    ○ エラーを確認
    ○ 周囲のエンジニアに周知
    3. インシデント対応
    ○ Rollback
    ○ 対象のPRをRevert
    4. インシデント解消
    © 2023 Wantedly, Inc.

    View full-size slide

  15. よかったこと
    ● インシデントを起こした数十分後に上司が出社した
    ○ 上司と同期的に密なコミュニケーションがとれた
    ● リリース後の監視がうまくワークした
    ○ ユーザー問い合わせ前の内部発見に繋がった
    ● 毎週金曜日に行われている All Hands Meeting 前に気づけた
    ○ 復旧作業を他のエンジニアと協力して迅速に行えた
    ○ 焦ることなく、行うべき一次対応に集中できた
    © 2023 Wantedly, Inc.

    View full-size slide

  16. Wantedlyの障害対応の心構えについて
    Wantedly Engineering Handbook
    © 2023 Wantedly, Inc.

    View full-size slide

  17. Wantedly Engineering Handbook
    © 2023 Wantedly, Inc.
    新しくWantedlyの開発チームに参加する人向けのドキュメン

    社内のエンジニアが知るべき情報のうち外部にも公開できる情
    報を体系的にまとめたもの

    View full-size slide

  18. Wantedly Engineering Handbook
    © 2023 Wantedly, Inc.
    インシデントを起こす前日に更新

    View full-size slide

  19. Wantedly Engineering Handbook
    © 2023 Wantedly, Inc.
    障害を起こした人に向けてのセクションが加筆されている

    View full-size slide

  20. インシデントを起こしたあとに
    ドキュメントに残す文化が深く根付いている
    © 2023 Wantedly, Inc.
    Wantedlyの文化

    View full-size slide

  21. ポストモーテムとは
    © 2023 Wantedly, Inc.
    失敗から学ぶために振り返りを行うこと

    View full-size slide

  22. ポストモーテムを実施しての気づき
    そもそもテストの書き方がよくないのでは🤔
    © 2023 Wantedly, Inc.

    View full-size slide

  23. 都合の良いモックデータを与えたことが本当の原因なのか
    🤔
    © 2023 Wantedly, Inc.
    UserHashService は内部で UserService を使い User の情報を引っ張って
    きている
    本来は UserHashService の返り値をモックするのではなく
    UserService の返り値をモックしてあげるべきなのでは?
    そもそもモックせずに UserService から取得した User のデータ
    をそのまま使うことはできなかったのか?

    View full-size slide

  24. 本当の根本原因
    テストの書き方が問題ということに気づいた
    © 2023 Wantedly, Inc.

    View full-size slide

  25. 再発防止のために
    ● すぐに取り組みができること
    ○ すべてのPRにおいてマージ前後の動作確認やアラートチェックを欠かさない
    ○ テストファイルの見直し
    ● 時間をかけて改善すること
    ○ 結合テストの導入
    © 2023 Wantedly, Inc.
    大きく2つある

    View full-size slide

  26. なにを学んだか
    ● 電気通信事業者の場合メッセージ機能を停止させてしまうと官庁報告が必要
    な場合がある
    ● リリース前後にマニュアルテストをすることの重要性
    ● なにか異変に気づいたら報告することの大切さ
    ● 再発防止のためにポストモーテムを実施することの大切さ
    © 2023 Wantedly, Inc.

    View full-size slide

  27. まとめ
    © 2023 Wantedly, Inc.
    ● テストファイルの書き方は大切
    ○ 自分を疑うためのテストを書け
    ● マニュアルテストも大切
    ● インシデントが発生した場合にドキュメントに残す文化の偉大さ
    ● インシデントを起こしてしまったことで過度に責められることはない
    ● 優しい言葉をいただけたお陰でメンタルが安定した

    View full-size slide

  28. ご清聴ありがとうございました
    © 2023 Wantedly, Inc.
    おわり

    View full-size slide