$30 off During Our Annual Pro Sale. View Details »

面倒なのは嫌なのでコンテナのマネージドサービスの極振りしたいと思います。

n1215
PRO
March 25, 2023

 面倒なのは嫌なのでコンテナのマネージドサービスの極振りしたいと思います。

2023/03/25(土) PHPerKaigi 2023 の登壇資料です。

n1215
PRO

March 25, 2023
Tweet

More Decks by n1215

Other Decks in Programming

Transcript

  1. for PHPerKaigi 2023
    面倒なのは嫌なのでコンテナのマネージドサービスに
    極振りしたいと思います。
    2023年3月25日 (土) 株式会社Nextat 中榮健二
    Nextat Inc. 1

    View Slide

  2. 自己紹介
    from 京都
    - 中榮健二 (なかえけんじ)
    - twitter: @n_1215 
    - 株式会社Nextat 取締役
    - Webアプリのバックエンドがメインのはず。インフラ専任ではない
    - ここ最近はWebフロントエンドやUnityを使ってクライアント側をやったり
    PHP以外の仕事も増加
    Nextat Inc. 2

    View Slide

  3. 発表概要
    1. 本発表の前提
    2. コンテナベースのPaaSの特徴と具体例
    3. PHPとコンテナベースのPaaS
    4. DBサーバの選択肢
    5. 頻出処理におけるサービス・機能の選択
    6. デプロイ周りの話
    7. その他トピック
    8. まとめ
    Nextat Inc. 3

    View Slide

  4. 1. 本発表の前提
    Nextat Inc. 4

    View Slide

  5. 想定する聴衆の例
    インフラ保守のコスト(人的コストを含む)を減らしたい
    楽にWebアプリケーションをデプロイしたい
    AWS App RunnerやGoogle Cloud Runに興味はあるが手は出していない
    Herokuからの移行先を探している
    Amazon ECSは業務で利用しているが設定が大変なので他の方法を探している
    HTTP APIの実装にAWS Lambdaを使ったことがあるが辛みがあった
    Nextat Inc. 5

    View Slide

  6. PaaS(Platform as a Service) と
    CaaS(Container as as Service)
    Cloud Run や App RunnerもCaaS(Container as a Service)と呼んで良いのでは
    と思っていたが、Google Cloudのドキュメントによると
    https://cloud.google.com/learn/paas-vs-iaas-vs-saas?hl=ja
    CaaS: GKE
    PaaS: GAE、Cloud Run
    とのこと
    Nextat Inc. 6

    View Slide

  7. 極振りしたい コンテナのマネージドサービス とは
    本資料でメインに扱う コンテナのマネージドサービス は
    DockerfileやBuildpacks(後述)の設定だけすれば良い感じにコンテナとして
    Webアプリを動かしてくれるサービス
    コンテナベースのPaaS
    と分類するのが良さそう
    CaaS は
    Container Runtime as a Service
    くらいのニュアンスかなと思ってい
    たが、
    Container Orchestrator as a Service
    のほうが近そう
    Amazon ECSはCaaSで良い?
    セッションのタイトルにCaaSと入れてなくてよかった
    Nextat Inc. 7

    View Slide

  8. そもそもコンテナとは
    仮想化の一種
    OSは共有し、ハードウェアは仮想化しない
    ハイパーバイザ型の仮想化(ex. Hyper-V、VirtualBox)に比べ軽量でリソー
    ス利用の効率が良い
    ホストOSの他のプロセスからの隔離+リソース制限
    ポータビリティ(可搬性)が高い
    Build, Ship and Run Any App, Anywhere
    by Docker
    本番環境に近い構成をローカル環境で再現しやすい
    Nextat Inc. 8

    View Slide

  9. https://academy.gmocloud.com/vps/20211228/13893 より
    Nextat Inc. 9

    View Slide

  10. Open Container Initiative
    https://opencontainers.org/
    コンテナランタイム・コンテナイメージフォーマットの標準策定のため設立
    Linux Foundationプロジェクトの一つ
    コンテナランタイムの例
    runc: 広く利用されているリファレンス実装。containerd(を利用する
    Docker)やcri-oのランタイムとして利用
    kata-runtime: 軽量VMで高い安全性を志向するKata Containersのランタイ

    runsc: 高い安全性を志向するGoogleのgVisorのランタイム
    Nextat Inc. 10

    View Slide

  11. Dockerイメージ と OCIイメージ
    OCIの策定した仕様に準拠するコンテナイメージをOCIイメージと呼ぶ
    OCIイメージであればOCI準拠のコンテナランタイムで動かせる
    OCIイメージというインターフェースへの依存
    OCIの標準化にはDockerが大きく貢献
    資料内ではDockerイメージという用語よりコンテナイメージという用語を多く使いま
    すが、OCIイメージのことだと思ってください
    蛇足: OCI だけで検索するとOracleのクラウドがヒットしやすいので注意
    Nextat Inc. 11

    View Slide

  12. Build/Share/Run
    元々Build/Ship/Runだったが最近は Ship → Share としている模様
    https://www.docker.com/
    Build: コンテナイメージの作成
    コンテナのビルドツールを利用
    Share: コンテナイメージの保管と共有
    コンテナレジストリを利用
    脆弱性検証なども含むが今回は触れない
    Run: コンテナとして動作
    コンテナランタイムを利用
    今日はこの3つのステージのうち、BuildとRunの話がメイン
    Nextat Inc. 12

    View Slide

  13. コンテナをビルドするツールの選択肢
    OCIイメージは必ずしもDockerfileを使ってビルドされるとは限らない
    Cloud Native Buildpacks(以下Buildpacks or CNBとも呼称)
    Bazel: https://bazel.build/?hl=ja
    Jib(Java用): https://github.com/GoogleContainerTools/jib
    Nixpacks(Railwayのプロジェクト): https://nixpacks.com/docs/getting-
    started
    本日紹介するコンテナ系マネージドサービスのデプロイパイプラインはDockerfileな
    いしBuildpacksに対応している場合が多い
    Nextat Inc. 13

    View Slide

  14. Cloud Native Buildpacks
    https://buildpacks.io/
    アプリケーションのソースコードからOCIイメージを作成するツール
    ベストプラクティスが多すぎる Dockerfile からの解放
    セキュアなイメージを共有したい
    PHPの場合はHerokuのBuildpacksが使いやすい
    HerokuのBuidlpacksからCNBは標準化されたので元祖とも言える
    Herokuで使われているイメージが手元でも再現できる
    GCPでもGoogle Cloud BuildpacksとしてBuildpacksをサポートしている
    ただしPHPには非対応
    Nextat Inc. 14

    View Slide

  15. HerokuのBuildpackでLaravelアプリのイメージを作成する例
    Procfile: 起動処理はnginxとApacheを選択可
    web: heroku-php-nginx -C nginx.conf public
    nginx.conf: nginxの設定
    location / {
    try_files $uri @rewriteapp;
    }
    location @rewriteapp {
    rewrite ^(.*)$ /index.php$1 last;
    }
    Nextat Inc. 15

    View Slide

  16. project.toml: Buildpacksの設定ファイル
    [project]
    id = "my-laravel-app"
    name = "My Laravel Application"
    version = "1.0.0"
    [build]
    exclude = [
    "/README.md",
    ".git",
    "/vendor",
    "/node_modules"
    ]
    builder = "heroku/buildpacks:20"
    [[build.buildpacks]]
    uri = "heroku/php"
    [[build.buildpacks]]
    uri = "heroku/procfile"
    [[build.buildpacks]]
    uri = "heroku/nodejs"
    Nextat Inc. 16

    View Slide

  17. composer.json: PHPのバージョンとPHP拡張はcomposer.jsonから読み取って自動
    で設定される
    {
    "require": {
    "php": "8.2.0",
    "ext-apcu": "*"
    }
    }
    package.json: ビルド時にJSのアセットを生成
    {
    "scripts": {
    "heroku-postbuild": "npm run production"
    },
    }
    Nextat Inc. 17

    View Slide

  18. packコマンドを打つと 指定した名前のコンテナイメージが生成される
    pack build my-laravel-app
    docker runでコンテナを起動できる
    docker run --rm -e PORT=8080 -p 8080:8080 my-laravel-app
    Dockerfileの場合より少し記述は散らばるが、PHP拡張の依存までは気にする必
    要がなくなる
    ext-grpc
    が入らない、ARM対応していないなどの一部制限はある
    参考
    Dockerfile不要!Cloud Native BuildpacksでLaravelアプリケーションのコンテ
    ナイメージを作成する
    https://nextat.co.jp/staff/archives/266
    Nextat Inc. 18

    View Slide

  19. 2. コンテナベースのPaaSの特徴と具体例
    Nextat Inc. 19

    View Slide

  20. PaaS(Platform as a Service)の良いところ
    サービス提供側にサーバ・ミドルウェアの管理を任せられる
    スケーリングも任せられる
    特にGAE/SEはスケーラビリティが高い
    アプリケーション開発に集中できる
    Nextat Inc. 20

    View Slide

  21. 非コンテナベースのPaaSの辛いところ
    運用の労力低減と自由度の高さはトレードオフ
    PHPバージョンの自由度が低い
    GAE: なかなかPHPのバージョンが上がらなかった時期がある
    PHP拡張の自由度が低かったり扱いがわかりにくかったり
    Heroku: Buildpackだとext-grpcが使えない
    GAE: ext-sodiumの使い方が難解
    独自の制限
    GAE: 1ディレクトリの下に1000ファイルまで
    ローカル開発での環境再現に難あり
    インフラの費用自体はIaaS(VM)に比べて高くなりがち
    ※ 人的コストまで入れて比較すべき
    Nextat Inc. 21

    View Slide

  22. FaaS(Function as a Service)の良いところ
    イベントドリブンなアーキテクチャに適している
    リクエストを処理している時間だけに課金
    無料枠も大きい場合が多い
    スケーラビリティが高い(スパイクにとても強い)
    スケーラビリティ重視の場合やインフラコスト削減への強い要望がある場合に
    AWS縛りの中のLambdaは強力な選択肢
    ECS/FargateやApp Runnerはスケールの初速が遅い+完全にはゼロスケー
    ルしない(待機状態でも課金される)
    Nextat Inc. 22

    View Slide

  23. FaaS(+PHP)の辛いところ
    普段慣れているアプリケーション開発の構成を変える必要がある
    FaaS特有の知識が必要になるので必要なインフラ知識が増える
    ローカルでの再現に難あり
    FaaSごとに統一性がない
    AWS Lambda
    PHPには公式では非対応なのでカスタムランタイムを使う必要がある
    Bref (https://bref.sh/)を使えば楽ができるが、一つ間接層が増える
    Google Cloud Functions
    PHPに公式対応しているが、GAEと同じくPHPバージョンとPHP拡張の自由度低
    Nextat Inc. 23

    View Slide

  24. コンテナベースのPaaS
    非コンテナベースのPaaSとCaaSの間くらいの立ち位置
    非コンテナベースのPaaSより自由度は高いが、コンテナやミドルウェアの存
    在は意識する必要がある
    CaaSほど設定が複雑ではないが自由度は低い
    コンテナイメージを自由にカスタマイズできる
    PHPのバージョンやPHP拡張を自由にコントロール
    コンテナを動かすために裏側で使われる技術スタックは様々だが、コンテナイメ
    ージというインターフェースは共通
    コンテナ依存なのでローカル環境での再現性が高い
    Amazon ECSのサービスのようにコンテナを複数まとめた単位では扱えない場合
    が多いので、コンテナのサイドカーなどは使えない
    Nextat Inc. 24

    View Slide

  25. 例1 Heroku
    老舗のPaaSとして知られるが、裏はコンテナベース
    HerokuのBuildpackはCloud Native Buildpacksに準拠している
    Dockerイメージとコンテナレジストリを用いたデプロイも可能
    https://devcenter.heroku.com/ja/categories/deploying-with-docker
    Nextat Inc. 25

    View Slide

  26. 例2 Render
    https://render.com/
    Buildpacksには対応していないがDockerfile対応
    リージョンは今の所シンガポールが日本から近い。東京対応予定はある様子
    https://feedback.render.com/features/p/tokyo-region
    Nextat Inc. 26

    View Slide

  27. 例3 Fly.io
    https://fly.io/
    アクセスしたユーザに近いリージョンでサービス(コンテナ)を実行するという
    一風変わったPaaS。CDNに近い発想
    Buildpacks・Dockerfile対応
    パブリックなDockerイメージの指定可
    AWS Lambda/Fargateと同じFirecracker VMを利用 https://firecracker-
    microvm.github.io/
    Nextat Inc. 27

    View Slide

  28. 例4 Railway
    https://railway.app/
    Buildpacks・Dockerfile・Nixpacks対応
    管理画面のUIがよく出来ているとの評判
    リージョンはUSのみだがAsia対応予定はある模様
    https://blog.railway.app/p/scaling-railway-roadmap
    Nextat Inc. 28

    View Slide

  29. 例5 Koyeb
    https://www.koyeb.com/
    コンテナレジストリからのデプロイに対応
    Buildpacks対応
    まだ発展途上でリージョンも少ないが複数リージョンが選択できるなど面白そう
    裏は Firecracker VM + Nomad + Kuma
    Nextat Inc. 29

    View Slide

  30. 例6 Cloud Run
    https://cloud.google.com/run?hl=ja
    Dockerfile対応
    Google Cloud BuildpacksというCNB準拠な仕組みがあるがPHPは非対応
    実体はマネージドKnative: https://cloud.google.com/knative?hl=ja
    FaaSと同じく料金含めゼロスケールするのが特徴
    カナリアリリースなど機能が充実
    Nextat Inc. 30

    View Slide

  31. 例7 AWS App Runner
    https://aws.amazon.com/jp/apprunner/
    マネージドランタイムはPHP 8.1に対応。当初ビルトインウェブサーバを使って
    いたが最近nginx/Apache+PHP-FPM構成にも対応
    https://github.com/aws/apprunner-roadmap/issues/157
    ECRからのデプロイを選択すればコンテナイメージを自由にカスタムできる
    裏は ECSと同じFargate
    比較的新しいサービスだが、最低限の機能は揃ってきた
    PHPerKaigi 2023 でも 3/23(木) day0 に @seike460 さんのセッションあ

    https://speakerdeck.com/seike460/my-continued-use-of-aws-
    lambda-php-production-explores-the-potential-of-aws-app-runner
    Nextat Inc. 31

    View Slide

  32. 3. PHPとコンテナベースのPaaS
    Nextat Inc. 32

    View Slide

  33. PHPとコンテナベースのPaaS
    複数コンテナをまとめた単位で扱えないため、1コンテナでHTTPサーバとなる方
    が都合が良い
    1コンテナにWebサーバとPHP-FPM または Apache httpd + mod_phpと
    なることが多い
    前者は1コンテナ1プロセスの教えには反するが、Herokuで実績は十分ある
    使い分け基準の例
    APIサーバ専用 → オーバーヘッドが少ない Apache httpd + mod_php
    静的アセット配信も兼ねる → nginx + PHP-FPM
    速さが足りない → RoadRunner、Swoole、ReactPHP、AMPHP etc.
    ビルトインウェブサーバーは本番ではダメ絶対
    Nextat Inc. 33

    View Slide

  34. 1コンテナに複数プロセス
    ラッパースクリプトかプロセスマネージャ(supervisordなど)を利用する
    Run multiple services in a container
    https://docs.docker.com/config/containers/multi-service_container/
    HerokuのBuildpacksの場合
    nginx + PHP-FPM or Apache httpd + PHP-FPM をProcfileで指定
    それぞれ起動スクリプトが用意されている
    App RunnerのPHPマネージドランタイムの場合
    supervisordは自力で追加する形での対応。ラッパースクリプトによる方法も
    紹介されている
    https://docs.aws.amazon.com/ja_jp/apprunner/latest/dg/service-
    source-code-php.html
    Nextat Inc. 34

    View Slide

  35. 4. DBサーバの選択肢
    Nextat Inc. 35

    View Slide

  36. DBサーバをどうする?
    DBサーバのコストは全体に占める割合が比較的高いので重要
    自前管理は面倒なのでマネージドなサービスを使いたい
    PaaSのサービスはRDBMSやRedisにも対応していることが多い
    クラウドプロバイダのコンテナ系PaaSを使う場合は、同一プロバイダ内で済
    ませるのが一番楽
    外部のDBaaSを使うのも一手
    自由度の制限はあることに注意。特にPostgreSQL率が割と高い
    今回はNoSQL系DBの話はしません
    Nextat Inc. 36

    View Slide

  37. PaaS付属のRDB
    Render: PostgreSQL
    https://render.com/docs/databases
    Fly.io: PostgreSQL
    https://fly.io/docs/postgres/
    Railway: PostgreSQL / MySQL
    https://docs.railway.app/databases/postgresql
    https://docs.railway.app/databases/mysql
    Nextat Inc. 37

    View Slide

  38. クラウドプロバイダのマネージドRDBサービス
    AWS: Amazon RDS、Aurora、Aurora Serverless
    https://aws.amazon.com/jp/rds/
    https://aws.amazon.com/jp/rds/aurora/
    https://aws.amazon.com/jp/rds/aurora/serverless/
    GCP: Cloud SQL、AlloyDB for PostgreSQL、Cloud Spanner
    https://cloud.google.com/sql?hl=ja
    https://cloud.google.com/alloydb?hl=ja
    https://cloud.google.com/spanner?hl=ja
    DBをプライベートなVPCに配置する場合は追加で設定が必要
    App Runner: VPCエンドポイント、Cloud Run: サーバレスVPCアクセス
    Nextat Inc. 38

    View Slide

  39. DBaaS系の外部サービス
    外部のマネージドなDBサービスを利用する手もある
    サーバレスDB、Cloud Database Platformなどとも呼ばれる
    Koyebの記事: https://www.koyeb.com/blog/which-cloud-database-
    platform-to-choose-for-your-applications
    Nextat Inc. 39

    View Slide

  40. DBaaSの例
    Supabase Postgres
    https://supabase.com/docs/guides/database/overview
    Supabase自体は Backend as a Service
    DigitalOcean
    https://www.digitalocean.com/products/managed-databases
    DigitalOcean自体はDBaaSというよりはクラウドプロバイダ
    最寄りRegionはシンガポール
    Aiven(アイベン)
    https://aiven.io/ja
    MySQL、PostreSQL、 Redis、OpenSearch etc.
    AWS、Azure、GCP、DigitalOceanなどクラウドやリージョン間の移行が可

    Nextat Inc. 40

    View Slide

  41. DBaaSの例(続き)
    Crunchy Bridge
    https://www.crunchydata.com/products/crunchy-bridge
    PostgreSQL で有名な Crunchy Data
    AWS、Azure、GCP
    Neon
    https://neon.tech/
    マルチクラウドなマネージドPostgreSQL
    最寄りRegionはシンガポール
    Nextat Inc. 41

    View Slide

  42. NewSQL系のDBaaSの例
    https://ja.wikipedia.org/wiki/NewSQL
    従来のデータベースシステムのACID特性を維持しながら、オンライントランザク
    ション処理(OLTP)の作業負荷に対してNoSQLシステムのスケーラビリティを
    提供しようとするリレーショナルデータベース管理システムの一種である
    PlanetScale(MySQL互換)
    https://planetscale.com/
    YugabyteDB Managed(PostgreSQL互換)
    https://www.yugabyte.com/managed/
    CockroachDB serverless(PostgreSQL互換)
    https://www.cockroachlabs.com/get-started-cockroachdb/
    Nextat Inc. 42

    View Slide

  43. NewSQL系のDBaaSの例(続き)
    TiDB Cloud(MySQL互換)
    https://pingcap.co.jp/tidb-cloud/
    MySQL8系には未対応
    TiDBは日本でもソーシャルゲーム業界などで採用の兆し
    https://speakerdeck.com/cygames/zui-gao-nokontentu-wozhi-
    eru-cygamesnodetabesuji-shu-nojin-madetokorekara-ci-shi-dai-
    detabesu-tidb-nojian-zheng-wokai-shi-sitacygamesnoqu-rizu-mi
    注1: New SQL系のサービスはサービスによっては例えば auto incrementが連番
    にならない、主キーはUUIDv4推奨 など元のRDBMSにはない制限がある場合が
    ある
    注2: PaaSや同一クラウドプロバイダのDBサービスを使う場合に比べ、DBaaSは
    レイテンシの問題が出る場合があるので、利用時は実際に計測推奨
    Nextat Inc. 43

    View Slide

  44. Redis
    用途が多いのでとりあえず構成に入れておきがち
    セッションストア
    セッションストアにもRDBを使う手もあるが負荷が上がると厳しい
    キャッシュストア
    コンテナローカルなキャッシュでも良ければAPCuという手もある
    ロック(排他制御)
    これはRDBでもできる
    非同期処理時のメッセージのキューイング・Pub/Sub
    こちらもRDBでも代替可
    マネージドサービスで冗長構成にすると地味に料金が高い
    負荷が上がった時のスケーリングの辛み
    Nextat Inc. 44

    View Slide

  45. PaaS付属のRedis
    Redis®* | Render · Cloud Hosting for Developers
    https://render.com/docs/redis
    Redis | Railway Docs
    https://docs.railway.app/databases/redis
    The Redis database service uses the bitnami/redis:6.0 docker
    image.
    Nextat Inc. 45

    View Slide

  46. クラウドプロバイダのマネージドRedis
    AWS: ElastiCache for Redis
    https://aws.amazon.com/jp/elasticache/redis/
    AWS: Amazon MemoryDB for Redis
    https://aws.amazon.com/jp/memorydb/
    Redis互換 + 耐久性・高可用性
    GCP: Cloud Memorystore for Redis
    https://cloud.google.com/memorystore?hl=ja
    Redis Enterprise Cloud(AWS/GCP/Azure対応)
    https://redis.com/redis-enterprise-cloud/overview/
    Nextat Inc. 46

    View Slide

  47. DBaaSのRedis(サーバレスRedis)
    Upstash: Serverless Data for Redis® and Kafka®
    https://upstash.com/
    Fly.io は Upstash推奨の様子 https://fly.io/docs/reference/redis/
    日本リージョンあり(AWSのap-northeast-1)
    Momento(サーバレスキャッシュ)
    https://jp.gomomento.com/
    少しずれるが他のサービスがあまり見当たらなかったので紹介
    Redis互換のためのproxyがある模様 https://github.com/pelikan-
    io/pelikan/blob/main/src/proxy/momento/README.md
    Nextat Inc. 47

    View Slide

  48. 5. 頻出処理におけるサービス・機能の選択
    Nextat Inc. 48

    View Slide

  49. 5-1. 非同期処理(メッセージのキューイング)
    キューやPub/Subの仕組みを使ってその場で処理する必要のない処理や重い処理
    をバックグランドで実行
    レスポンスを早く返せる
    例)メール送信
    Push型とPull型の2種類の構成がある
    Nextat Inc. 49

    View Slide

  50. https://www.tencentcloud.com/document/product/406/4791 より
    Nextat Inc. 50

    View Slide

  51. Push型
    Consumer側でHTTPエンドポイントを用意するのが一般的
    メリット
    リアルタイム性
    コスト
    デメリット
    Pushした時点でConsumerが落ちていないことを要求
    リトライやデッドレターキューなどでカバーはできる
    Pushする側がConsumerについて知っている必要がある
    ProducerのほうがConsumerより性能が高い場合にあふれる可能性がある
    Nextat Inc. 51

    View Slide

  52. Pull型
    Consumer側がworkerを起動させてポーリングする
    メリット
    一時Consumerがダウンしていたとしてもメッセージが棄却されない
    Consumer側の処理性能が低い場合でも流量調整が必要ない
    デメリット
    リアルタイム性が低くなる場合あり
    Worker常駐のコスト
    ポーリング間隔の調整が必要な場合も
    Nextat Inc. 52

    View Slide

  53. 選択肢1) Redis Pub/Sub
    https://redis.io/docs/manual/pubsub/
    Redisを使ってPub/Subのメッセージングができる
    Redisを使った非同期処理ではよく採用されている
    Nextat Inc. 53

    View Slide

  54. 選択肢2) Redis Streams(Redis >= 5.0)
    https://redis.io/docs/data-types/streams/
    データを時系列に格納する追記用の データ構造
    Consumerが落ちていても後から参照できる
    データを取得して以降も揮発しない
    参考
    Redis Streams tutorial | Redis
    https://redis.io/docs/data-types/streams-tutorial/
    マイクロサービスを支えるメッセージング技術:Redis Streams
    https://zenn.dev/nitaking/articles/e5bdaa4605b637
    Redis Streamsを活用したイベントドリブンアーキテクチャの構築事例
    https://inside.dmm.com/articles/games-redis-cluster/
    Nextat Inc. 54

    View Slide

  55. 選択肢3) RDBのSKIP LOCKEDを使う
    PostgreSQL >= 9.5
    MySQL >= 8.0.1

    SKIP LOCKED
    が追加
    SELECT FOR UPDATE
    の際に別のトランザクションで行ロックされているレコードを除
    外する事が可能
    → キュー用途に使ってもデッドロックが起きない+パフォーマンスの向上が期待でき

    Nextat Inc. 55

    View Slide

  56. SKIP LOCKEDの参考
    MySQL :: MySQL 8.0.1: Using SKIP LOCKED and NOWAIT to handle hot
    rows
    https://dev.mysql.com/blog-archive/mysql-8-0-1-using-skip-locked-
    and-nowait-to-handle-hot-rows/
    What's new in PostgreSQL 9.5 - PostgreSQL wiki
    https://wiki.postgresql.org/wiki/What's_new_in_PostgreSQL_9.5#SKIP
    _LOCKED
    PostgreSQLのSKIP LOCKEDを使ってテーブルをキューとして使用する -
    Enjoy*Study
    https://blog.enjoyxstudy.com/entry/2017/09/10/000000
    Nextat Inc. 56

    View Slide

  57. 例) LaravelのキューのDBドライバー
    パフォーマンスに関しては最高ではないが、本番でも使えるレベルになっているとの
    こと
    I've tested the changes processing 516,783 jobs by 50 workers and it
    resulted no deadlocks.
    A production-ready database queue driver for Laravel - Diving Laravel
    https://divinglaravel.com/a-production-ready-database-queue-diver-
    for-laravel
    Nextat Inc. 57

    View Slide

  58. 選択肢4) PostgreSQLのLISTEN/NOTIFYを使う
    LISTEN
    /
    NOTIFY
    https://www.postgresql.org/docs/current/sql-listen.html
    https://www.postgresql.org/docs/current/sql-notify.html
    Pub/Subの仕組み
    参考
    PostgreSQL でメッセージキューイングを行う(LISTEN, NOTIFY)
    https://symfoware.blog.fc2.com/blog-entry-2519.html
    Do You Really Need Redis? How to Get Away with Just PostgreSQL
    https://spin.atomicobject.com/2021/02/04/redis-postgresql/
    Nextat Inc. 58

    View Slide

  59. 例) Symfony の Messengerコンポーネント
    トランスポート(≒メッセージの伝送路)として、DoctrineとPostgreSQLを使う設定
    が可能
    舞台裏では、SymfonyはPostgreSQLに組み込みの、高速で、スケーラブルで、
    トランザクションできる pub/sub システム(LISTEN/NOTIFY)を利用していま
    す。メッセージの保存先としてPostgreSQLの代わりにRabbitMQを使いたい場
    合は、RabbitMQの章を読んでみてください。
    参考
    非同期にする (Symfony 6.2 Docs)
    https://symfony.com/doc/6.2/the-fast-track/ja/18-async.html
    Nextat Inc. 59

    View Slide

  60. 選択肢5) クラウドプロバイダのマネージドサービス
    Amazon SQS (Pull型)
    https://aws.amazon.com/jp/sqs/
    Amazon SNS(Push型)
    https://aws.amazon.com/jp/sns/
    Cloud Pub/Sub(PushとPullを選択可)
    https://cloud.google.com/pubsub/docs/overview?hl=ja
    Cloud Tasks(Push型)
    https://cloud.google.com/tasks?hl=ja
    Cloud Tasks か Pub/Sub かの選択
    https://cloud.google.com/tasks/docs/comp-pub-sub?hl=ja
    Nextat Inc. 60

    View Slide

  61. 選択肢6) 自前のコンテナでサービスを立てる
    ※ あまりおすすめはしない
    RabbitMQ
    https://www.rabbitmq.com/
    Fly.ioのコミュニティでは試している方々がいた
    https://community.fly.io/t/rabbitmq-on-fly-io/5510
    Apache ActiveMQ
    https://activemq.apache.org/
    Nextat Inc. 61

    View Slide

  62. メッセージのConsumer
    Pull型の場合はキューワーカー用のコンテナを常駐させるのが基本
    Webアプリケーションからキューワーカーまで全部入りのコンテナにする手
    もあるがメモリとコンテナの常駐化が必要なことには注意
    Consumerの処理速度を上げるにはバッチ取得を使うかコンテナを増やす
    App Runnerは今の所は常駐設定がない(Lambdaを挟んでHTTPリクエスト
    を投げる構成は可能だが、この場合も実行時間上限がネック)
    Push型の場合は認証付きのHTTPエンドポイントを用意するのが手軽
    Webアプリケーションと同じコンテナを使える+スケーリングも楽
    Nextat Inc. 62

    View Slide

  63. PaaSのキューワーカー機能の例
    Background Workers | Render · Cloud Hosting for Developers
    https://render.com/docs/background-workers
    Cron and Queues · Fly Docs
    https://fly.io/docs/laravel/the-basics/cron-and-queues/
    単にワーカー用のコンテナを起動する
    Nextat Inc. 63

    View Slide

  64. 5-2. 定時処理
    選択肢1) 常駐コンテナでcronを動かす
    Cron and Queues · Fly Docs
    https://fly.io/docs/laravel/the-basics/cron-and-queues/
    選択肢2) PaaS 組み込みのスケジューラー
    Heroku Scheduler | Heroku Dev Center
    https://devcenter.heroku.com/ja/articles/scheduler
    Cron Jobs | Render
    https://render.com/docs/cronjobs
    Nextat Inc. 64

    View Slide

  65. 定時処理(続き)
    選択肢3) スケジューラー + HTTPエンドポイント
    Amazon EventBridge(API Destinations) + App Runner
    https://aws.amazon.com/jp/eventbridge/
    App Runnerの実行時間の上限が低い(120秒)のがネック
    Cloud Schduler + Cloud Run
    https://cloud.google.com/scheduler?hl=ja
    Cloud Runは実行時間が柔軟。デフォルト5分、最長60分
    選択肢4) スケジューラー + コンテナ起動
    Amazon EventBridge + ECS Task
    https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide
    /scheduled_tasks.html
    Cloud Schduler + Cloud Run Jobs
    https://cloud.google.com/run/docs/execute/jobs-on-schedule
    Nextat Inc. 65

    View Slide

  66. 定時処理(続き)
    スケジューラーを使う場合は常駐のコンテナは節約できるが、起動スケジュールの定
    義がPHPアプリの外部になるのをどう管理するかが問題になる
    例)Laravelのタスクスケジュール
    https://laravel.com/docs/10.x/scheduling
    use Illuminate\Console\Scheduling\Schedule;
    $schedule->command('emails:send')
    ->hourly()
    ->days([Schedule::SUNDAY, Schedule::WEDNESDAY]);
    Nextat Inc. 66

    View Slide

  67. 5-3. 画像やファイルのアップロード処理
    オブジェクトストレージ
    PaaSの対応
    Render
    Feature RequestsでPLANNEDとはなっているが2023年中は進展なさそう
    https://feedback.render.com/features/p/cloud-object-storage
    Deploy MinIO Object Storage to Fly.io · Fly Docs
    https://fly.io/docs/app-guides/minio/
    S3互換のMinIOをコンテナで立てる + Fly Volume Storage に永続化
    コンテナへの極振りっぷりが清々しい
    Nextat Inc. 67

    View Slide

  68. クラウドプロバイダのオブジェクトストレージのサービス
    Amazon S3
    https://aws.amazon.com/jp/s3/
    Google Cloud Storage
    https://cloud.google.com/products/storage?hl=ja
    Cloudflare R2
    S3互換、エグレス料金ゼロのオブジェクトストレージ
    https://www.cloudflare.com/ja-jp/products/r2/
    Nextat Inc. 68

    View Slide

  69. 6. デプロイ周りの話
    Nextat Inc. 69

    View Slide

  70. デプロイパイプライン
    マネージドの場合
    ほとんどソースコードだけを気にしていれば良い
    せいぜいDockefileないしCloud Native Buildpacksの設定のみ
    App RunnerのマネージドランタイムやCloud RunのGoogle Cloud
    Buildpacksを用いたデプロイもこちら
    自前の場合
    デプロイスクリプトないしビルド設定ファイルを書く
    コンテナイメージをビルドしてレジストリにプッシュする処理がメイン
    App Runner: AWS CodeBuild/CodePipeline + Elastic Container
    Registry
    Cloud Run: Cloud Build + Artifact Registry
    Nextat Inc. 70

    View Slide

  71. デプロイパイプラインへの介入
    DBのマイグレーションなど、デプロイ時に行いたい処理はあるもの
    自前定義の場合はコマンドを直接書けば済む
    デプロイパイプラインがマネージドの場合、苦し紛れの設定としてはコンテナの
    起動処理に入れこむ手もあるが……
    Nextat Inc. 71

    View Slide

  72. リリースコマンド
    Fly.ioはrelease_commandという設定がある
    https://fly.io/docs/reference/configuration/#run-one-off-commands-
    before-releasing-a-deployment
    [deploy]
    release_command = "php artisan migrate"
    RenderはリリースコマンドのFeature RequestがあるがPLANNED
    https://feedback.render.com/features/p/release-phase-script
    Nextat Inc. 72

    View Slide

  73. コマンドを実行するその他の方法
    SSH接続などを介してコンテナでコマンドを実行できる場合もある
    無料プランでサポートされていない場合もあるので注意

    Connecting with SSH | Render
    https://render.com/docs/ssh
    Fly sshコンソール
    https://fly.io/docs/flyctl/ssh-console/
    fly ssh console -C "php /var/www/html/artisan migrate --force"
    Nextat Inc. 73

    View Slide

  74. コマンドを実行するその他の方法(続き)
    ECS Task、Cloud Run Jobsなどでコンテナを実行
    Cloud RunのDBマイグレーションどうする問題にCloud Runジョブで対処す
    る - Qiita
    https://qiita.com/okonomi/items/b885c22e3dae4153f67d
    HTTPエンドポイントから実行
    定時処理同様に、DBマイグレーションコマンドを実行できる認証ありの
    HTTPエンドポイントを生やしておく手もある
    デプロイと別タイミングでマイグレーションを実行する場合は、Feature Flagなどデ
    プロイとリリースのタイミングをずらす仕組みを使うと安全
    デプロイ → DB
    マイグレーション →
    フラグを有効化して新機能リリース
    Nextat Inc. 74

    View Slide

  75. 7. その他トピック
    Nextat Inc. 75

    View Slide

  76. プライベートサービスの構成
    アクセス元の制限やユーザーが直接アクセスしないサービスの構成に利用
    Private Services | Render · Cloud Hosting for Developers
    https://render.com/docs/private-services
    AWS App Runner が Amazon VPC 内のプライベートにアクセス可能なサービ
    スのサポートを開始
    https://aws.amazon.com/jp/about-aws/whats-new/2022/11/aws-app-
    runner-supports-privately-accessible-services-amazon-vpc/
    プライベート ネットワークと Cloud Run
    https://cloud.google.com/run/docs/securing/private-networking?
    hl=ja
    Nextat Inc. 76

    View Slide

  77. 静的サイトの配信
    極振り からは少し外れるが、静的サイトの配信をしたい場合はコンテナにこだわらな
    いほうが良い場合がある
    PaaS付属の静的サイトホスティング機能
    Fly.ioはGoの静的アセット用Webサーバをコンテナで立てるという極振り
    オブジェクトストレージ + CDN
    S3 + CloudFront
    Cloud Storage + Cloud CDN
    Cloudflare R2 + Workers
    外部の静的サイトホスティングサービス
    Cloudflare Pages、Firebase Hosting、GitHub Pages etc.
    Nextat Inc. 77

    View Slide

  78. WebSocketやHTTP/2、gRPC対応
    サポート状況はまちまちなので使う予定がある場合は選定時に調べると良い
    Cloud Run: サポート済
    https://cloud.google.com/blog/ja/products/serverless/cloud-run-gets-
    websockets-http-2-and-grpc-bidirectional-streams
    App Runner: 未サポート
    https://github.com/aws/apprunner-roadmap/issues/13
    https://github.com/aws/apprunner-roadmap/issues/77
    Fly.io: サポート済
    https://fly.io/blog/websockets-and-fly/
    https://fly.io/docs/app-guides/grpc-and-grpc-web-services/
    Nextat Inc. 78

    View Slide

  79. ARM対応
    Apple Silicon搭載Macの登場でコンテナのポータビリティに若干の疑問符
    今回資料で取り上げたサービスはARM対応していないはずなので、手元の環境と
    差異が出る可能性がある
    今回対象ではないがAWS FargateはLinux/ARMに対応(Graviton2)してお
    り、ARMのほうが時間あたりの価格は安い
    https://aws.amazon.com/jp/fargate/pricing/
    裏が同じFargateのApp Runnerは早めに対応しそうな気はする
    https://github.com/aws/apprunner-roadmap/issues/98
    Nextat Inc. 79

    View Slide

  80. 8. まとめ
    Nextat Inc. 80

    View Slide

  81. まとめ
    コンテナベースのPaaSは従来のPaaSとCaaSの中間くらいのサービス
    コンテナイメージというインターフェースに依存する事で移植性・PHP実行環境
    の柔軟性・エコシステムの有効活用が期待できる
    PHPでもコンテナベースのPaaSと各種マネージドサービスを組み合わせて運用コ
    ストを下げていこう
    主観によるおすすめ度
    現状でのおすすめはCloud Run。「Cloud Runはいいぞ」
    次点にUIが優しく機能も一通り揃ったRender
    Fly.ioはやや玄人好み。コンテナへの極振りにかけてはお前がナンバーワンだ
    App Runnerも最近改善が目覚ましい。後は常駐のワーカーに対応すればな
    んとでもなる
    Nextat Inc. 81

    View Slide

  82. PR: ITエンジニアを募集しています
    株式会社Nextat https://nextat.co.jp
    受託開発
    業務システム、ECサイト、スマホアプリ、VR...
    本社は京都ですが、東京・名古屋・北海道・島根などフルリモート勤務実績あり
    設計の話に付き合ってくれる方大歓迎!
    Nextat Inc. 82

    View Slide

  83. ご清聴ありがとうございました
    Nextat Inc. 83

    View Slide