Spring Boot调用接口报错:session作用域当前线程未激活
Hey there, let's break down why you're hitting this Scope 'session' is not active error when calling your /helloWorld endpoint, and how to fix it.
The Root Cause
Hystrix uses thread isolation by default—meaning when a @HystrixCommand is triggered, it spins up a new thread to execute the logic. But your oauth2ClientContext is scoped to the session, which is tied to the original web request thread. The new Hystrix thread doesn't have access to that request/session context, hence the error. Even though you added RequestContextListener, it only works for the original request thread, not the Hystrix-managed ones.
Solution 1: Switch Hystrix Isolation Strategy to Semaphore
The simplest fix is to tell Hystrix not to switch threads. Use the SEMAPHORE isolation strategy instead, which keeps execution in the original request thread.
You can set this globally in your application.yml:
hystrix: command: default: execution: isolation: strategy: SEMAPHORE
Or apply it to just your specific command:
@HystrixCommand(commandProperties = { @HystrixProperty(name = "execution.isolation.strategy", value = "SEMAPHORE") }) public String helloWorld() { // Your logic here }
Solution 2: Pass Request Context to Hystrix Threads (For Thread Isolation)
If you need to keep thread isolation (e.g., for better resource management), you can create a custom HystrixConcurrencyStrategy to copy the request context from the original thread to the Hystrix thread.
First, create the strategy class:
public class RequestContextHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy { private final HystrixConcurrencyStrategy delegate; public RequestContextHystrixConcurrencyStrategy() { try { this.delegate = HystrixPlugins.getInstance().getConcurrencyStrategy(); if (this.delegate instanceof RequestContextHystrixConcurrencyStrategy) { return; } // Reset and re-register existing plugins along with our strategy HystrixPlugins.reset(); HystrixPlugins.getInstance().registerConcurrencyStrategy(this); HystrixPlugins.getInstance().registerCommandExecutionHook(HystrixPlugins.getInstance().getCommandExecutionHook()); HystrixPlugins.getInstance().registerEventNotifier(HystrixPlugins.getInstance().getEventNotifier()); HystrixPlugins.getInstance().registerMetricsPublisher(HystrixPlugins.getInstance().getMetricsPublisher()); HystrixPlugins.getInstance().registerPropertiesStrategy(HystrixPlugins.getInstance().getPropertiesStrategy()); } catch (Exception e) { throw new RuntimeException("Failed to register RequestContext Hystrix strategy", e); } } @Override public <T> Callable<T> wrapCallable(Callable<T> callable) { // Capture the request context from the original thread RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); return () -> { try { // Set the context on the Hystrix thread RequestContextHolder.setRequestAttributes(requestAttributes); return callable.call(); } finally { // Clean up after execution RequestContextHolder.resetRequestAttributes(); } }; } // Delegate other methods to the original strategy @Override public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey, HystrixProperty<Integer> corePoolSize, HystrixProperty<Integer> maximumPoolSize, HystrixProperty<Integer> keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { return delegate.getThreadPool(threadPoolKey, corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); } @Override public BlockingQueue<Runnable> getBlockingQueue(int maxQueueSize) { return delegate.getBlockingQueue(maxQueueSize); } @Override public <T> HystrixRequestVariable<T> getRequestVariable(HystrixRequestVariableLifecycle<T> rv) { return delegate.getRequestVariable(rv); } }
Then register this bean in your Spring Boot application:
@SpringBootApplication @EnableOAuth2Sso @EnableEurekaClient public class YourAppApplication { // ... other beans @Bean public RequestContextHystrixConcurrencyStrategy requestContextHystrixConcurrencyStrategy() { return new RequestContextHystrixConcurrencyStrategy(); } public static void main(String[] args) { SpringApplication.run(YourAppApplication.class, args); } }
Double-Check Your RequestContextListener
Make sure your RequestContextListener is properly registered as a bean (not just added manually somewhere):
@Bean public RequestContextListener requestContextListener() { return new RequestContextListener(); }
This ensures the request context is available in the original thread before Hystrix takes over.
内容的提问来源于stack exchange,提问作者gstackoverflow

