Shoeisha Technology Media

CodeZine(コードジン)

記事種別から探す

JavaでWebサービスを作り続けるための戦略と戦術(後編)

2018/01/26 14:00

 本連載では、株式会社ビズリーチのエンジニアが、急成長を続ける事業の中で得られた実践的なノウハウをつづります。2009年の創業以来、HRTechベンチャーとして新たな事業を展開するビズリーチ。「HRTech」は、「FinTech」や「HealthTech」と同様に、テクノロジーの力で革新する昨今のトレンドの中で、人事・採用など「HR」の領域のイノベーションとして注目されています。ビズリーチは、創業から8年で16の事業を立ち上げた経験の中で、事業課題の解決に向けた地に足の着いた技術や、最新技術を身につけてきました。これらのノウハウを発信し、業界を越えて社会に貢献していこうと考え、連載を開始しました。今回は「JavaでWebサービスを作り続けるための戦略と戦術」後編になります。

目次

バッチ処理

 ユーザーのブラウザ上での操作をトリガーとして動作するのがWebアプリケーションの基本ですが、画面操作とはまったく無関係に何らかの処理を実行する必要もあります。古いセッション情報や不要となったDBレコードを一定の間隔で破棄する機能、あらかじめ決めた時刻になったら送信するメール配信機能などです。画面処理と対比する形でバッチ処理と呼ばれることがありますが、実はバッチという単語には注意が必要です。

 バッチ処理という言葉は本来、「大きめのデータに対する、時間のかかる一括処理」といった意味あいが強いものです。しかしほとんどのWebアプリケーションシステムで必要となるのはバッチ処理というよりはスケジューリング処理です。つまりUNIXのcrontabに似た機能でしょう。Spring Frameworkを使っていると、バッチと聞いてついSpring Batchの使い方を調べ始めてしまうことがありますが、大抵の場合で必要なのはSchedulerです。

@Component
public BatchService {
    @Scheduled(cron="*/5 * * * * MON-FRI")
    public void execute() {
        // バッチ的な処理
    }
}
@Configuration
@EnableScheduling // ここがポイント
@ComponentScan(...) // BatchServiceクラスが含まれるように指定
public class AppConfig {
}

 Spring 3.1以上であれば最低限たったこれだけの設定クラスとロジッククラスで、このアプリケーションが稼働中の間、5分おきにバッチ処理が走ります。実際にはこうしたバッチ処理をまとめたWebアプリケーションとして構築し、ブラウザ向け画面のボタンでもBatch Serviceのメソッドを実行できるようにしておくと運用しやすくなります。また、念のため二重起動を防ぐようなコーディングも必要でしょう。

Javaでクラウドサービスとつきあう

 初めはクラウドと言ってもAmazon S3くらいしか使っていなかったはずのWebアプリケーションが、機能追加を続けている間にいつのまにかAmazon SESやらTwilioやら、複数のクラウドサービスに依存するようになっているのはよくあることです。AWSのサービスだけであればAWS SDK for Javaとして統制されたライブラリが提供されるので何ら心配する必要はありませんが、他のクラウドサービスが提供するJavaライブラリも同時に使おうとすると意外な問題が発生することがあります。

 com.amazonaws:aws-java-sdk-s3:1.11.119とcom.twilio.sdk:twilio-java-sdk:6.3.0はそれぞれAWSとTwilioから2017年のほぼ同時期にリリースされました。しかし、RESTエントリポイントにHTTPアクセスするために使用しているライブラリが、AWSのほうはorg.apache.httpcomponents:httpclient:4.5.2ですが、TwilioのSDKではorg.apache.httpcomponents:httpclient:4.2.6です。Apache HttpComponentsライブラリは4.3を境にAPIが大きく変更されています。ここでは詳述しませんが、これらのSDKを混同して利用すると、HTTPアクセスのライブラリはどちらか一方のみを使うことになるため、確実な挙動という意味では不安が残ってしまいます。Twilioの新系統のライブラリ(ただし下位互換性無し)に乗り換えればこの問題は無くなりますが、そうするとTwilioの古いライブラリに依存した古いコードを書き直す必要に迫られます。

 こういった問題を回避するコツは、クラウドサービス側が提供するJavaライブラリに頼りすぎないことです。ほとんどのクラウドサービスは根本的にREST APIとして公開されており、各種言語向けのライブラリはそのREST APIに対するHTTPアクセスをラップしているだけです。つまり、クラウドサービスが提供するクライアントJavaライブラリに必ずしも頼る必要はなく、REST APIに対するHTTPリクエスト処理を直接実装するだけで簡単に要求を満たせる場合があります。

 Spring Frameworkを使っている場合はHTTPアクセス処理にRestTemplateクラスを使うとよいでしょう。リクエスト処理の調整、レスポンス処理の実装をある一定のパターンに寄せることができます。また、RestTemplateはデフォルトではJava標準のHttpURLConnectionを使いますが、Apache HttpClient、Netty、OkHttpを明示的に指定してHTTP通信することもできます。何らかの理由によりライブラリ競合が発生した場合もその対策が容易です。


著者プロフィール

  • 渡辺 祐(ビズリーチ)(ワタナベ ユウ)

    電機メーカー、SIer等を経て、2014年からビズリーチへ入社。CI環境整備やアーキテクチャ全般を担当。個人では mixer2というテンプレートエンジンライブラリをOSSとして作ったり。ときどきJJUG等で講演させてもらったりしています。 twitter: @nabedge...

バックナンバー

連載:BIZREACH Developer Blog
All contents copyright © 2005-2018 Shoeisha Co., Ltd. All rights reserved. ver.1.5