Spring bootにおけるThread unsafetyなServiceとの付き合い方

はじめに

Spring bootでウェブサービスを作っていると、Thread unsafetyな@Serviceに気づくことがあります。私の場合はdeeplearning4jで極性判定技術をWebAPIにして公開しているのですが、MultiLayerNetworkがThread unsafetyであったために極性判定結果が極端にNegativeに偏る現象が起きていました。今回、その対策をしたので共有します。

2016/10/28 追記

WebAPIで公開する場合、sessionだとガトリング的にアクセスしたときに問題ありそうです。requestに統一してみます。

2016/10/28 20:30 追記

@makingさんがTwitterでコメントくださいまして、大幅に修正しました!

やること

要約すると、Thread unsafetyなクラスを@Scopeで制御します。ScopeはRequestかPrototypeにします。

@SpringBootApplication
public class HogeMain {
  public static void main(String[] args) {
    SpringApplication.run(HogeMain.class, args);
  }

  @Scope(value=WebApplicationContext.SCOPE_REQUEST, proxyMode=ScopedProxyMode.TARGET_CLASS)
  //@RequestScope //Spring boot 1.4から
  @Bean
  public Hoge hoge() {
    return new Hoge(); //こいつがThread unsafety
  }
}

何をやったかというと、@ScopeでHTTPリクエスト毎にインスタンスを作るようにしました。メモリ消費量は増えてしまいますが、Thread unsafetyの問題は解決できます。

おわりに

今回、先日公開した日本語極性判定APIがNegativeしか出力しなくなったとの報告を受けて対策を実施しました。ひとつ勉強になりました。報告いただいた ぴよまる様 ありがとうございました。ぴよまる様はAppleScriptで極性判定APIを使ってくださいまして、スクリプトを公開してくれています。こちらについてもありがとうございました!

また、Twitterで@makingさんが私の間違いを指摘し、修正箇所を教えて下さいました。たいへん参考になりました。ここで御礼申し上げます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です