Spring HttpServletRequest在HystrixCommand中不可访问
在Javanica注释的Spring HttpServletRequest在HystrixCommand中不可访问,spring,hystrix,Spring,Hystrix,在Javanica注释的@HystrixCommand中,我们通过检查以下内容来检查请求是否在实际的HTTP servlet请求中: RequestContextHolder.getRequestAttributes() != null; 但是,从@HystrixCommand调用时,即使请求来自Spring MVC请求,该条件始终为false 如果我删除@HystrixCommand注释,一切正常。 我们还尝试直接使用HttpServletRequest,这很好(没有@HystrixComm
@HystrixCommand
中,我们通过检查以下内容来检查请求是否在实际的HTTP servlet请求中:
RequestContextHolder.getRequestAttributes() != null;
但是,从@HystrixCommand
调用时,即使请求来自Spring MVC请求,该条件始终为false
如果我删除@HystrixCommand
注释,一切正常。
我们还尝试直接使用HttpServletRequest
,这很好(没有@HystrixCommand
):
对于带注释的@HystrixCommand
,我们面临异常,表明我不在有效的HttpServletRequest
中。我知道这是由于Hystrix在其自身线程池的不同线程中运行命令,并尝试这样做,但也不起作用:
public class RequestServletFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// No Impl
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HystrixRequestContext context = HystrixRequestContext.initializeContext();
try {
chain.doFilter(request, response);
} finally {
context.shutdown();
}
}
@Override
public void destroy() {
// No Impl
}
有人知道如何将SpringHttpServletRequest
委托给HystrixCommands吗
非常感谢您的帮助。在使用
RequestContextHolder
时,默认情况下不会共享it参数(有充分的理由!)
假设您使用的是DispatcherServlet
来处理请求,您可以将其[threadContextInheritable
]设置为true
,以便在请求之间共享RequestContext
和LocaleContext
这同样适用于RequestContextFilter
,而RequestContextListener
则不可能
<强>注:< /强>我将考虑在线程之间共享<代码> HttpServletRequest <代码>作为你不应该做的事情,并且应该非常小心地做!p> 嗯。。。在访问请求时,实际上一点也不臭吗?感觉您正在尝试做一些您不应该做的事情。我们的应用程序服务于不同的国家(客户端),因此,在构建REST URL以从第三方后端检索数据时,必须在URL中考虑客户端。因此,我们将此客户机处理委托给一个定制的ClientContext.java,我们可以根据需要自动连接它。这只是为了舒适性,否则我们需要在任何地方循环客户端,这是一件痛苦的事情。但是,将
HttpServletRequest
注入@HystrixCommand
注释方法又有什么关系呢?也很高兴知道你使用的是普通的Hystrix还是弹簧云包裹的?我想说的是,您的ClientContext
应该与请求分离(您可能希望根据传入的请求创建它,但之后不应再依赖它)。这将使共享对象(我希望是只读的)变得更容易。我们不直接在@HystrixCommand注释存储库中自动连接HttpServletRequest,而是在ClientContext中自动连接。ClientContext通过提供方法getRequestSpecificClient()来使用HttpServletRequest;如果没有可用的HttpServletRequest,则此方法返回null。在本例中有,但由于分离的HystrixCommand线程,它仍然返回null。解决方法是只检查服务中的当前客户端,然后将客户端路由到任何地方。但正如我所说的,这是不现实的,这就是为什么我建议无论当前请求与否,ClientContext
都应该工作的原因。这可能取决于RequestContextHolder
,它是一个ThreadLocal
。IMHO您应该使用所需的属性来填充ClientContext
。如果您使用它来访问代码库中任何地方的当前请求,我会说这是一种气味。我假设当您开始使用Hystrix中的RequestCollasing时,将HttpServletRequest共享给HystrixCommand会变得很混乱。
public class RequestServletFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// No Impl
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HystrixRequestContext context = HystrixRequestContext.initializeContext();
try {
chain.doFilter(request, response);
} finally {
context.shutdown();
}
}
@Override
public void destroy() {
// No Impl
}