📌 はじめに
Spring Boot でタスクを定期実行させるやり方はたくさん公開されていますが、 Kotlin でっていう記事はあまり見受けられなかったので公開することにしました。
ただし、 Java で実装する時とほとんど何も変わりません🙄
Kotlinの勉強がてらに何か作りたいって時にはちょうど良いかもしれません!
今回は Heroku で本番公開するところまでやってみようと思います。
📌 前提条件(環境情報)
対象 | バージョン |
---|---|
macOS | Sierra 10.12.6 |
Java | 1.8.0_121 |
Kotlin | 1.2.71 |
Spring Boot | 2.1.1.RELEASE |
📌 実際に作る
ではさっそく、 Kotlin + Spring Boot でタスクの定期実行を実装していきます。
1. SPRING INITIALIZR で Project 作成
まずは Spring Boot のプロジェクトフォルダを作成します。
SPRING INITIALIZR にアクセスし、画面上側にあるプルダウンを以下のように選択します。
Generate a [Gradle Project] with [Kotlin] and Spring Boot [2.1.1]
次に、 Project Metadata を設定します。
ここは自由に命名してもらってかまいません。
Group | Artifact |
---|---|
生成されるソースのパッケージ名。 | アプリケーションの名前。ディレクトリ名に使われる。 |
最後に、 Dependencies (依存ライブラリ)を設定します。
検索ワードを入力すると、依存ライブラリの候補が表示されるので、以下のものを選択します。
検索ワード | 選択項目 | 何に使うか |
---|---|---|
cloud task | Cloud Task | タスクの定期実行 |
こんな感じになっていればOKです。
上記内容の設定がすべて終わったら、「Generate Project」ボタンでプロジェクトフォルダをzipファイルでダウンロードします。
zipファイルを解凍してお好みのディレクトリに配置してください。
2. アプリケーションクラスをタスクの定期実行(スケジューリング)に対応させる
main の処理があるアプリケーションクラスで、タスクの定期実行をするための準備を行います。
EnableScheduling
をインポートし、クラスにアノテーションを追加します。
/src/main/kotlin/com/marei/springbootkotlinbatch/SpringbootKotlinBatchApplication.kt
package com.marei.springbootkotlinbatch import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.runApplication import org.springframework.scheduling.annotation.EnableScheduling // ← 追加 @SpringBootApplication @EnableScheduling // ← 追加 class SpringbootKotlinBatchApplication fun main(args: Array<String>) { runApplication<SpringbootKotlinBatchApplication>(*args) }
こちらのアノテーションを追加することで、後に実装するタスクが実行されるようになります。
3. タスク処理を実装する
実際に実行したいタスク処理を記述するクラスを作成します。
※クラス名は何でも良い
/src/main/kotlin/com/marei/springbootkotlinbatch/BatchTasks.kt
package com.marei.springbootkotlinbatch import org.springframework.scheduling.annotation.Scheduled import org.springframework.stereotype.Component @Component class BatchTasks { // initialDelay:アプリケーションが起動してから何秒後に実行するか(ミリ秒指定) // fixedDelay:何秒ごとに処理を実行するか(ミリ秒指定) // アプリケーション起動5秒後と10秒間隔で実行 @Scheduled(initialDelay = 5000, fixedDelay = 10000) fun helloWorld() { println("はろー、わーるど!") } // cron:cron 記法で実行時間を指定 // zone:cron の起動時間のタイムゾーンを指定 // 毎日00時00分00秒に実行 @Scheduled(cron = "0 0 0 * * *", zone = "Asia/Tokyo") fun helloWorld2() { println("はろー、わーるど!2") } }
@Scheduled
アノテーションを付けたメソッドが、実際にタスクとして実行されるメソッドになります。
本記事での詳細な説明は省略しますが、こちらの記事が大変参考になります。
4. 動作確認
ここまで実装すれば、もうタスクを定期実行する準備は整いました。
それでは、アプリケーションを起動して動作を確認してみましょう!
アプリケーションのディレクトリ配下で下記を実行します。
./gradlew bootRun
すると、下記のようになり、「はろー、わーるど!」と表示されれば成功です🎉
※初回はインストールが実行されるので少し時間がかかります。
$ ./gradlew bootRun > Task :bootRun . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.1.1.RELEASE) 2018-12-03 16:03:39.096 INFO 62374 --- [ main] c.m.s.SpringbootKotlinBatchApplicationKt : Starting SpringbootKotlinBatchApplicationKt on TESPC-084.local with PID 62374 (/Users/r-hashimoto/project/private/springboot-kotlin-batch/build/classes/kotlin/main started by r-hashimoto in /Users/r-hashimoto/project/private/springboot-kotlin-batch) 2018-12-03 16:03:39.102 INFO 62374 --- [ main] c.m.s.SpringbootKotlinBatchApplicationKt : No active profile set, falling back to default profiles: default 2018-12-03 16:03:41.464 INFO 62374 --- [ main] o.s.s.c.ThreadPoolTaskScheduler : Initializing ExecutorService 'taskScheduler' 2018-12-03 16:03:41.910 INFO 62374 --- [ main] c.m.s.SpringbootKotlinBatchApplicationKt : Started SpringbootKotlinBatchApplicationKt in 3.574 seconds (JVM running for 4.495) はろー、わーるど! はろー、わーるど! はろー、わーるど! <==========---> 80% EXECUTING [34s] > :bootRun
※ Ctrl + C で停止
📌 Heroku で公開する
ひたすら「はろー、わーるど!」を出力するだけのタスクですが、 Heroku を利用して本番環境にデプロイしてみましょう。
jp.heroku.com (え、てか、いつの間にか日本語対応してるじゃんやば、感動😭)
1. Git の管理下にする
Heroku にデプロイする際にブランチ単位でデプロイすることになります。
※こちらの作業は Git がインストールされている前提です。
まずは、 Git の管理下にします。
git init
実装した内容をステージングに上げます。
git add .
コミットします。
git commit -m "Kotlin + Spring Boot でタスクの定期実行"
これで デプロイする用の master ブランチが完成しました。
2. Heroku CLI をインストールする
私は Mac 環境なので brew でインストールしますが、別の方法もあるので公式サイトを参考にしてください。
brew install heroku/brew/heroku
3. Heroku でアプリケーションを作成する
Kotlin + Spring Boot で作ったタスクを定期実行するアプリケーションを Heroku のアプリケーションとして作成します。
heroku create springboot-kotlin-batch
※ springboot-kotlin-batch
は自分のアプリケーション名です。
この時、ブラウザが開きログインを求められると思います。
アカウントがあればログインし、無ければそのまま作成してください。
ブラウザでのログインに成功すると、アプリケーションの作成も自動で完了します。
$ heroku create springboot-kotlin-batch Creating ⬢ springboot-kotlin-batch... ! ▸ Invalid credentials provided. heroku: Press any key to open up the browser to login or q to exit: › Warning: If browser does not open, visit https://cli-auth.heroku.com/auth/browser/c045769b-ea2c-43cd-94ff-eaca3d4ffab3 Logging in... done Logged in as メールアドレス Creating ⬢ springboot-kotlin-batch... done https://springboot-kotlin-batch.herokuapp.com/ | https://git.heroku.com/springboot-kotlin-batch.git
4. Heroku にデプロイする
それでは、先程 Git 管理下においたソースを Heroku にデプロイしてみましょう! Heroku に push するだけでデプロイが実行されます。
git push heroku master
デプロイが完了するとこんな感じになると思います。
$ git push heroku master Counting objects: 28, done. Delta compression using up to 4 threads. Compressing objects: 100% (17/17), done. Writing objects: 100% (28/28), 55.33 KiB | 9.22 MiB/s, done. Total 28 (delta 0), reused 0 (delta 0) remote: Compressing source files... done. remote: Building source: remote: remote: -----> Gradle app detected remote: -----> Spring Boot detected remote: -----> Installing JDK 1.8... done remote: -----> Building Gradle app... remote: -----> executing ./gradlew build -x test remote: Downloading https://services.gradle.org/distributions/gradle-4.10.2-bin.zip remote: .......................................................................... remote: remote: Welcome to Gradle 4.10.2! remote: remote: Here are the highlights of this release: remote: - Incremental Java compilation by default remote: - Periodic Gradle caches cleanup remote: - Gradle Kotlin DSL 1.0-RC6 remote: - Nested included builds remote: - SNAPSHOT plugin versions in the `plugins {}` block remote: remote: For more details see https://docs.gradle.org/4.10.2/release-notes.html remote: remote: > Task :compileKotlin remote: > Task :compileJava NO-SOURCE remote: > Task :processResources remote: > Task :classes remote: > Task :bootJar remote: > Task :inspectClassesForKotlinIC remote: > Task :jar SKIPPED remote: > Task :assemble remote: > Task :check remote: > Task :build remote: remote: BUILD SUCCESSFUL in 33s remote: 4 actionable tasks: 4 executed remote: -----> Discovering process types remote: Procfile declares types -> (none) remote: Default types for buildpack -> web remote: remote: -----> Compressing... remote: Done: 62.4M remote: -----> Launching... remote: Released v3 remote: https://springboot-kotlin-batch.herokuapp.com/ deployed to Heroku remote: remote: Verifying deploy... done. To https://git.heroku.com/springboot-kotlin-batch.git * [new branch] master -> master
5. 動作確認
デプロイが完了したので、既にアプリケーションの実行が開始されているはずです。
Heroku のログを見て確認してみましょう。
heroku logs -t
「はろー、わーるど!」と出ていれば成功です🎉
$ heroku logs -t 2018-12-03T07:39:14.182175+00:00 app[api]: Initial release by user 自分のメールアドレス 2018-12-03T07:39:14.182175+00:00 app[api]: Release v1 created by user 自分のメールアドレス 2018-12-03T07:39:14.401472+00:00 app[api]: Release v2 created by user 自分のメールアドレス 2018-12-03T07:39:14.401472+00:00 app[api]: Enable Logplex by user 自分のメールアドレス 2018-12-03T07:43:06.000000+00:00 app[api]: Build started by user 自分のメールアドレス 2018-12-03T07:43:50.728881+00:00 app[api]: Deploy 73bb6fa3 by user 自分のメールアドレス 2018-12-03T07:43:50.728881+00:00 app[api]: Release v3 created by user 自分のメールアドレス 2018-12-03T07:43:50.745994+00:00 app[api]: Scaled to web@1:Free by user 自分のメールアドレス 2018-12-03T07:43:55.224660+00:00 heroku[web.1]: Starting process with command `java -Dserver.port=34349 $JAVA_OPTS -jar build/libs/*.jar` 2018-12-03T07:43:57.543451+00:00 app[web.1]: Create a Procfile to customize the command used to run this process: https://devcenter.heroku.com/articles/procfile 2018-12-03T07:43:57.588489+00:00 app[web.1]: Setting JAVA_TOOL_OPTIONS defaults based on dyno size. Custom settings will override them. 2018-12-03T07:43:57.595830+00:00 app[web.1]: Picked up JAVA_TOOL_OPTIONS: -Xmx300m -Xss512k -XX:CICompilerCount=2 -Dfile.encoding=UTF-8 2018-12-03T07:44:01.278185+00:00 app[web.1]: 2018-12-03T07:44:01.278249+00:00 app[web.1]: . ____ _ __ _ _ 2018-12-03T07:44:01.278283+00:00 app[web.1]: /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ 2018-12-03T07:44:01.278339+00:00 app[web.1]: ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ 2018-12-03T07:44:01.278404+00:00 app[web.1]: \\/ ___)| |_)| | | | | || (_| | ) ) ) ) 2018-12-03T07:44:01.278454+00:00 app[web.1]: ' |____| .__|_| |_|_| |_\__, | / / / / 2018-12-03T07:44:01.278520+00:00 app[web.1]: =========|_|==============|___/=/_/_/_/ 2018-12-03T07:44:01.294856+00:00 app[web.1]: :: Spring Boot :: (v2.1.1.RELEASE) 2018-12-03T07:44:01.294881+00:00 app[web.1]: 2018-12-03T07:44:01.648240+00:00 app[web.1]: 2018-12-03 07:44:01.634 INFO 4 --- [ main] c.m.s.SpringbootKotlinBatchApplicationKt : Starting SpringbootKotlinBatchApplicationKt on d67c7ffc-1c9b-4090-b075-17cee0909c26 with PID 4 (/app/build/libs/springboot-kotlin-batch-0.0.1-SNAPSHOT.jar started by u57903 in /app) 2018-12-03T07:44:01.649378+00:00 app[web.1]: 2018-12-03 07:44:01.649 INFO 4 --- [ main] c.m.s.SpringbootKotlinBatchApplicationKt : No active profile set, falling back to default profiles: default 2018-12-03T07:44:02.000000+00:00 app[api]: Build succeeded 2018-12-03T07:44:06.409003+00:00 app[web.1]: 2018-12-03 07:44:06.408 INFO 4 --- [ main] o.s.s.c.ThreadPoolTaskScheduler : Initializing ExecutorService 'taskScheduler' 2018-12-03T07:44:07.031812+00:00 app[web.1]: 2018-12-03 07:44:07.031 INFO 4 --- [ main] c.m.s.SpringbootKotlinBatchApplicationKt : Started SpringbootKotlinBatchApplicationKt in 7.15 seconds (JVM running for 9.433) 2018-12-03T07:44:12.019978+00:00 app[web.1]: はろー、わーるど! 2018-12-03T07:44:22.020616+00:00 app[web.1]: はろー、わーるど! 2018-12-03T07:44:32.021084+00:00 app[web.1]: はろー、わーるど!
以上ですべての作業が完了です。
おつかれさまでした!
📌 さいごに
やってみると分かりますが、本番公開まで手軽に一瞬でできてしまうのが素晴らしいですね。
Heroku は無料プランなのでお金もかかりません。
単純にバッチ処理の実行として使うこともできますが、その他に Twitter のボットや LINE のボットなどでも利用できそうです。
※ Twitter はアプリケーションを作成するのに審査が厳しくなってしまいましたが…。
近々、 LINE のボットは作ってみようと思うので、またその時に行ったことを記事にしようと思います。
さいごに、今回作成したアプリケーションを GitHub で公開します。