13

私が(Javaで)Akkaを定期的に使用することを妨げているのは、ThreadLocalsを使用するライブラリに関する懸念です。

つまり、一部のAkkaディスパッチャーは、ThreadLocal変数が取り残されたり、すべて一緒に欠落したりする可能性があると思います。したがって、明らかな解決策はThreadLocalsの使用を避けることですが、それらを使用するライブラリは非常に多くあります:Spring、Wro4j、Log4jなど...

ThreadLocalsは通常、サーブレットコンテナで正常に機能します。これは、コンテナにスレッドプールがある場合でも、リクエストは主に同期ライフサイクルであるため、通常、リクエストの最後に、SpringやWro4Jなどがスレッドローカルをクリーンアップします。Tomcatのような一部のコンテナは、スレッドローカルリークを監視します。

私が理解していることから、Akkaではそうではありません。

人々はこの問題をどのように回避しますか?

今のところ、Akkaの使用を避け、メッセージキュー(RabbitMQやActiveMQなど)を使用していますが、非同期の問題/解決策の範囲が広いため、Akkaを使用したいと思います。

Nettyにも同様の問題があると思いますが、Nettyは、ThreadLocalの代わりに使用できるある種のChannel Contextオブジェクトを提供していると思います。理論的には、一部のライブラリはThreadLocalの代わりにそれを使用することを知っているかもしれません。

4

1 に答える 1

3

これを解決する最も簡単な方法は、ThreadLocalsの使用を区別することです。そのため、次のようにメソッドを作成します。

def withSecurityContext[T](thunk: => T)(implicit secCtx: SecurityContextFetcher): T = {
  val old = threadLocalSecurityContext.get
  threadLocalSecurityContext.set(secCtx.fetch)
  try thunk finally threadLocalSecurityContext.set(old)
}

次に、俳優の内部など:

class MyActor extends Actor {
    def receive = {
      case "foo" => withSecurityContext { beAwesome() }
    }
}

ただし、一般的には、ThreadLocalsは分散システムと実際には融合しないため、避けたいと思います。それらは明確に区切られたセクションでのみ機能します。

于 2012-11-04T16:04:14.307 に答える