Spring HttpServletRequest在HystrixCommand中不可访问

Spring HttpServletRequest在HystrixCommand中不可访问,spring,hystrix,Spring,Hystrix,在Javanica注释的@HystrixCommand中,我们通过检查以下内容来检查请求是否在实际的HTTP servlet请求中: RequestContextHolder.getRequestAttributes() != null; 但是,从@HystrixCommand调用时,即使请求来自Spring MVC请求,该条件始终为false 如果我删除@HystrixCommand注释,一切正常。 我们还尝试直接使用HttpServletRequest,这很好(没有@HystrixComm

在Javanica注释的
@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
}
有人知道如何将Spring
HttpServletRequest
委托给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
}