Skip to content

Commit e5632e1

Browse files
committed
修复bug,优化代码, 拆分插件
1 parent 78eb0ed commit e5632e1

File tree

151 files changed

+8383
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

151 files changed

+8383
-0
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package cn.springcloud.gray.client.netflix;
2+
3+
import cn.springcloud.gray.GrayManager;
4+
import cn.springcloud.gray.ServerChooser;
5+
import cn.springcloud.gray.ServerListResult;
6+
import cn.springcloud.gray.choose.GrayPredicate;
7+
import cn.springcloud.gray.model.GrayService;
8+
import cn.springcloud.gray.request.GrayRequest;
9+
import cn.springcloud.gray.request.RequestLocalStorage;
10+
import cn.springcloud.gray.servernode.ServerExplainer;
11+
import cn.springcloud.gray.servernode.ServerListProcessor;
12+
import cn.springcloud.gray.servernode.ServerSpec;
13+
import com.netflix.loadbalancer.Server;
14+
15+
import java.util.ArrayList;
16+
import java.util.List;
17+
import java.util.stream.Collectors;
18+
19+
public class RibbonServerChooser implements ServerChooser<Server> {
20+
21+
private GrayManager grayManager;
22+
23+
private RequestLocalStorage requestLocalStorage;
24+
25+
private GrayPredicate grayPredicate;
26+
27+
private ServerExplainer<Server> serverExplainer;
28+
29+
protected ServerListProcessor serverListProcessor;
30+
31+
32+
public RibbonServerChooser(
33+
GrayManager grayManager,
34+
RequestLocalStorage requestLocalStorage,
35+
GrayPredicate grayPredicate,
36+
ServerExplainer<Server> serverExplainer,
37+
ServerListProcessor serverListProcessor) {
38+
this.grayManager = grayManager;
39+
this.requestLocalStorage = requestLocalStorage;
40+
this.grayPredicate = grayPredicate;
41+
this.serverExplainer = serverExplainer;
42+
this.serverListProcessor = serverListProcessor;
43+
}
44+
45+
@Override
46+
public boolean matchGrayDecisions(ServerSpec serverSpec) {
47+
return grayPredicate.apply(serverSpec);
48+
}
49+
50+
@Override
51+
public boolean matchGrayDecisions(Server server) {
52+
return matchGrayDecisions(serverExplainer.apply(server));
53+
}
54+
55+
@Override
56+
public ServerListResult<Server> distinguishServerList(List<Server> servers) {
57+
GrayRequest grayRequest = requestLocalStorage.getGrayRequest();
58+
if (grayRequest == null) {
59+
return null;
60+
}
61+
62+
return distinguishServerList(grayRequest.getServiceId(), servers);
63+
}
64+
65+
66+
@Override
67+
public ServerListResult<Server> distinguishAndMatchGrayServerList(List<Server> servers) {
68+
ServerListResult<Server> serverListResult = distinguishServerList(servers);
69+
if (serverListResult == null) {
70+
return null;
71+
}
72+
73+
serverListResult.setGrayServers(
74+
serverListResult.getGrayServers().stream()
75+
.filter(this::matchGrayDecisions)
76+
.collect(Collectors.toList()));
77+
78+
return serverListResult;
79+
}
80+
81+
82+
private ServerListResult<Server> distinguishServerList(String serviceId, List<Server> servers) {
83+
if (!grayManager.hasGray(serviceId)) {
84+
return null;
85+
}
86+
87+
GrayService grayService = grayManager.getGrayService(serviceId);
88+
List<Server> serverList = serverListProcessor.process(serviceId, servers);
89+
List<Server> grayServers = new ArrayList<>(grayService.getGrayInstances().size());
90+
List<Server> normalServers = new ArrayList<>(Math.min(servers.size(), grayService.getGrayInstances().size()));
91+
92+
for (Server server : serverList) {
93+
if (grayService.getGrayInstance(server.getMetaInfo().getInstanceId()) != null) {
94+
grayServers.add(server);
95+
} else {
96+
normalServers.add(server);
97+
}
98+
}
99+
100+
return new ServerListResult<>(serviceId, grayServers, normalServers);
101+
}
102+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package cn.springcloud.gray.client.netflix.configuration.properties;
2+
3+
4+
import lombok.Data;
5+
import org.springframework.boot.context.properties.ConfigurationProperties;
6+
7+
@Data
8+
@ConfigurationProperties("gray.hystrix")
9+
public class GrayHystrixProperties {
10+
private boolean enabled;
11+
12+
private ThreadTransmitStrategy threadTransmitStrategy = ThreadTransmitStrategy.WRAP_CALLABLE;
13+
14+
public static enum ThreadTransmitStrategy {
15+
WRAP_CALLABLE, HYSTRIX_REQUEST_LOCAL_STORAGE
16+
}
17+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package cn.springcloud.gray.client.netflix.hystrix;
2+
3+
4+
import cn.springcloud.gray.concurrent.GrayCallable;
5+
import cn.springcloud.gray.concurrent.GrayConcurrentHelper;
6+
import com.netflix.hystrix.HystrixThreadPoolKey;
7+
import com.netflix.hystrix.HystrixThreadPoolProperties;
8+
import com.netflix.hystrix.strategy.HystrixPlugins;
9+
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
10+
import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariable;
11+
import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariableLifecycle;
12+
import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier;
13+
import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook;
14+
import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisher;
15+
import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy;
16+
import com.netflix.hystrix.strategy.properties.HystrixProperty;
17+
18+
import java.util.concurrent.BlockingQueue;
19+
import java.util.concurrent.Callable;
20+
import java.util.concurrent.ThreadPoolExecutor;
21+
import java.util.concurrent.TimeUnit;
22+
23+
public class GrayHystrixContextConcurrencyStrategy extends HystrixConcurrencyStrategy {
24+
private HystrixConcurrencyStrategy delegate;
25+
26+
public GrayHystrixContextConcurrencyStrategy() {
27+
this.delegate = HystrixPlugins.getInstance().getConcurrencyStrategy();
28+
if (this.delegate instanceof GrayHystrixContextConcurrencyStrategy) {
29+
return;
30+
}
31+
// Keeps references of existing Hystrix plugins.
32+
HystrixCommandExecutionHook commandExecutionHook = HystrixPlugins.getInstance().getCommandExecutionHook();
33+
HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance().getEventNotifier();
34+
HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance().getMetricsPublisher();
35+
HystrixPropertiesStrategy propertiesStrategy = HystrixPlugins.getInstance().getPropertiesStrategy();
36+
37+
HystrixPlugins.reset();
38+
39+
// Registers existing plugins excepts the Concurrent Strategy plugin.
40+
HystrixPlugins.getInstance().registerConcurrencyStrategy(this);
41+
HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook);
42+
HystrixPlugins.getInstance().registerEventNotifier(eventNotifier);
43+
HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher);
44+
HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy);
45+
}
46+
47+
@Override
48+
public BlockingQueue<Runnable> getBlockingQueue(int maxQueueSize) {
49+
return delegate.getBlockingQueue(maxQueueSize);
50+
}
51+
52+
@Override
53+
public <T> HystrixRequestVariable<T> getRequestVariable(HystrixRequestVariableLifecycle<T> rv) {
54+
return delegate.getRequestVariable(rv);
55+
}
56+
57+
@Override
58+
public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey, HystrixProperty<Integer> corePoolSize, HystrixProperty<Integer> maximumPoolSize, HystrixProperty<Integer> keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
59+
return delegate.getThreadPool(threadPoolKey, corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
60+
}
61+
62+
@Override
63+
public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey, HystrixThreadPoolProperties threadPoolProperties) {
64+
return delegate.getThreadPool(threadPoolKey, threadPoolProperties);
65+
}
66+
67+
@Override
68+
public <T> Callable<T> wrapCallable(Callable<T> callable) {
69+
Callable<T> delegateWrapCallable = delegate.wrapCallable(callable);
70+
if(delegateWrapCallable instanceof GrayCallable){
71+
return delegateWrapCallable;
72+
}
73+
return GrayConcurrentHelper.createDelegateCallable(delegateWrapCallable);
74+
}
75+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package cn.springcloud.gray.client.netflix.ribbon;
2+
3+
import cn.springcloud.gray.GrayClientHolder;
4+
import cn.springcloud.gray.ServerChooser;
5+
import com.google.common.base.Optional;
6+
import com.netflix.loadbalancer.Server;
7+
import com.netflix.loadbalancer.ZoneAvoidanceRule;
8+
9+
public class GrayChooserRule extends ZoneAvoidanceRule {
10+
11+
private ServerChooser<Server> serverChooser;
12+
13+
public GrayChooserRule() {
14+
serverChooser = GrayClientHolder.getServerChooser();
15+
}
16+
17+
@Override
18+
public Server choose(Object key) {
19+
return serverChooser.chooseServer(getLoadBalancer().getAllServers(), servers -> {
20+
Optional<Server> server = getPredicate().chooseRoundRobinAfterFiltering(servers, key);
21+
if (server.isPresent()) {
22+
return server.get();
23+
} else {
24+
return null;
25+
}
26+
});
27+
}
28+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package cn.springcloud.gray;
2+
3+
import cn.springcloud.gray.choose.ListChooser;
4+
import cn.springcloud.gray.servernode.ServerSpec;
5+
import org.apache.commons.collections.CollectionUtils;
6+
7+
import java.util.List;
8+
9+
public interface ServerChooser <Server> {
10+
11+
boolean matchGrayDecisions(ServerSpec serverSpec);
12+
13+
boolean matchGrayDecisions(Server server);
14+
15+
/**
16+
* 区分灰度实例和正常实例
17+
* @param servers
18+
* @return 返回区分后的结果,如果关闭灰度开关,将会返回null
19+
*/
20+
ServerListResult<Server> distinguishServerList(List<Server> servers);
21+
22+
23+
24+
/**
25+
* 区分灰度实例和正常实例,并比对灰度实例的灰度决策
26+
* @param servers
27+
* @return 返回区分及比对后的结果,如果关闭灰度开关,将会返回null
28+
*/
29+
ServerListResult<Server> distinguishAndMatchGrayServerList(List<Server> servers);
30+
31+
32+
33+
default Server chooseServer(List<Server> servers, ListChooser<Server> chooser){
34+
ServerListResult<Server> serverListResult = distinguishAndMatchGrayServerList(servers);
35+
if(serverListResult==null){
36+
return chooser.choose(servers);
37+
}
38+
39+
if(CollectionUtils.isNotEmpty(serverListResult.getGrayServers())){
40+
Server server = chooser.choose(serverListResult.getGrayServers());
41+
if(server!=null){
42+
return server;
43+
}
44+
}
45+
46+
return chooser.choose(serverListResult.getNormalServers());
47+
}
48+
49+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package cn.springcloud.gray;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Data;
5+
import lombok.NoArgsConstructor;
6+
7+
import java.util.List;
8+
9+
@Data
10+
@NoArgsConstructor
11+
@AllArgsConstructor
12+
public class ServerListResult<Server> {
13+
14+
private String serviceId;
15+
16+
private List<Server> grayServers;
17+
private List<Server> normalServers;
18+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package cn.springcloud.gray.choose;
2+
3+
import cn.springcloud.gray.GrayManager;
4+
import cn.springcloud.gray.decision.GrayDecision;
5+
import cn.springcloud.gray.decision.GrayDecisionInputArgs;
6+
import cn.springcloud.gray.request.GrayRequest;
7+
import cn.springcloud.gray.request.RequestLocalStorage;
8+
import cn.springcloud.gray.servernode.ServerSpec;
9+
10+
import java.util.List;
11+
12+
public class DefaultGrayPredicate implements GrayPredicate {
13+
14+
private RequestLocalStorage requestLocalStorage;
15+
private GrayManager grayManager;
16+
17+
18+
public DefaultGrayPredicate(RequestLocalStorage requestLocalStorage, GrayManager grayManager) {
19+
this.requestLocalStorage = requestLocalStorage;
20+
this.grayManager = grayManager;
21+
}
22+
23+
@Override
24+
public boolean apply(ServerSpec serverSpec) {
25+
GrayDecisionInputArgs decisionInputArgs = GrayDecisionInputArgs
26+
.builder().grayRequest(requestLocalStorage.getGrayRequest()).server(serverSpec).build();
27+
return apply(decisionInputArgs);
28+
}
29+
30+
@Override
31+
public boolean apply(GrayDecisionInputArgs decisionInputArgs) {
32+
GrayRequest grayRequest = decisionInputArgs.getGrayRequest();
33+
if(grayRequest==null){
34+
return false;
35+
}
36+
ServerSpec serverSpec = decisionInputArgs.getServer();
37+
if(serverSpec==null){
38+
return false;
39+
}
40+
41+
List<GrayDecision> grayDecisions =
42+
grayManager.getGrayDecision(serverSpec.getServiceId(), serverSpec.getInstanceId());
43+
44+
for (GrayDecision grayDecision : grayDecisions) {
45+
if (grayDecision.test(decisionInputArgs)) {
46+
return true;
47+
}
48+
}
49+
return false;
50+
}
51+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package cn.springcloud.gray.choose;
2+
3+
import cn.springcloud.gray.decision.GrayDecisionInputArgs;
4+
import cn.springcloud.gray.servernode.ServerSpec;
5+
6+
public interface GrayPredicate {
7+
8+
boolean apply(ServerSpec serverSpec);
9+
10+
boolean apply(GrayDecisionInputArgs decisionInputArgs);
11+
12+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package cn.springcloud.gray.choose;
2+
3+
import java.util.List;
4+
5+
public interface ListChooser<Server> {
6+
7+
Server choose(List<Server> servers);
8+
}

0 commit comments

Comments
 (0)