Heroku で Web 以外の Java dyno を実行する
この記事の英語版に更新があります。ご覧の翻訳には含まれていない変更点があるかもしれません。
最終更新日 2019年12月16日(月)
Table of Contents
一部のアプリケーションでは、ロジックを複数のコンポーネントに分割することでメリットが得られます。
- エンドユーザーによって消費される Web プロセス
- バックグラウンドタスクと管理タスクを実行する 1 つ以上の Web 以外のプロセス
Web 以外のプロセスは、以下のいずれかです。
- Worker dyno で長時間実行され、(データベース上の、またはメッセージキューからの) イベントを待機しているプロセス
- One-off dyno で実行され、コマンドラインから、または Heroku Scheduler などのサービスから手動で呼び出すことができるコマンド
前提条件
- Java の基本的な知識 (インストールされている JVM および Maven のバージョンなど)
- Git の基本的な知識 (インストールされている Git のバージョンなど)
サンプルアプリケーション
One-off とワーカーの各プロセスタイプの例を示す単純なアプリは、2 つの単純な Java クラスと 1 つのビルドファイルとして作成できます。
sampleapp/
pom.xml
src/
main/
java/
OneOffProcess.java
WorkerProcess.java
src/main/java/OneOffProcess.java
public class OneOffProcess
{
public static void main(String[] args)
{
System.out.println("OneOffProcess executed.");
}
}
src/main/java/WorkerProcess.java
public class WorkerProcess
{
public static void main(String[] args)
{
while(true) {
try {
Thread.sleep(1000);
} catch(InterruptedException e) {}
System.out.println("Worker process woke up");
}
}
}
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>herokujavasample</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.1.1</version>
<configuration>
<assembleDirectory>target</assembleDirectory>
<programs>
<program>
<mainClass>WorkerProcess</mainClass>
<name>worker</name>
</program>
<program>
<mainClass>OneOffProcess</mainClass>
<name>oneoff</name>
</program>
</programs>
</configuration>
<executions>
<execution>
<phase>package</phase><goals><goal>assemble</goal></goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
アプリアセンブラプラグインにより、アプリケーションを開始するための便利な起動スクリプトが生成されます。1 つの pom.xml
で複数の Web、ワーカー、または管理プロセスを定義できます。
GitHub からこのプロジェクトを複製できます。
ローカルでの実行
アプリケーションをビルドするには、次を実行します。
$ mvn package
次のようにしてワーカーを実行します。
$ sh target/bin/worker
Worker process woke up
Worker process woke up
Worker process woke up
...
(Windows では target\bin\worker.bat
を使用します。)次のようにして One-off プロセスを実行します。
$ sh target/bin/oneoff
OneOffProcess executed.
これで、Heroku にデプロイする準備ができました。
Heroku にデプロイする
Procfile の作成
アプリケーションを実行する方法を、プロジェクトルートの Procfile で宣言します。次の内容でこのファイルを作成します。
worker: sh target/bin/worker
One-off dyno で実行するコマンドを Procfile に追加する必要はありません。One-off dyno のメカニズムでは、One-off dyno を起動するときにコマンドを指定します。
Heroku にデプロイする
変更を Git にコミットします。
$ git init
$ git add .
$ git commit -m "Ready to deploy"
アプリを作成します。
$ heroku create
Creating empty-fire-9222... done, stack is heroku-18
http://empty-fire-9222.herokuapp.com/ | git@heroku.com:empty-fire-9222.git
Git remote heroku added
コードをデプロイします。
$ git push heroku master
Counting objects: 66, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (31/31), done.
Writing objects: 100% (66/66), 15.74 KiB, done.
Total 66 (delta 10), reused 30 (delta 9)
-----> Heroku receiving push
-----> Java app detected
-----> Installing Maven 3.0.3..... done
-----> executing /app/tmp/repo.git/.cache/.Maven/bin/mvn -B -Duser.home=/tmp/build_14lc6nws0m7oc -Dmaven.repo.local=/app/tmp/repo.git/.cache/.m2/repository -DskipTests=true clean install
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building herokujavaworker 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.513s
[INFO] Finished at: Mon Nov 28 15:44:32 UTC 2011
[INFO] Final Memory: 12M/490M
[INFO] ------------------------------------------------------------------------
-----> Discovering process types
Procfile declares types -> worker
-----> Compiled slug size is 12K
-----> Launching... done, v5
http://empty-fire-9222.herokuapp.com deployed to Heroku
ワーカープロセスのスケーリング
ここで、次のようなコマンドを使用して Worker dyno を開始およびスケーリングできます。
$ heroku ps:scale worker=1
Scaling worker processes... done, now running 1
複数の dyno にワーカーをスケーリングすることで、リスナーを増やすことができ、それによって、より多くのメッセージを同時に消費および処理できるようになります。Worker dyno のログを確認するには、次のコマンドを使用できます。
$ heroku logs --tail
2011-12-14T00:52:26+00:00 heroku[slugc]: Slug compilation started
2011-12-14T00:52:54+00:00 heroku[web.1]: State changed from created to down
2011-12-14T00:52:55+00:00 heroku[slugc]: Slug compilation finished
2011-12-14T00:53:17+00:00 heroku[worker.1]: State changed from created to starting
2011-12-14T00:53:17+00:00 heroku[api]: Scale to worker=1 by jesper@heroku.com
2011-12-14T00:53:17+00:00 heroku[worker.1]: Starting process with command `sh target/bin/worker`
2011-12-14T00:53:18+00:00 heroku[worker.1]: State changed from starting to up
2011-12-14T00:53:19+00:00 app[worker.1]: Worker process woke up
2011-12-14T00:53:20+00:00 app[worker.1]: Worker process woke up
2011-12-14T00:53:21+00:00 app[worker.1]: Worker process woke up
One-off dyno
プロセスが、必要に応じて手動で実行したいコマンドである場合、One-off dyno を使用してそのように実行できます。 One-off dyno を開始してコマンドを実行するには、次のように heroku run
コマンドを使用します。
$ heroku run "sh target/bin/oneoff"
Running sh target/bin/oneoff attached to terminal... up, run.1
OneOffProcess executed.
ジョブのスケジューリング
一定の間隔または頻度に基づいてジョブを実行する必要があるアプリケーションでは、Scheduler アドオンを使用するか、Quartz などのライブラリを使用してカスタムクロックプロセスを定義することができます。
スケジュールされたジョブとワーカー
One-off プロセスのスケジューリングは、キャッシュのクリアや、メールで送信されるレポートの作成トリガーなどの管理タスクを実行するのに適した方法です。これらの種類のイベントは頻繁に発生するものではなく、スケールアップやスケールダウンの必要がありません。
ワーカープロセスは、フロントエンド Web プロセスまたは他のワーカープロセスによってキューに入れられている作業の処理に適しています。アプリへのトラフィックに応じてワークロードが変わる場合があり、ワーカー数をスケールアップすることで、より多くの作業を並列で実行できます。10 分未満の間隔でイベントを処理する必要があるだけの場合にも、ワーカープロセスを使用できます。