Propagating the Security Context or using Spring Scopes
https://cloud.spring.io/spring-cloud-static/Brixton.SR7/
传播安全上下文,使用Spring Security的上下文,或者使用Spring的Scope,Spring他有几种Scope,有SessionScope,
和RequestScope,还有其他的Scope
The same thing applies if you are using @SessionScope or @RequestScope. You will know when you need to
do this because of a runtime exception that says it can’t find the scoped context.
如果你想要线程本地的上下文,去传播到这个注解,我们这个@HystrixCommand,它会在线程池中执行HystrixCommand,
直接使用这种注解,让他使用不同的隔离策略
If you want some thread local context to propagate into a @HystrixCommand the default declaration
will not work because it executes the command in a thread pool (in case of timeouts).
You can switch Hystrix to use the same thread as the caller using some configuration,
or directly in the annotation, by asking it to use a different "Isolation Strategy". For example:
@HystrixCommand(fallbackMethod = "stubMyService",
commandProperties = {
@HystrixProperty(name="execution.isolation.strategy", value="SEMAPHORE")
}
)
@HystrixProperty然后用"execution.isolation.strategy",SEMAPHORE信号量
https://github.com/Netflix/Hystrix/wiki/Configuration
第一个就是
execution.isolation.strategy
这个属性表明哪一个隔离策略,这个方法去执行了隔离策略
This property indicates which isolation strategy HystrixCommand.run() executes with,
one of the following two choices:
一个是Thread,一个是SEMAPHORE
THREAD — it executes on a separate thread and concurrent requests are limited
by the number of threads in the thread-pool
SEMAPHORE — it executes on the calling thread and concurrent requests are limited
by the semaphore count
一个是线程,一个是信号量,如果你配置线程的话,他就会使用隔离的线程,如果你用信号量的话,它会用你请求的线程,
并发的请求会被信号量所限制,那我们可能就要问了,那他这个默认是什么呢,默认是Thread,默认并且推荐的配置呢,默认
并且推荐的是Thread,我们先来写个demo吧
The default, and the recommended setting, is to run HystrixCommands using thread isolation (THREAD)
and HystrixObservableCommands using semaphore isolation (SEMAPHORE).
@GetMapping("/movie/{id}")
@HystrixCommand(fallbackMethod = "findByIdFallback",
commandProperties = @HystrixProperty(name="execution.isolation.strategy", value="SEMAPHORE"))
public User findById(@PathVariable Long id) {
return this.restTemplate
.getForObject("http://microservice-simple-provider-user/simple/" + id, User.class);
}
public User findByIdFallback(Long id) {
User user = new User();
user.setId(0L);
return user;
}
这样配就意味着在一个线程里运行,请求它是一个线程,@HystrixCommand它是一个隔离的线程,就这样的区别,@SessionScope,
Spring的Bean他有几种Scope,这是@SessionScope,其实就等同于Scope里面的Session,
acts as a shortcut for {@code @Scope("session")} with the default
<p>In this context, <em>scope</em> means the lifecycle of an instance,
such as {@code singleton}, {@code prototype}, and so forth. Scopes
provided out of the box in Spring may be referred to using the
{@code SCOPE_*} constants available in the {@link ConfigurableBeanFactory}
and {@code WebApplicationContext} interfaces.
他有singleton,prototype,还有sessionScope,requestScope,还有global session,就是application,
如果你使用session scope和request scope,你会知道你什么时候需要这样做,因为那个时候会报一个
运行时异常,假如他找不到scope context,这个时候你可以配
HystrixProperty(name="execution.isolation.strategy", value="SEMAPHORE")
你还可以把属性设为true,你可以配置Hystrix并发的策略,Hystrix不允许多个线程的策略,不允许注册多个
并发策略,Spring Cloud会在SPRING的上下文查找实现,并且将它包装到自己的插件中,
https://cloud.spring.io/spring-cloud-netflix/reference/html/#netflix-eureka-client-starter
You also have the option to set the hystrix.shareSecurityContext property to true. Doing so
auto-configures a Hystrix concurrency strategy plugin hook to transfer the SecurityContext
from your main thread to the one used by the Hystrix command. Hystrix does not let multiple
Hystrix concurrency strategy be registered so an extension mechanism is available by declaring
your own HystrixConcurrencyStrategy as a Spring bean. Spring Cloud looks for your implementation
within the Spring context and wrap it inside its own plugin.
https://cloud.spring.io/spring-cloud-netflix/reference/html/#netflix-eureka-client-starter
https://github.com/spring-cloud/spring-cloud-netflix/issues/1330
FEIGN + OAUTH2 calls from another thread not propagating security #1330
Hi there, checkout the reference doc on 1.2.0.M1. A new property hystrix.shareSecurityContext=true
will auto configure an Hyxtrik hook that will propagate the security context to the thread of
your Hystrix command. Let me know if it fits your need.
你可以查看一下官方文档,在1.2.0MineStone,里程碑,那时候还不是正式版本,有一个新的属性,
hystrix.shareSecurityContext=true
它会自动配置Hystrix的一个钩子,如果这个属性满足你这个需求,告诉我一下,什么叫SecurityContext呢,就是Spring
Security的上下文,他就叫securityContext,
https://github.com/spring-cloud/spring-cloud-netflix/issues/1336
Hystrix shareSecurityContext is not working #1336
Spring Security
BTW, I don't see Spring Security Starter in your gradle. The hystrix.shareSecurityContext will be
effective if Spring Security is present in the classpath. Share a sample project and I'll see if
there is any means to adapt the mechanism specially for Spring Cloud OAuth without depending on
Spring Security.
正常是不要去配置,等到抛异常了再去配置
package com.learn.cloud.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.learn.cloud.entity.User;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
@RestController
public class MovieController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/movie/{id}")
@HystrixCommand(fallbackMethod = "findByIdFallback", commandProperties = @HystrixProperty(name="execution.isolation.strategy", value="SEMAPHORE"))
public User findById(@PathVariable Long id) {
return this.restTemplate.getForObject("http://microservice-simple-provider-user/simple/" + id, User.class);
}
public User findByIdFallback(Long id) {
User user = new User();
user.setId(0L);
return user;
}
}