この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
SpringBootでバッチ処理をするプロジェクトを作り、EC2上で動作させたいと思ったのですが、所々はまったので自分用にメモします。
環境
Spring Tool Suite 3.8.0
概要
今回やってみる内容はまとめると以下の様な作業になります。
・SpringBootで定期的にS3のリソースを取得して中身を表示するプログラムを書く
・jarファイルにしてEC2にアップロード
・EC2上で実行
実装
まずはコード
BlogProjectApplication.java
@SpringBootApplication
@EnableScheduling
public class BlogProjectApplication {
public static void main(String[] args) {
SpringApplication.run(BlogProjectApplication.class, args);
}
}
自動生成されたコードなので、特に説明は不要だと思いますが、2行目はScheduledService.javaで定時実行するために必要なアノテーションです。
ScheduledService.java
@Service
public class ScheduledService {
@Autowired
GetS3Object getS3Object;
@Scheduled(cron = "0 * * * * *", zone = "Asia/Tokyo")
public void fixedRate(){
getS3Object.showS3Object();
}
}
ここでバッチ処理をしていますが、単純に毎分showS3Objectを実行しているだけです。
バッチ処理については詳しく書きませんのでこちらをご覧ください
コピペでできる3ステップお手軽バッチ処理
GetS3Object.java
@Component
public class GetS3Object {
public void showS3Object(){
AmazonS3 amazonS3 = new AmazonS3Client();
S3Object s3Object = amazonS3.getObject("BUCKET_NAME", "FILENAME");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(s3Object.getObjectContent()));
StringBuilder stringBuilder = new StringBuilder();
String line;
try {
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(stringBuilder.toString());
}
}
7行目のgetObjectの第1引数がS3のバケット名、第2引数がファイル名になります。
build.gradle
buildscript {
ext {
springBootVersion = '1.4.0.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'spring-boot'
jar {
baseName = 'BlogProject'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile 'com.amazonaws:aws-java-sdk:+'
compile('org.springframework.boot:spring-boot-starter')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
eclipse {
classpath {
containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER')
containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8'
}
}
build.gradleの18行目でエクスポートするファイル名を指定して、29行目でAWS SDK for Javaを使うために記述しています。
jarファイルをエクスポート
このプロジェクトをビルドするとプロジェクトルートのbuld/libs以下にjarタスク(build.gradleの17-19行)で指定された名前でjarファイルが作成されます。(今回の場合だとBlogProject.jar)
アップロード
このファイルをEC2にアップロードします。 方法はいろいろあると思いますが今回僕はscpコマンドを使いました。
$ scp -i 秘密鍵のパス 送信するファイルのパス ユーザ名@EC2インスタンスのパブリックIPアドレス:ファイルを配置するパス
わかりにくいかもしれないので例を書くと以下のようになります
$ scp -i /Desktop/utsunomiya.pem /Desktop/BlogProject/build/libs/BlogProject.jar ec2-user@53.238.xx.xxx:/home/ec2-user/
実行
S3のファイルが全員に公開されていればこの時点で
$ java -jar /home/ec2-user/BlogProject.jar
とコマンドを打てば実行できます。
最後に
扱うファイルが公開されているものとは限りませんので、S3のファイルは認証済みユーザーのみに公開されている想定でもやってみました。
[SpringBoot] エクスポートしたjarファイルをEC2上で実行する 〜非公開のS3にアクセス〜