はじめに
株式会社Retail AI X AdventCalender2022の 12 日目の記事です。
昨日は@broccolibroccolibroccoli さんの『デザインチームを立ち上げた話』でした。
自己紹介
Retail AI XのSREチームに所属しています。
直近の仕事内容はFlutter、Android Java、Objective-C、GCPのインフラです。
IoT、金融、基幹システム、WEB・・・色々幅広くやっている会社です。
詳細を聞きたい方や興味がある方は、以下を参照下さい。
会社HP:https://www.retail-ai.jp/
採用ページ:https://recruit.jobcan.jp/retail-ai/
目的
会社のメディアをWordPressで運営しています。
その新着記事をメールマガジンやLINE、アプリなどの媒体で告知を行うのですが、登録メディア数を合わせると数十万になります。
メール配信やLINE通知後、すぐにアクセスする人が0.1%だとしても数百〜数千の同時接続のアクセスを捌く必要があります。
このパルス(バルス)的なアクセスを現状捌き切れずに503エラーが出てしまう状況です。
CloudCDNを前段に置いてGCE(GoogleComputeEngine)1台にて動かしているのですが、静的ファイルのキャッシュのみで動的ページはキャッシュされずにサーバーに負荷をかけています。
構成
GCE:CentOS7、PHP8.0
CloudSQL:MySQL8
GCS、CloudCDN
GCEにはgcsfuseを使用してGCSディレクトリをマウントし、メディア系ファイルをアップロードしています。
データベースは現在接続中のCloudSQLをそのまま使用し、Cloud SQL Auth Proxyを使用してCloud Runを接続します。
以下に今回作成したWordPressのDockerfile(一部抜粋したもの)です。
FROM centos:centos7.9.2009
EXPOSE 8080
RUN rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 && \
yum -y update && \
yum clean all && \
localedef -f UTF-8 -i ja_JP ja_JP.UTF-8 && \
ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
ENV LANG="ja_JP UTF-8" \
LANGUAGE="ja_JP:ja" \
LC_ALL="ja_JP.UTF-8" \
TZ="Asia/Tokyo"
RUN yum -y install epel-release; yum clean all
# install php8
RUN yum install -y https://rpms.remirepo.net/enterprise/remi-release-7.rpm; yum clean all
RUN yum install -y yum-utils centos-release-scl
RUN yum-config-manager --disable 'remi-php*'
RUN yum-config-manager --enable remi-php80
RUN yum -y install php php-xml php-xmlrpc php-pecl-apcu php-mbstring php-gd php-json \
php-pdo php-mysqlnd php-soap php-intl php-pear
# install mysql client
RUN yum remove mariadb-libs
RUN rpm -ivh https://dev.mysql.com/get/mysql80-community-release-el7-2.noarch.rpm
RUN rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022
RUN yum install -y mysql-community-client
# install python3.8
RUN yum install -y rh-python38 rh-python38-python-devel rh-python38-python-config
RUN cat /opt/rh/rh-python38/enable >> /root/.bashrc
# default python3
ENV PATH /opt/rh/rh-python38/root/bin:$PATH
# supervisord
RUN pip install Flask==2.0.2 gunicorn==20.1.0 supervisor
ADD (後述するsupervisord.conf) /etc/supervisord.conf
CMD ["/opt/rh/rh-python38/root/usr/local/bin/supervisord","-n","-c","/etc/supervisord.conf"]
CloudRunでは「1つのイメージに対し、1つのポートを設定する」ことしかできません。
https://cloud.google.com/run/docs/container-contract#port
しかしWordPressを起動させるには最低WEBサーバーのポート(80 or 443)とMySQLのポート(3306)が必要になってきます。
supervisord
http://supervisord.org/
子プロセスをメモリ上に作成して、常駐・監視等行い、要求に応じて処理を行います。
supervisord.confの中身は以下のようになりました(一部抜粋)。
[unix_http_server]
file=/tmp/supervisor.sock
chmod=0700
[supervisord]
pidfile=/tmp/supervisord.pid
nodaemon=true
user=root
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///tmp/supervisor.sock
[program:httpd]
command=/usr/sbin/httpd -DFOREGROUND
[program:cloudsqlproxy]
command=/usr/local/bin/cloud_sql_proxy -instances=(MySQLインスタンス)
[program:gcsfuse]
command=/usr/bin/gcsfuse --debug_gcs --debug_fuse --foreground --implicit-dirs -o rw,allow_other (GCSバケット) (WordPressアップロードディレクトリ)
user=root
startretries=1
httpd、gcsfuse、cloudsqlproxy、それぞれを子プロセスで動作させることになります。
これによりWordPressをCloud Run上で実行することができます。
課題
WordPressの管理画面上でデザインやプラグインの修正を行うと、コンテナイメージが複数存在する場合は1台しか書き換えられず、ユーザーや権限を設定して変更できないようにする必要があります。
それらが変更されたら他のコンテナと同期を取るなど、の手段も考えられます。
変更を加える際はGitにpushしてもらい新しいイメージを作るのが良いのですが、エンジニアはそれで対応していますが、メディア対応する方々は現状そのようにはなっていません。
また管理画面のログインのcookieも共有する必要があります。
Google CDNがキャッシュが弱い為に、AWSのCloud FrontやCloudFlareなど試す必要があります。
他の会社などでWordPress + CloudRunの実績が見当たらない(知らないだけ?)ので、引き続き調査・検討を進めていきたいと思います。
次
株式会社Retail AI X AdventCalender2022の13日目
社内イベント企画が得意な @esoul さんによる「Reactでよく使われるpropsについて知ろう」になります。
参考
https://github.com/google-github-actions/deploy-cloudrun
https://ondwn.com/github-action-cloudrun-wp/