MAGELLAN で動作する Spring Boot ウェブアプリケーションの作成方法

MAGELLAN で動作する Spring Boot ウェブアプリケーションの作成方法を解説します。このドキュメントでは、「MAGELLAN で動作する Spring Boot ウェブアプリケーション」を便宜的に「Spring Boot Worker」と呼ぶこととします。

はじめに

MAGELLAN で動作するアプリケーションを Worker と呼びます。Worker は、Docker コンテナとして動作します。このため、Spring Boot ウェブアプリケーションを MAGELLAN で動作させるためには、Spring Boot ウェブアプリケーションが動作する Docker イメージ(コンテナ)を用意すれば良いことになります。

Worker の動作原理

下図は、ウェブブラウザー - Worker 間の通信仕様です。ウェブブラウザーから Worker へのリクエストは、一旦 MAGELLAN が受け取り、何らかの処理を行い Worker へ引き渡します。この際、ウェブブラザからの HTTP/HTTPS リクエストを独自プロトコルのリクエストに変換します。レスポンスは、その逆で独自プロトコルのレスポンスを HTTP/HTTPS のレスポンスに変換します。

ウェブブラザ - Worker 間の通信仕様

このように、MAGELLAN - Worker 間のインタフェースが独自プロトコルとなっているため、そのままでは、Spring Boot ウェブアプリケーションは、動作できません(独自プロトコルが処理できません)。

この問題を解決するために、magellan-proxy というツールを提供しています。magellan-proxy は、MAGELLAN 独自プロトコルと HTTP を相互変換するツールです。

magellan-proxy は、下図のように Worker 内で、Spring Boot ウェブアプリケーションのフロントエンドとして動作させます。こうすることで、Spring Boot ウェブアプリケーションは、MAGELLAN 独自プロトコルを一切関知することなく、動作可能となります。

magellan-proxy

このように、Spring Boot Worker の基本は、magellan-proxy を Spring Boot ウェブアプリケーションのフロントエンドとして動作させる Docker イメージを用意することになります。

Spring Boot Worker の作成方法

それでは、Spring Boot Worker の作成方法を具体的に見ていきます。

推奨環境

推奨環境は、Basic プランの Standard(vCPU: 2 / Memory: 400MB)です。

Spring Boot ウェブアプリケーションの構成やチューニングをどうするかにもよりますが、Spring Boot ウェブアプリケーションの動作にはメモリ容量が 400MB 程度は必要となります。

tips用アイコン

Micro では、メモリ容量が 200MB のため、動作保証できません。

magellan-proxy を使った Docker イメージ作成の基本

magellan-proxy の使い方は、とても簡単です。Spring Boot ウェブアプリケーション用 Dockerfile に対して、次の手順を踏むだけです。

  1. magellan-proxy コマンドのインストール
  2. CMD 命令の修正

magellan-proxy コマンドのインストール

まず、magellan-proxy コマンドのインストールですが、次の 2 行を Dockerfile に追加します。

ADD https://github.com/groovenauts/magellan-proxy/releases/download/v0.0.2/magellan-proxy-0.0.2_linux-amd64 /usr/app/magellan-proxy
RUN chmod +x /usr/app/magellan-proxy

CMD 命令の修正

続いて、CMD 命令の修正は、"magellan-proxy" を CMD 命令の先頭に追加します。

例えば、次のように、CMD 命令が指定されていたとします。

CMD ["java", "-Djava.security.egd=file:/dev/./urandom", "-Xmx350m", "-Xms350m", "-jar", "/usr/app/app.jar"]

“java” コマンドの前に、”magellan-proxy” コマンドを追加します。

CMD ["/usr/app/magellan-proxy", "java", "-Djava.security.egd=file:/dev/./urandom", "-Xmx350m", "-Xms350m", "-jar", "/usr/app/app.jar"]

magellan-proxy のオプション

magellan-proxy には、--port オプションと --num オプションがあります。

オプション 意味
–port Spring Boot ウェブアプリケーションが待ち受けているポート番号を指定します。80 番の場合は指定不要です。
–num magellan-proxy が Spring Boot ウェブアプリケーションに対して、リクエストを並行して送信可能な最大数を指定します。設定する値は、Spring Boot の設定ファイルで設定した並行処理可能なリクエスト数と合わせます。
  • 例 1)ポート番号 8080 番利用、並行処理可能リクエスト数 5 の場合

    CMD ["/usr/app/magellan-proxy", "--port", "8080", "--num", "5", "java", "-Djava.security.egd=file:/dev/./urandom", "-Xmx350m", "-Xms350m", "-jar", "/usr/app/app.jar"]
    
  • 例 2)ポート番号 80 番利用、並行処理可能リクエスト数 3 の場合

    CMD ["/usr/app/magellan-proxy", "--num", "3", "java", "-Djava.security.egd=file:/dev/./urandom", "-Xmx350m", "-Xms350m", "-jar", "/usr/app/app.jar"]
    

Google Cloud SQL 利用時の留意事項

MAGELLAN が提供する Google Cloud SQL(以降、Cloud SQL と略す)を利用する場合は、Cloud SQL にアクセスするためのスクリプトを別途用意する必要があります。

MAGELLAN が提供する Cloud SQL を利用する場合は、MYSQL_ で始まる環境変数群に、Cloud SQL への接続情報が設定されます。この環境変数群は、MAGELLAN が設定し、Worker から参照することができます。今回利用する環境変数を次に示します。

環境変数名 意味
MYSQL_HOST データベースの IP アドレス
MYSQL_DATABASE データベース名
MYSQL_USERNAME データベースのユーザ名
MYSQL_PASSWORD 上記ユーザのパスワード

作成するスクリプトは、次のとおりです。

スクリプトファイル名 用途
migrate.sh マイグレーション用スクリプト
run.sh Spring Boot ウェブアプリケーション起動用スクリプト。

この他に、データベースマイグレーション用のツール Liquibase もダウンロードして使います。このため、スクリプトと関連するツール一式を管理する専用のディレクトリを用意した方が良いでしょう。

この例では、bin という名称のディレクトリを用意して、そこでスクリプトと関連するツール一式を管理する前提で記述します。最終的には、次のような構成になります。

bin
├── liquibase-3.4.1-bin  <-- Liquibase ツール一式
│   ├── LICENSE.txt
│   ├── README.txt
│   ├── lib
│   │   ├── mysql-connector-java-5.1.35.jar  <-- Java 用 MySQL JDBC ドライバ
│   │   └── snakeyaml-1.13.jar
│   ├── liquibase
│   ├── liquibase.bat
│   ├── liquibase.jar
│   ├── liquibase.spec
│   └── sdk
:       :
  (中略)
:       :
├── migrate.sh  <-- 作成するスクリプト
└── run.sh      <-- 作成するスクリプト

マイグレーションの留意事項

Spring Boot は、データベースのマイグレーションをサポートしていますが、アプリケーション起動時にマイグレーションを実行する仕様となっています。この仕様では、アプリケーションを複数起動した場合に不都合が起こります。

そこで、Spring Boot の仕組みは使わずに、MAGELLAN の仕組みを使ってマイグレーションを実行することにします。

MAGELLAN には、マイグレーション用のコマンドを実行する機能 Migration Command 1 および Migration Command 2 があります。

機能 意味
Migration Command 1 Worker の初回リリース時に、登録されたコマンドを実行します。
Migration Command 2 Worker のバージョンアップ・リリース時に、登録されたコマンドを実行します。

マイグレーション用のスクリプトを作成して、Migration Command 1 および Migration Command 2 それぞれに対してそのスクリプトを登録します。

マイグレーション用のスクリプトは、次の内容で作成します。ファイル名は、migrate.sh とします。

#!/bin/sh
`dirname $0`/liquibase-3.4.1-bin/liquibase --url="jdbc:mysql://$MYSQL_HOST/$MYSQL_DATABASE?createDatabaseIfNotExist=true" --username=$MYSQL_USERNAME --password=$MYSQL_PASSWORD migrate "$@"

スクリプトの内容は、liquibase コマンドを引数を指定して実行しているだけです。引数の意味は、次のとおりです。

引数 意味
–url データベース接続用 URL
–username データベースのユーザ名
–password 上記ユーザのパスワード

この時点での bin ディレクトリの構成は、次のようになっています。

bin
└── migrate.sh

続いて、スクリプトから実行するデータベースマイグレーションツール Liquibase をダウンロードページ からダウンロードして、bin ディレクトリ直下に展開します。以下は、バージョン 3.4.1 の Liquibase をダウンロードして展開した例です。

bin
├── liquibase-3.4.1-bin
│   ├── LICENSE.txt
│   ├── README.txt
│   ├── lib
│   │   └── snakeyaml-1.13.jar
│   ├── liquibase
│   ├── liquibase.bat
│   ├── liquibase.jar
│   ├── liquibase.spec
│   └── sdk
:       :
  (中略)
:       :
└── migrate.sh

Java 用の MySQL JDBC ドライバをダウンロードページ からダウンロードして、Liquibase を展開したディレクトリ内の lib ディレクトリにコピーします。以下は、バージョン 5.1.35 の Java 用 MySQL JDBC ドライバ(mysql-connector-java-5.1.35.jar)をコピーした例です。

bin
├── liquibase-3.4.1-bin
│   ├── LICENSE.txt
│   ├── README.txt
│   ├── lib
│   │   ├── mysql-connector-java-5.1.35.jar  <-- Java 用 MySQL JDBC ドライバ
│   │   └── snakeyaml-1.13.jar
│   ├── liquibase
│   ├── liquibase.bat
│   ├── liquibase.jar
│   ├── liquibase.spec
│   └── sdk
:       :
  (中略)
:       :
└── migrate.sh

Spring Boot ウェブアプリケーション起動時の留意事項

Spring Boot ウェブアプリケーション起動スクリプトは、次の内容で作成します。ファイル名は、run.sh とします。

#!/bin/sh
export SPRING_DATASOURCE_USERNAME=$MYSQL_USERNAME
export SPRING_DATASOURCE_PASSWORD=$MYSQL_PASSWORD
export SPRING_DATASOURCE_URL="jdbc:mysql://$MYSQL_HOST/$MYSQL_DATABASE?createDatabaseIfNotExist=true"
exec "$@"
  • 2 行目〜4 行目
    Spring Boot のデータベース接続用環境変数に、MAGELLAN が設定する Cloud SQL 接続用環境変数を使って、適切な値を設定しています。
  • 最終行
    スクリプト実行時に指定された引数列をそのまま実行します。引数に、Spring Boot ウェブアプリケーションの実行コマンドとその引数が指定されることを期待しています。
    実行例)
    run.sh java -Djava.security.egd=file:/dev/./urandom -Xmx350m -Xms350m -jar app.jar

Spring Boot のデータベース接続用環境変数の意味は次のとおりです。

環境変数名 意味
SPRING_DATASOURCE_USERNAME データベースのユーザ名
SPRING_DATASOURCE_PASSWORD 上記ユーザのパスワード
SPRING_DATASOURCE_URL データベース接続用 URL

これで、スクリプトの作成は完了です。最終的に、bin ディレクトリは次のような構成となります。

bin
├── liquibase-3.4.1-bin
│   ├── LICENSE.txt
│   ├── README.txt
│   ├── lib
│   │   ├── mysql-connector-java-5.1.35.jar
│   │   └── snakeyaml-1.13.jar
│   ├── liquibase
│   ├── liquibase.bat
│   ├── liquibase.jar
│   ├── liquibase.spec
│   └── sdk
:       :
  (中略)
:       :
├── migrate.sh
└── run.sh

Dockerfile サンプル

Cloud SQL 利用時の留意事項を含んだ Dockerfile のサンプル紹介します。

FROM java:8u66-jre

WORKDIR /usr/app

ADD target/spring-boot-worker-example.jar /usr/app/app.jar

ADD bin /usr/app/bin
ADD liquibase.properties /usr/app/liquibase.properties
ADD db /usr/app/db

ADD https://github.com/groovenauts/magellan-proxy/releases/download/v0.0.2/magellan-proxy-0.0.2_linux-amd64 /usr/app/magellan-proxy
RUN chmod +x /usr/app/magellan-proxy

CMD ["/usr/app/magellan-proxy", "-n", "5", "bin/run.sh", "java", "-Djava.security.egd=file:/dev/./urandom", "-Xmx350m", "-Xms350m", "-jar", "/usr/app/app.jar"]

本 Dockerfile サンプルが前提としているディレクトリおよびファイルの構成は、次のとおりです。

ディレクトリ / ファイル 用途
bin/ 各種スクリプト用ディレクトリ
db/ マイグレーションファイル用ディレクトリ
Dockerfile Dockerfile
liquibase.properties Liquibase 設定ファイル
target/spring-boot-worker-example.jar jar ファイルにパッケージングした Spring Boot ウェブアプリケーション
  • ベースイメージの指定

    FROM java:8u66-jre
    

    Docker 公式の Java 実行環境をベースイメージに指定しています。ここでは、2015/10/01 時点の Java 8 最新実行環境を使っています。

    指定するベースイメージに制約はありません。Spring Boot ウェブアプリケーションが動作するために必要なベースイメージを適切に指定してください。

  • インストール先ディレクトリの指定

    WORKDIR /usr/app
    

    この例では、Spring Boot ウェブアプリケーションやスクリプトなどを /usr/app ディレクトリにインストールする設定としています。

  • Spring Boot ウェブアプリケーションのインストール

    ADD target/spring-boot-worker-example.jar /usr/app/app.jar
    

    Spring Boot ウェブアプリケーション target/spring-boot-worker-example.jar/usr/app ディレクトリに、インストールしています。ファイル名は、app.jar に変更しています。

  • スクリプトのインストール

    ADD bin /usr/app/bin
    ADD liquibase.properties /usr/app/liquibase.properties
    ADD db /usr/app/db
    

    準備したスクリプト一式とマイグレーションに必要な各種設定ファイルをインストールしています。なお、Cloud SQL を利用しない場合は、この記述は不要です。

    Liquibase 設定ファイル(liquibase.properties)とマイグレーションファイル用ディレクトリ(db/)は、必ず WORKDIR 命令で指定したディレクトリ直下にコピーしてください。参考までに、Libquibase 設定ファイルおよびマイグレーション関連のファイルの例を掲載しておきます。

    • libquibase.properties

      driver: com.mysql.jdbc.Driver
      changeLogFile: db/changelog/db.changelog-master.yaml
      
    • db/changelog/db.changelog-master.yaml

       databaseChangeLog:
       - changeSet:
           id: 1
           author: your-email@example.jp
           changes:
               - createTable:
                   tableName: person
                   columns:
                       - column:
                           name: id
                           type: bigint
                           autoIncrement: true
                           constraints:
                               primaryKey: true
                               nullable: false
                       - column:
                           name: name
                           type: varchar(255)
                           constraints:
                               nullable: false
                       - column:
                           name: age
                           type: int
                           constraints:
                               nullable: false
    
  • magellan-proxy のインストール

    ADD https://github.com/groovenauts/magellan-proxy/releases/download/v0.0.2/magellan-proxy-0.0.2_linux-amd64 /usr/app/magellan-proxy
    RUN chmod +x /usr/app/magellan-proxy
    

    magellan-proxy をインストールしています。

  • Spring Boot ウェブアプリケーションの起動

    CMDtext ["/usr/app/magellan-proxy", "-n", "5", "bin/run.sh", "java", "-Djava.security.egd=file:/dev/./urandom", "-Xmx350m", "-Xms350m", "-jar",   "/usr/app/app.jar"]
    

    magellan-proxy を使って、Spring Boot ウェブアプリケーションを起動します。

    Cloud SQL を利用しない場合は、次のようになります("bin/run.sh", の記述が不要)。

    CMD ["/usr/app/magellan-proxy", "-n", "5", "java", "-Djava.security.egd=file:/dev/./urandom", "-Xmx350m", "-Xms350m", "-jar", "/usr/app/app.jar"]
    
    オプション 意味
    -Djava.security.egd=file:/dev/./urandom 乱数生成時の性能劣化を抑えるための設定です。
    -Xmx350m, -Xms350m 使用メモリ容量を 350MB に制限。Basci プラン Standard では、メモリ容量が 400MB のため、magellan-proxy 用に50MB 分確保し、残り 350MB 分を Worker 用に割り当てています。メモリ容量をどれくらい割り当てるかは、アプリケーションの特性に合わせて、適切に設定してください。

Worker 用 Docker イメージの作成と Docker Hub への登録

ここまでで、Spring Boot ウェブアプリケーション固有の作業は、ほぼ完了です。Worker 用 Docker イメージの作成と Docker Hub への登録を行います。

Worker 用 Docker イメージの作成は、docker build コマンドを使います。

$ docker build -t yourname/spring-boot-worker-example:1.0.0 .

Worker 用 Docker イメージの作成が完了したら、その Docker イメージを docker push コマンドを使って、Docker Hub に登録します。

$ docker push yourname/spring-boot-worker-example:1.0.0

参考リンク:

デプロイ

デプロイ作業以降は、Ruby on Rails の Worker と同様の手順となります。

MAGELLAN が提供する Cloud SQL を利用する場合は、Worker 登録時の Migration Command 1 および Migration Command 2 において、作成したマイグレーション用スクリプト bin/migrate.sh の設定を行ってください。

項目名
Name Worker 名
Image Name Docker Hub に登録したイメージ名
Container Num 起動したいコンテナ数
Migration Command 1 bin/migrate.sh
Migration Command 2 bin/migrate.sh
Environment Variables 作成したアプリケーションの仕様に基づき必要に応じて適切に設定

参考リンク: