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

7年間運用したソーシャルゲームをAmazon EC2構成からAmazon ECS構成へと乗り換えた話

7年間運用したソーシャルゲームをAmazon EC2構成からAmazon ECS構成へと乗り換えた話

YAPC2022での発表スライドです

こもじゅん

January 29, 2025
Tweet

More Decks by こもじゅん

Other Decks in Programming

Transcript

  1. 1, Amazon Linux のサポート終了 EC2 上で利用しているOS のサポートが2020 年末に終了するため 何かしら手を打たなければならなかった 後継OS

    Amazon Linux2 への乗り換えという選択肢もあるが… https://aws.amazon.com/jp/blogs/news/update-on-amazon-linux-ami-end-of-life/ 16
  2. Perl 5.26 での変更点 特にテストコードが影響を受けた https://perldoc.jp/docs/perl/5.26.0/perl5260delta.pod perl バイナリは @INC にパスのデフォルト集合を含んでいます。歴史的に、汚染モード (perl

    - T) が有効でない限り、最終的なエントリとして カレントディレクトリ (".") も含んでいまし た。 これは便利ですが、セキュリティ上の問題がありました: 例えば、 カレントディレクト リが(/tmp のように) 信頼できない場合、 スクリプトが追加のモジュールを読み込もうとする と、そのディレクトリの下から コードを読み込んで実行する可能性があります。 v5.26 から、"." は汚染モードの場合だけではなく、 常にデフォルトで 除去されるようになり ました。 これはモジュールのインストールとスクリプトの実行に大きな影響を与えます。 use t::Util; use strict; 1 use warnings; 2 use utf8; 3 4 use Test::More; 5 ... 6 24
  3. @inc のドットに頼ったモジュールはそう多くなかったので、引っ越して対応 Before After https://perldoc.jp/docs/perl/5.26.0/perl5260delta.pod @inc からドットが除去されたことによるテストの問題を修正するとき、 @inc にドットを再挿 入するのは慎重に行うべきです、

    これも実行時コードの実際の問題を抑制するかもしれない からです。 可能な限り、明示的な絶対/ 相対パスを使うという前述した手法を適用するか、 必要なファイルをサブディレクトリに再配置して、代わりに そのサブディレクトリを @inc に 追加することを勧めます。 /repository_root |--t |--Util.pm |--testa.t |--testb.t /repository_root |--t |--lib | |--t | |--Util.pm |--testa.t |--testb.t perl -Ilib -It/lib 25
  4. Perl 5.24 での変更点 こういうのがダメ https://perldoc.jp/docs/perl/5.24.0/perl5240delta.pod (autoderef 機能は取り除かれました) 実験的な autoderef 機能

    (push, pop, shift, unshift, splice, keys, values, each をスカラ引数で呼び出せ るようにする) は失敗と 判断されました。 これは削除されました; この機能を use しようとす ると ( または以前は 引き起こされていた experimental::autoderef 警告を無効にしようとすると) 例外が発生するようになりました。 my $arrayref = [1,2,3]; while (my $num = shift $arrayref) { # NG! ... } 27
  5. @ をつけて回る作業 ↓ my $item_dic = { one => "hoge",

    two => "fuga", three => "piyo", }; for my $item (keys $item_dic) { # NG! ... } for my $item (keys @$item_dic) { # OK my $item_dic = { 1 one => "hoge", 2 two => "fuga", 3 three => "piyo", 4 }; 5 6 ... 7 } 8 28
  6. 長いときはpostderef 機能に積極的に頼った ↓ https://perldoc.jp/docs/perl/5.24.0/perl5240delta.pod 接尾辞デリファレンスは実験的ではなくなりました postderef 機能と postderef_qq 機能を使っても警告が発生しなくなりました。 以前使われてい

    た、experimental::postderef 警告カテゴリを無効にしている 既存のコードはそのまま動作しま す。 postderef 機能は何の効果もありません; 全ての Perl コードは、スコープ内でどの機能が宣 言されているかに関わらず、接尾辞デリファレンスを使えます。 5.24 機能バンドルは postderef_qq 機能を含むようになりました。 my $arrayref_by_name = { one => [2,3,4], two => [5,6,7], }; while (my $num = shift $arrayref_by_name->{one}){ # NG! ... } while (my $num = shift $arrayref_by_name->{one}->@*){ # postderefに頼る my $arrayref_by_name = { 1 one => [2,3,4], 2 two => [5,6,7], 3 }; 4 5 ... 6 } 7 29
  7. Perl 5.18 ハッシュのランダム化のあおりを受ける keys や values を使って取り出した配列を使ってfor 文を回すような箇所で、 配列の順番に依存したテストが落ちていた https://perldoc.jp/docs/perl/5.18.0/perl5180delta.pod#Hash32randomization

    Perl のハッシュ関数が使う種はランダムになりました。 これは、keys(), values(), each() のよう な関数が返すキー/ 値の 順序は実行毎に異なるということです。 my %tests = ( testa => sub { return "aaa" }, testb => sub { return "bbb" }, ); my @expected = ["aaa", "bbb"]; for my $test (values %tests) { is, $test(), shift @expected; # testa から実行されるとは限らない! } 31
  8. 2 階建て作戦 base イメージとapp イメージに分ける 夜中に依存パッケージ、モジュール、ツール類をbase イメージでインストール リリース用ブランチへのコミットがある度、アプリケーションコードをコンテナにコピー する Dockerfile.base

    Dockerfile 運用上必要な箇所のみにコンテナイメージビルドの時間をかける FROM perl:5.30.0-buster RUN apt-get install 必要なソフトウェア ... $ docker build -t app:base . FROM app:base COPY ./ /home/user/repo/ ... $ docker build -t app . 43
  9. CloudWatch Event( 今はEventBridge) + SQS + sqsjkr 作戦 CloudWatch Event:

    定刻のイベント発火をマネジメントサービス化 SQS: 発火したジョブをキューイング sqsjkr: SQS からジョブを取得し実行する( 排他制御機能があり、冗長化可能) https://techblog.kayac.com/2017/04/10/090000 https://github.com/kayac/sqsjkr 48
  10. ぼくらの甲子園! ポケットでは… crontab.txt cron 書式のテキストファイルで管理している テキストを解析して日時や内容の整合性をチェックするテストが作り込まれている 100 以上のエントリがあるのでCloudWatch Event の上限に引っかかる

    運用上、頻繁に書き換える必要がある このフォーマットは維持したい… 10 00 * * * perl script/batch_aaa.pl 12 00 * * * perl script/batch_bbb.pl 16 00 * * * perl script/batch_ccc.pl ... 49
  11. sqsjfr + SQS + sqsjkr 作戦 sqsjfr: crond と同様にスケジューラの役割を果たし、実行すべきジョブをSQS に送り込む

    SQS FIFO キュー: 同一メッセージを削除しながらジョブをキューイングする sqsjfr: SQS からジョブを取得し実行する SQS FIFO キューの重複削除機能によって、sqsjfr の冗長化ができる sqsjfr がcron 書式を解釈できるためcron 書式がそのまま使える! https://github.com/kayac/sqsjfr 51
  12. 66