使我无法定期使用Akka(使用Java)是我对使用ThreadLocals的库的一个担忧。
那就是我认为一些Akka Dispatchers可能导致ThreadLocal变量被遗忘或一起丢失。所以显而易见的解决方案是避免使用 ThreadLocals ,但有很多库使用它们:Spring,Wro4j,Log4j等等......
ThreadLocals通常在Servlet容器中正常工作。这是因为即使容器有线程池,请求主要是一个同步生命周期,因此通常在请求结束时,像Spring和Wro4J这样的东西会清除那里的threadlocals。像Tomcat这样的容器甚至可以监视线程本地泄漏。
根据我的理解,Akka的情况并非如此。
人们如何解决这个问题?
目前我只是避免使用Akka并使用Message Queue(如RabbitMQ或ActiveMQ),但希望使用Akka,因为它涵盖了更广泛的异步问题/解决方案。
我也认为Netty有类似的问题,但我相信Netty提供了一些可用于代替ThreadLocal的Channel Context对象,理论上一些库可能知道使用它而不是ThreadLocal。
答案 0 :(得分: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,因为它们并没有真正融入分布式系统。它们只在清晰划分的部分工作。