Liberent-Dev’s blog

株式会社リベル・エンタテインメントのテックブログです。

AmazonGameLiftを試してみた

こんにちわ!
システム開発部のK.Mです。

今までの記事とは少し趣を変えて、ゲーム実装部分に関する内容を紹介していきます。

近年、様々な形でリアルタイム通信を使ったゲームが増えてきているように感じます。
モバイル向けのゲームに関しては今後5Gが普及していけば通信環境が今より良くなり、リアルタイム通信を使ったものが、ますます増えてくるのではと個人的に考えています。

しかし、リアルタイム通信を最初から実装するとなると非常に大変なものとなります。
その大変なリアルタイム通信の実装をサポートするサービスが色々と存在しています。
有名どころであればPhotonやモノビット、MagicOnion、最近だとdiarkis等があったりしますが、サービスによってどこまで担ってくれるかが微妙に異なっており、利用する場合はゲームの仕様の性質に応じて検討することをお勧めします。

今回は触る機会がありました、AWSが提供しているGameLiftというサービスを使い、 簡単な実装例を交えて紹介していきます。

GameLiftとは?

Amazonが提供しているAWS内の1サービスとなります。
GameLiftにはユーザー側で実装を全て行うカスタムサーバ機能と一部の実装だけを行うリアルタイムサーバ機能の2つが用意されています。
GameLift内に内包されている機能でFleetIQなどが独自して存在しておりますが、今回はGameLiftのリアルタイムサーバ機能の話にフォーカスしています。

また、今回後述するAmazonが用意している導入手順ではリアルタイムサーバ機能での手順のため、この記事内もリアルタイムサーバでの手順となります。

リアルタイムサーバ機能ですが、サーバ側の実装に必要な処理はJavaScriptで記載してサーバに配置する形となります。
Unity側の通信周りの実装はAWSにて用意されているSDKを使うことで実装出来ます。

今回対象外になるカスタムサーバ機能ですが、C#C++が使えるので複雑で高度なオンラインゲーム(MMOなど)であれば、
こちらを利用するのがベストです。

確認環境

  • MacOS 10.15.7
  • VisualStudio for Mac 8.10.7
  • Unity 2019.3.4f1

ローカルで動く対戦ゲームを作る

ここがメインの話では無いので詳しい説明は省きますが、まずはUnityで下記のようなゲームを作ります。
Unityだと当たり判定が簡単に出来るので楽ですね!

  • スペースキーを押してから離すと心ちゃんが前進
    • 必然的にボタンの連打が必要になり簡単なものだがゲームしてる感を出すようにしました
  • 同じようにエンターキーを押してから離すと桃助が前進
  • 上下移動しているカメロンパンに接触している間は前進不可
  • 画面左のクマ校長が居る場所まで移動したらゴール

f:id:Liberent-Dev:20220217162442g:plain 出来上がったものです。

続きを読む

Qwiklabsで学習しよう

Qwiklabsで学習しよう

はじめに

こんにちは。 システム開発部のこたつみかんと申します。

オンプレミスからクラウドへの移行が進むにつれ、サーバサイドの学習をどのように行うかについては皆さん悩みどころかと思います。

通常パブリッククラウドサービスの学習を行うためには実際にサービスを利用するのが最もわかりやすいとされ、そのような解説記事も多く出ています。

一方、コスト意識の高い企業が多い中で、操作をほんの少し間違えることで意図しない費用が発生してしまうリスクを考慮すると、新サービスを試しに使うことを躊躇してしまったことのある方は少なくないと思います。

本記事では、上記のような問題に対して低コスト、もしくは固定コストでクラウドサービスについて学習のできるQwiklabsについて紹介していきます。

Qwiklabs とは

Qwiklabsは実際の環境を使いながらクラウドについて学ぶことのできるeラーニングサービスです。

ここではGCPの導入的なクエストである「Google Cloud Essencials」を実行しながらサービスについて説明していきます。

まず、Qwiklabsのホーム画面に移動します。

f:id:Liberent-Dev:20220126114707p:plain
Qwiklabsのホーム画面

ここで「クエスト」と「ラボ」という用語が登場します。 これはQwiklabsのサービスの構成単位となります。

サービスの構成

  • ラボ
    • Qwiklabsでの最も細かい課題の単位になります
    • 無料のものと有料のものがあります。有料のものは規定のクレジットを支払うことで一回ラボを開始できます
    • ラボには目標が設定されています。ラボ内には目標を達成するためのチェックポイントがあり、いずれかの方法で達成できます
      • 択一の設問に正解する
      • ラボで開いたコンソール内で規定の機能を実行する
    • 制限時間が設定されていて、時間内にすべてのチェックポイントを達成するとラボを完了できます。
      • 制限時間はラボにとって異なります。概ね30分〜1時間です。
  • エス
    • 学習のためにいくつかのラボを組み合わせた一連の構成をクエストと呼びます
    • エスト内の一定のラボを達成することでクエストを完了できます
    • エストを完了するとバッジを入手できます

では「Google Cloud Essencials」を選びます。

f:id:Liberent-Dev:20220126114854p:plain
エストのトップページ
こちらは既にクエストをクリアしたもので、バッジが取得されています。
また、クリアしたラボにはチェックマークが入っています。
試しに一番初めのラボを選んでみます。
f:id:Liberent-Dev:20220126115037p:plain
ラボの画面
こちらがラボの画面になります。
左上の「ラボを開始」を選ぶと開始します。
このラボは無料なので早速押してみましょう。
f:id:Liberent-Dev:20220126115255p:plain
ラボを開始した画面
ボタンの色が変わってタイマーが動き始めたのがわかります。
また、必要であれば「Google Consoleを開く」を選ぶことで本物のGCP環境にアクセスできます。
利用するためのアカウント情報はその下に表示されています。
このアカウント情報はワンタイムのものになっています。

また、表示されている画面は目標の最後にある「理解度チェック」になります。
設問に正解することで次の目標に移り、最後まで進めることでラボをクリアできます。

ここで選んだラボは無料でしたが、その次のラボには「クレジット:1」と書いてありました。
このラボを進めるためにはクレジットを購入する必要があります。

課金システム

有料コンテンツの課金方法は以下の2種類です。

  • クレジット購入
    • 基本の方式。1クレジット=1$で8クレジットから。
    • 40クレジット以上同時に購入すると割引があります
  • Advantageサブスクリプション
    • 期間内はクレジットを消費せずにすべての有料ラボを利用可能
    • 月間プラン:$55/月
    • 年間プラン:$495/年

課題の紹介

私が実際に選んでみてよかったクエストがありますので、その印象についてご紹介します。

  • Insight from Data with BigQuery
    • BigQueryを使ったデータの処理についてのクエストです
    • 実際のオープンデータを使って学ぶので、データの応用について想像しやすかったです
    • このクエストの最後のラボは通常のラボより難易度が上がっていて、クリアした時の達成感がうれしいです

その他いくつかおすすめのクエストをご紹介します。

  • G Suite Essentials
    • Google Workspaceを初めて使うスタッフの教育に最適のクエストです
    • 最後のラボは未翻訳なのでご注意ください。これを抜いて進めても問題ないです
  • Google Cloud Essentials
    • 先程の画面です
    • 初めてGCPに触れるエンジニアの教育として最適のクエストです

ここまでざっくりとQwiklabsのサービスについて説明してきました。
ここでQwiklabsを実際に使ってみてここはいいなと思う部分とちょっと工夫する必要があるなと思った部分について紹介していきます。

メリット

  • 本物のクラウドの環境が使える
    • 自分で試しに環境を作るより安く色々なサービスを試せます
    • 現在日本語に対応しているのはGCP,AWSです
  • 無料のラボがたくさんある
    • 試したことのないサービスの内容をかじるには最適です
  • 学習目標を設定しやすい
    • 習得したいサービスに対して必要なラボをまとめたクエストが構成されているので学習を進めやすいです
    • エストのバッジが履修確認になるのでわかりやすいです
  • 理解するまで置いていかれない
    • 各ステップの次に進行するためにはコンソールでの実操作が必要なので、通常の座学より理解度が高いです
    • 操作を間違えても正しい結果にたどり着くまで待っていてくれるので焦る必要がありません
  • 資格試験対策になる
    • Googleの資格試験における標準学習環境として提示されています
    • チャレンジラボはケーススタディになっており、実際の問題解決と同じような形で実力をつけることが可能です

デメリットと対策

  • 好き勝手に環境を作ることはできない
    • ラボの問題解決が目的なので、それ以外のことはできません
  • 時間切れになるとラボが強制終了する
    • クレジットを買うとやり直しが効かないので再履修を繰り返すと最終的に高価になってしまいます
    • 対策としてはサブスクリプションがおすすめです。決められた期間内にできるだけ色々なものを試すとコスパが高くなると思います
  • 課題の解決に英語力が必要
    • 基となるデータセットが全て英語で構成されていて、かつ普段扱っている分野と別のものであるため、見たことのない単語を見かけることがしばしばあります
    • ラボは日本語のものを選べば翻訳済みなのですが、サービス特有の技術用語はそのままカタカナ化されているのでテキストを噛み砕いて読む必要があります

まとめ

Qwiklabsは導入部から深い学習まで可能なクラウド向けのeラーニングサービスです。
実際に様々なサービスを業務に投入する前にここで学ぶことで問題解決能力を上げ、実力をつけてから業務に臨むことができるので、ぜひ一度試してみてください。


リベル・エンタテインメントでは、このような最新技術などの取り組みに興味のある方を募集しています。
もしご興味を持たれましたら下記サイトにアクセスしてみてください。
https://liberent.co.jp/recruit/

ゲームのデータをBigQueryにインポートする方法

f:id:Liberent-Dev:20211210161913p:plain

こんにちわ。 システム開発部ネットワーク課のsupercontinueです。

はじめに

http://takano-plantuml-server.herokuapp.com/svg/SoWkIImgAStDuU8gpixCAqWiIinLoCtFoq_EAChFJLKeAIfDvUBYqdZSFEznqyx7JViVD-zvtDmE8flsQohewjefQ3XbfWUMfXPLQeBLBGFBRGEHZUiUD-q6QvX6WfuN2tkUTazzkd7fixLRC5Kx9fVa5ocW22fOARoStVPYHSVZvjrFEzgUpPl0vP2QbmBq5000

ゲームのサービスを運営する上で、ユーザーの行動データを集計・分析する必要があります。

集計・分析するプラットフォームとして、Google Cloud の BigQuery は一般的なオプションの1つです。

BigQueryは膨大なデータを分析するのに特化したデータベースです。

以下では、ゲームのサービスで使うデータの種類ごとに BigQuery にインポートする方法を説明します。

  • マスターデータ

    • ゲームサービスにおいて、ガチャやストーリーやレベルアップに必要な経験値など、一般的にマスターデータと呼ばれるデータがあります。
    • 内容によってデータのサイズはまちまちですが、一般的にはユーザーデータやログと比較すれば、十分小さいと言えます。
  • ユーザーのセーブデータ

    • 経験値や持っているアイテムなどを保存しているデータです。
    • ユーザー数に応じてデータ全体のサイズが大きくなります。数百万のユーザーを考えると、大きなデータになることが想像できます。
  • ユーザーの行動履歴

    • ユーザーが、ゲームで、いつ・何をしたのかを記録したデータです。
    • ユーザー数とサービス期間によって、どんどんデータは蓄積し、膨大な大きさのデータになります。

マスターデータをインポート

本番サービスのデータを更新したら、BigQueryのマスターデータも更新します。

マスターデータは比較的サイズが小さい・更新頻度が低いため、BigQueryのマスターデータを一旦全部削除し、新規にマスターデータを追加します。

費用・時間・オペレーションの単純さの面で、一旦全部削除し、新規に追加する方がベターです。

http://takano-plantuml-server.herokuapp.com/svg/SoWkIImgAStDuU8gpixCAqWiIinLoCtFoq_EAChFJLKeAIfDvUBIA2akqrJGjLFGSCfC3onDBQhKLB1IyCbFJE5oICrB0Me70000

下記は tsv のマスターデータをインポートする例です。

bq --location=${MY_REGION} rm --force --table ${GCLOUD_PROJECT}:${DATASET}.${table}

bq load --autodetect --source_format=CSV --encoding=UTF-8 --field_delimiter='\t' --skip_leading_rows=1 \
        --max_bad_records=10 \
        ${GCLOUD_PROJECT}:${DATASET}.${table} ${file}

CIで自動で更新されるように設定します。

分析時の煩雑さが増しますが、マスターデータを日付ごとにBigQueryに保存するほうが良いかもしれません。データ自体が小さいため、BigQueryに置いておいてもコストの心配がないからです。

ユーザーのセーブデータをインポート

ユーザーのセーブデータは、1日1回、ユーザーデータベースである Google Cloud Spanner から Google Cloud Storage にエクスポート(バックアップ)をしています。

そのバックアップデータを、BigQuery にインポートします。

http://takano-plantuml-server.herokuapp.com/svg/SoWkIImgAStDuU8gpixCAqWiIinLoCtFoq_EAChFJLKeAIfDvUBI22v8pCjBBT9KqBLJq71t3jPKi59mIIn9JCl9B-U2281ad3BJ0qjJYof1qZxvYIbS3gbvAK330G00

ユーザーデータベースからBigQueryへ直接インポートもできますが、バックアップとしてGCSにデータがありますし、トラブルがあった時のやり直しや負荷を考えて、GCSへエクスポートされたものをソースとするのがベターです。

まずは avro形式でGCSヘエクスポート

Google Cloud Storage にエクスポートするには、Google Cloud Dataflow を使います。

下記のように、Google Cloud Storageには、avro形式でエクスポートしています。

TEMPLATE_LOCATION="gs://dataflow-templates/2020-01-09-00_RC00/Cloud_Spanner_to_GCS_Avro"

gcloud dataflow jobs run ${JOB_NAME} \
  --gcs-location=${TEMPLATE_LOCATION} \
  --region=${MY_REGION} \
  --staging-location=${MY_SPANNER_BACKUP_GS_URL}/temp \
  --parameters=instanceId=${MY_INSTANCE_ID},databaseId=${MY_DATABASE_ID},outputDir=${MY_SPANNER_BACKUP_GS_URL}/avro > tmp.log

上記の例では、ユーザーデータベースの Google SpannerからGCSへavro形式でエクスポートする、Googleが提供するテンプレートを利用しています。

テンプレートジョブは時々更新されており、最新版が自分の環境で突然動かなくなることがあります。

そのため、リリースを指定して使うのが良いでしょう。

つまり、下記のような latestは、使わない方が良いです。

TEMPLATE_LOCATION="gs://dataflow-templates/latest/Cloud_Spanner_to_GCS_Avro"

GCSのコストはとても低いので、過去の必要な日数分を保存するために利用できます。

GCSのavro形式のデータをBigQueryへインポート

以下では最新のセーブデータだけをBigQueryに入れています。

bq --location=${MY_REGION} rm --force --table ${GCLOUD_PROJECT}:${DATASET}.${table}

bq --location=${MY_REGION} load \
        --source_format=AVRO \
        ${DATASET}.${table} \
        "${MY_SPANNER_BACKUP_GS_URL}/avro/${MY_INSTANCE_ID}-${MY_DATABASE_ID}-${DATAFLOW_JOBID}/${table}.avro*"

上記のようなバッチスクリプトを1日1回実行します。

ユーザーデータをBigQueryに日付別に保存するかどうかは、分析方法とコストによって判断する必要があります。BigQueryに毎日蓄積させるとコストが増大していきます。そもそもGCSに日付別データがあるので、必要に応じてBigQueryに読み込むことができ、そのほうがコストが下がるケースがあるためです。

ユーザーの行動履歴をインポート

ユーザーの行動履歴は、1秒間に何千レコードも発生・追加する必要があるようなログデータです。ゲームによってはテラバイトのオーダーになるような巨大なデータです。

このようなデータは、一般的にストリーミングとして扱います。

ゲームサーバが出力するユーザー行動ログを、ストリーミングとしてBigQueryへ送信することで、ログデータを取り込むことができます。

http://takano-plantuml-server.herokuapp.com/svg/SoWkIImgAStDuU8gpixCAqWiIinLoCtFoq_EAChFJLKeAIfDvUBIUDoqwN7pdiVD2nutRGKp9ZnkNFUuUUtZfWsQ2hfs2XfEcUc1fQb5bPeALWeGySVDgq4gc_Q3oCRbZvjsFcxkUDoy2cBEouR69_iNSZcavgK0BGS0

ゲームサーバでログを出力する

BigQueryで扱いやすいように、jsonフォーマットでログを出力します。

go だと下記のような感じです。

var LoggerChild *logging.Logger
func LogJSON(ctx context.Context, level logging.Severity, v interface{}) {
    jsonPayload, err := json.Marshal(v)
    if err != nil {
        return
    }

    ret := ctx.Value(myLogDataContextKey)
    if ret != nil {
        if myLogData, ok := ret.(*MyLogData); ok {
            LoggerChild.Log(logging.Entry{
                Payload:  json.RawMessage(jsonPayload),
                Severity: level,
                Trace:    myLogData.TraceID,
                Labels: map[string]string{
                    // 自分で定義したラベルとデータ
                },
            })
        }
    }
}

BigQueryにテーブルを作る

ユーザー行動ログのテーブルの設定は下記のようにするのがベターです。

  • テーブルタイプ
    • 分割
  • 分割基準
    • DAY
  • フィールドで分割
    • レコードのtimestamp

ゲームの場合、日付単位での集計が多く、テーブルを日付で分割することで、速度とコストでメリットがあります。

ログルーターでログを送信する

Google CloudでログをBigQueryにストリームで送信するには、ログルーターシンクを定義します。

  • フィルタで、プロジェクトIDやログとして扱う条件を設定します。

    • ログにMyGameLogType のようなフィールドを設定しておき、そのフィールドに値があるログのみを送信するという感じで設定します。
  • 送信先にBigQueryのテーブルを選びます。

おわりに

ゲームのデータをBigQueryで集計・分析するために、必要なデータをインポートする方法を説明しました。

基本的に一度構築すれば手間はかかりません。少ない労力でBigQueryの活用を始めることができます。

BigQueryのコストは利用方法によって大きく変わるので、適切な構成にする必要があります。


リベル・エンタテインメントでは、このような最新技術などの取り組みに興味のある方を募集しています。もしご興味を持たれましたら下記サイトにアクセスしてみてください。 https://liberent.co.jp/recruit/

Google Cloud Spannerを使った際に感じた良かった点と注意点

Google Cloud Spannerを使った際に感じた良かった点と注意点

みなさま、こんにちは!
システム開発部のK.Mです。

弊社でGoogle Cloud Spannerをデータベースに使用する機会がありましたので、開発・運用時に感じた良かった点・注意点を個人的な見解を交えて記載していきます。

f:id:Liberent-Dev:20211125175521p:plain

  • Google Cloud Spannerを使った際に感じた良かった点と注意点
    • Google Cloud Spannerとは
    • 良かった点
    • 注意点
    • 開発時、運用時に起きた他の事例
    • その他、未確認事項
    • まとめ
    • 最後に

Google Cloud Spannerとは

Googleが開発した分散データベース
RDBMSとNoSQLの良い部分が合体したデータベース

良かった点

  • フルマネージドなので運営中に手がかからない

    • 運営期間中は追加実装など他業務に集中出来る。
      実際の運用時にspannerが落ちて繋がらなくなるということはありませんでした
    • イベントなどの負荷が上がりそうな時に事前にノード数を増やしたり、アクセス数が落ち着いてからノード数を減らすという作業しか行っていない
    • それ以外だと1日1回GCPの管理画面からspannerのCPU負荷やレイテンシに問題が発生していないかを確認する程度の作業量でした
  • データの水平・垂直分割しなくてもspanner側で勝手にやってくれる

    • DBの読み書き処理で水平・垂直分割の処理が不要なので、事前に分割しないといけないぐらいのデータ量になる想定がついている場合は、「実装コストが減る=テスト工数が減る=変なバグを仕込む心配が無い」という形になります
    • 例えると、MySQL ClusterやMySQLのSpiderストレージエンジンと同じような機能が設定不要で使えるということです
    • この機能は、かなり強いです
  • 運用時にメンテナンスを入れずにスキーマー変更が可能

    • 使用した案件では、本番環境にて動作確認をするためのメンテナンスを入れるという工程があったため、メンテナンス中にスキーマー更新を行っていたが、運営サイクルにてメンテナンスを無くすことを検討しているのであれば、魅力的な機能
  • 配列型や構造体型でデータが持てる

    • DBの設計がすっきりして、プログラム側での処理がしやすくなる
    • 配列型の一例
      • ストーリーの第何話を読んだというのを単純に実装しようとして、ユーザーIDと読んだストーリーの話数を保存するテーブルを作った場合、下記のように読んだストーリー数分のレコードが作られてしまいデータが膨れ上がるし、selectやinsert、updateの速度にも影響が出てしまう。(インデックスを設定すればselect自体の速度は速くなるが、insertの速度がデータが増えていくたびにインデックスの更新も入り遅くなっていきますので通常は取りえない設計)

        ユーザーID 読んだストーリーID
        1 1
        1 2
        1 3
        2 1
        2 2
      • 次に考えられるのが無駄にレコードが作られないように、読んだストーリー部分をカンマ区切りの文字列などで保存するという方法がある。こうすることで、ユーザー数分のレコードで済むのでデータ数は激減するが、プログラム側でDBからの読み込んだ際に、カンマで区切られた文字列をカンマ毎に分けて数字にしたり、DBに書き込む際に、数字をカンマで連結して文字列にしたりという処理が入ってきて、少し煩雑になってしまいます。

        ユーザーID 読んだストーリーID
        1 "1,2,3"
        2 "1,2"
      • そういった諸々を回避する方法として読んだストーリーIDをint型の配列型に設定することが可能になっています。配列型に設定出来る型自体は自由です。

        ユーザーID 読んだストーリーID
        1 [1,2,3]
        2 [1,2]
      • goの場合ですが、spannerから読み込んだ時点でint型のスライス(goでの配列のようなもの)として扱えるようになっているので、追加する場合は下記のようにappendするだけでデータが追加されます。

ストーリーテーブル.読んだストーリーID = append(ストーリーテーブル.読んだストーリーID, 4)
  • spannerの管理画面にて下記のような統計を表示するページがあり、クエリのCPU使用率や実行回数、レイテンシが見れるので調査のためにSQL(EXPLAINとか)を叩かなくてもブラウザ上で確認が出来るので調整が簡単に行える
    f:id:Liberent-Dev:20211122185625p:plain

  • GCP標準機能であるトレースにて、スタックトレースのようにspannerのコール順が分かるので、チューニング時にネックになっている箇所が分かりやすい。

    • 下記図はスタックトレースの一例になりますが、この内容ですとReadが頻繁に呼ばれているので、なるべくまとめてRead出来れば処理を短縮出来そうなので調べてみる。
      この例に挙げたケースは、バッチ処理で各テーブルを読み込んでいるという処理だったので、そのままにしておくという判断をしています。 f:id:Liberent-Dev:20211122185621p:plain
続きを読む

ゲームのお知らせページをJamstackで構築した

Jamstack logo

こんにちわ。 システム開発部ネットワーク課のsupercontinueです。

  • ゲーム内お知らせやガチャの情報を扱うWebアプリケーションのサーバ側の仕組みを紹介します。
  • Jamstack を採用して、低コスト・安全 な仕組みができました。

Jamstackとは

特徴

  • 基本的に、CI(継続的インテグレーション。Jenkinsなど)の利用を前提とした設計パターンです。

  • たとえば、Jamstackではない従来型設計の典型であるWordpressに比べると、低コストで安全性も高く、スケール・イン&アウトもしやすくなります

    • なぜ、安全性が高いのか?
      • コンテンツが静的配置され、バックエンドでデータベースに接続する必要がなく、サーバの仕組みが単純になり、セキュリティを担保する必要がある機能が最小限になるからです。
    • なぜ、低コストなのか?
      • 高コストになりがちなデータベースサーバが不要になります。
      • サーバ側でレンダリング(ページの生成)が不要になるため、必要なCPUパワーが少なくなります。
  • ブログやお知らせ・ガチャ・商品情報など、更新頻度があまり高くない、特定のフォーマット(レコード単位の情報)でページが構成される情報のサービスに向いています。

    • 多数ユーザーが高頻度で書き込みを行うようなサービスには向いていません。
  • 複数のシステムで構成され、それぞれは小さいですがスクリプトを記述することが多くなるため、Wordpressのように非エンジニアでも管理できる可用性は失われます。いわゆる「フルスタック・エンジニア」が必要かもしれません。

本案件の構成要素

ヘッドレスCMS

http://takano-plantuml-server.herokuapp.com/svg/SoWkIImgAStDuU8gpixCAqWiIinLoCtFoq_EAChFJLKeAIfDvU9I08E2nEJinFHK1QNm_AAKWgBKuc8bXMe5gAI2WeQpRx0cWlUuUStZvisFcniUDwy2CPesm2HhkP0qAEZgse4KjpzktlEuQV_ZvfbWnavDAuNdsrUydDt6XTiyd7eLh1IUzZSzRrtEvP2QbmBq7G00

  • ヘッドレスCMSは、データを編集・アウトプットする機能を、独立して提供します。
    • ヘッドレスCMSを使う場合、ビルド、レンダリング機能を自前で用意する必要があります

http://takano-plantuml-server.herokuapp.com/svg/SoWkIImgAStDuU8gpixCAqWiIinLoCtFoq_EAChFJLKeAIfDvU9IK2X8JCvEJ4zLK7hSFEDnS_FZvix7pMiUD-rqzWrMKgW6Ab1Gq02oDO6iMXJbJLiVDorvtDpnk77Tu-R9ZvjN0xN2TS157ZVl1Xhsk6dzu-PLZvkd0zNZDWck--NScSzdjJnkRd_SlETnqtwO3h0x57HrxK3cG-KUDyy4CtPgAbWfFD--ukNiDhXA6rrTNVnE0Ufvsj_ql7Kv5m4tGsn5TnV8oYdpdtLCuCBYQ0MGZcTTUv-sxzBaSaZDIm761G00

  • ヘッドレスCMSとして、Cockpit を使いました。
    • Mongodbにデータをアウトプットします。
    • オンプレ環境のDockerで運用しました。

f:id:Liberent-Dev:20211018142838p:plain

cockpitでの編集

  • 複数ユーザーアカウント、ロールで運用できます。

  • collectionsingletonasset の概念があります。

    • collection は複数レコードで構成されます。
      • お知らせ、ヘルプなどで使います。
    • singleton は単一レコードで構成されます。
      • ライセンス表示、利用規約などで使います。
    • どちらも、レコードのフィールドをカスタマイズできます。
      • 日付、時間、テキスト、Wysiwyg、数値、真偽値、オプション、、、
    • asset は基本的に画像ファイルです。

トップページ

f:id:Liberent-Dev:20211018135418p:plain
スクリーンショット:cockpit:トップページ

編集画面の例

f:id:Liberent-Dev:20211018135619p:plain
スクリーンショット:cockpit:記事編集1

f:id:Liberent-Dev:20211018135721p:plain
スクリーンショット:cockpit:記事編集2

アセット画面

f:id:Liberent-Dev:20211018135742p:plain
スクリーンショット:cockpit:アセット一覧

ビルド・スクリプト

  • 下記のように、Cockpitの提供するREST APIを使って、jsonデータを持ってきます。
## お知らせ
if [ "${ENV_VERSION}" = ".prod" ]; then
    INFOMATION_FILTER='{"sort":{"releaseDate":-1,"releaseTime":-1},"filter":{"production":true}}'
else
    INFOMATION_FILTER='{"sort":{"releaseDate":-1,"releaseTime":-1}}'
fi
curl -s ${CMS_API}/collections/get/information?token=${COCKPIT_API_TOKEN} \
 -H "Accept: application/json" -H "Content-type: application/json" \
 -d ${INFOMATION_FILTER} \
 | python -m json.tool > gae/collections/information.json
  • ゲームのレポジトリから、ゲームのマスターデータ(キャラクターやガチャなど)も参照します。

  • 生成する静的データのディレクトリ構成

    • collections 以下には、複数レコードで構成されるjsonデータを置きます。

      例)

      • お知らせ information.json
      • ヘルプ help.json
      • ガチャ gacha.json
    • singletons 以下には、1レコードで構成されるjsonデータを置きます。

      例)

      • ライセンス表記 License.json
      • 利用規約 TermsOfService.json
  • 画像などのファイルは、Cockpitの特定の場所にファイルとして保存されています。 デプロイ時に、CDNに同じファイルをコピーします。

サイト構成

http://takano-plantuml-server.herokuapp.com/svg/SoWkIImgAStDuU8gpixCAqWiIinLoCtFoq_EAChFJLKeAIfDvUBYKW22WiJaxCJqL0KbTqTNXRpyb5Izh68bXMgm70XeP9JavkWeP1NhA2GN5siYn8jJYyfIYu2gaSHUpftvV5RBu-Rsnyrx7ZVjLtYoO_VZnjLPnVbv44Mrg5Owk_YXM8LT-_CfkvyszoCReF6uUThZvfMFcvOzRjhskAabF3KfB3Er_77JUh3eaiTDYnutRtxStA6feAjhXzKBf1g1yAs2bGBSXK_xfptTDvqi0mdx5TbEF5h0eGjsrDJ7JOiVDwy6IW7jVzmy2wni1yZMfWrS3gbvAS040G00

  • html, js, cssは、CDNに置くことも可能ですが、サイズが小さく更新しやすいのでGAEに置きます。
  • 今回は node.js を使いましたが、サーバのスクリプトはとても小さいので、goでもpythonでもなんでもいいと思います。

Webページ

  • ページの開発は riot を使いました。
    • vueのようにメジャーではありませんが、覚えることが少なくて楽で、ビルドも早いしサイズも小さいです。

f:id:Liberent-Dev:20211018153352p:plain

  • ブラウザやWebViewから、お知らせなどのデータを取得するには、フィルタなどを指定して、下記のようにAPIで動的に取得します。
      var url = '/api/collections/get/information';

      fetch(url, {
        method: 'post',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          filter: {infoType: self.infoType},
          limit: self.limit,
          skip: self.limit * (self.page - 1),
          sort: {releaseDate:-1, releaseTime:-1},
        })
      })
  • サーバ側のスクリプト server.jsは、起動時に静的データを全てメモリに読み込み、リクエストに応じて、データを返します。
    const information = require('./collections/information.json');
    app.post('/api/collections/get/:collection', (req, res) => {
        // 指定した条件で抽出したデータをjsonで返す。
        ...
    app.get('/api/singletons/get/:singletonname', (req, res) => {
        // 指定した条件で抽出したデータをjsonで返す。
        ...

おわりに

  • Jamstackは「コストとセキュリティが気になる」、「スクリプトが得意」なエンジニアに向いています。

  • ブラックボックスがほとんどないので、問題が発生した時、解決できないリスクが少ないし、セキュリティも担保しやすいです。

    • Wordpressで深めの問題が起こったら、ほとんどの人は自力ではどうしようもないのとは対照的です。
  • 導入にあたっては、CMSを使う人やサービスを運用する人の理解や、その人たちへのサポートが必要です。


リベル・エンタテインメントでは、このような最新技術などの取り組みに興味のある方を募集しています。もしご興味を持たれましたら下記サイトにアクセスしてみてください。 https://liberent.co.jp/recruit/