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

ある日突然、Laravel Queue Workerが壊れた

1851e42555822b0fc915dbf3ef0c0f76?s=47 kubotak
March 28, 2021

ある日突然、Laravel Queue Workerが壊れた

PHPerKaigi 2021 LT

1851e42555822b0fc915dbf3ef0c0f76?s=128

kubotak

March 28, 2021
Tweet

Transcript

  1. Copyright © M&A Cloud All rights reserved. ある日突然、 Laravel Queue

    Workerが壊れた PHPerKaigi2021/LT Kenjiro Kubota
  2. Copyright © M&A Cloud All rights reserved. Profile 2 久保田

    賢二朗 kubotak-is kubotak_public kenjiro.kubota 株式会社M&Aクラウド JavaScript Go PHP https://kubotak.page
  3. Copyright © M&A Cloud All rights reserved. 前提知識 前提知識 •

    AWS ElasticBeanstalk(以降EB)のWebサーバーとWorkerサー バー上でLaravel Queuesを利用したJobを運用 • メッセージングシステムとしてAWS SQSを利用
  4. Copyright © M&A Cloud All rights reserved. アーキテクチャ

  5. Copyright © M&A Cloud All rights reserved. ある日突然、 Laravel Queue

    Workerが壊れた
  6. Copyright © M&A Cloud All rights reserved. 何もしてないのに壊れた • というわけではない。

    • PHP7.2のEB環境からPHP7.4にアップグレード後 に死んだ • EB環境が変わったことでなぜ死んだかは不明 何もしてないのに壊れた
  7. Copyright © M&A Cloud All rights reserved. なぜ死んだのか なぜ死んだのか •

    LaravelのQueueはJobというクラスをPHPシリアライズした文字 列のメッセージキューでやり取りする • Workerではメッセージから取得した文字列をアンシリアライズ することでPHPのコードとして実行する • アンシリアライズが失敗
  8. Copyright © M&A Cloud All rights reserved. なぜアンシリアライズが失敗するのか なぜアンシリアライズが失敗するのか 原因が不明だがシリアライズ前にスペースが2つ連続で含まれる文字

    列が、メッセージキューから取得されたあとのメッセージではスペー スが1つに纏められている事象があった (SQSからEBWorkerがHTTPに変換する際)
  9. Copyright © M&A Cloud All rights reserved. コードで説明 PHPシリアライズされた状態の文字列

  10. Copyright © M&A Cloud All rights reserved. コードで説明 アンシリアライズするともとのインスタンスに戻る

  11. Copyright © M&A Cloud All rights reserved. コードで説明 12345678910111213 型:値

  12. Copyright © M&A Cloud All rights reserved. コードで説明 アンシリアライズに失敗するとfalseとなる 11

    実際の文字数と異なる
  13. Copyright © M&A Cloud All rights reserved. わけがわからない上に影響範囲が大きい 対応

  14. Copyright © M&A Cloud All rights reserved. 「文字列全部Base64エンコードしちゃお」 対応

  15. Copyright © M&A Cloud All rights reserved. Base64 Base64 Base64は、データを64種類の印字可能な英数字のみを用いて、それ以外の文字

    を扱うことの出来ない通信環境にてマルチバイト文字やバイナリデータを扱う ためのエンコード方式である。 MIMEによって規定されていて、7ビットのデータしか扱うことの出来ない電子 メールにて広く利用されている。具体的には、A–Z, a–z, 0–9 までの62文字 と、記号2つ (+, /)、さらにパディング(余った部分を詰める)のための記号と して = が用いられる。 この変換によって、データ量は4/3(約133%)になる[1]。また、MIMEの基準 では76文字ごとに改行コードが入るため、この分の2バイトを計算に入れると データ量は約137%となる[2]。 出典: フリー百科事典『ウィキペディア(Wikipedia)』
  16. Copyright © M&A Cloud All rights reserved. Base64 Base64 Base64は、データを64種類の印字可能な英数字のみを用いて、それ以外の文字

    を扱うことの出来ない通信環境にてマルチバイト文字やバイナリデータを扱う ためのエンコード方式である。 MIMEによって規定されていて、7ビットのデータしか扱うことの出来ない電子 メールにて広く利用されている。具体的には、A–Z, a–z, 0–9 までの62文字 と、記号2つ (+, /)、さらにパディング(余った部分を詰める)のための記号と して = が用いられる。 この変換によって、データ量は4/3(約133%)になる[1]。また、MIMEの基準 では76文字ごとに改行コードが入るため、この分の2バイトを計算に入れると データ量は約137%となる[2]。 出典: フリー百科事典『ウィキペディア(Wikipedia)』 スペース撲滅
  17. Copyright © M&A Cloud All rights reserved. __serialize/__unserializeを利用 __serialize/__unserializeを利用 •

    PHP7.4から追加されたマジックメソッドの __serialize/__unserializeを利用 • 幸いにも弊社アプリケーションでは文字列をプリミティブではな くStringValue型という独自クラスで定義していたので、このク ラスに対してマジックメソッドを追加 ※7.4以前なら__sleep/__wakeupが代用できる
  18. Copyright © M&A Cloud All rights reserved. __serialize/__unserializeを利用

  19. Copyright © M&A Cloud All rights reserved. __serialize/__unserializeを利用

  20. Copyright © M&A Cloud All rights reserved.

  21. Copyright © M&A Cloud All rights reserved. まとめ まとめ •

    メッセージングシステムを利用するときはPHPシリアライズの文字 列ではなくJSON形式のような汎用的な形式が良いと思う! ◦ とはいえスペースが消えちゃうのはよくわからん • プリミティブな値ではなくラッパーした型を使っているとこういう ケースで助かるぞ! • マジックメソッドありがとう!
  22. Copyright © M&A Cloud All rights reserved. Thank you for

    watching :)