Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
* spring-cloud-start-gray
* spring-cloud-start-gray-server
* [spring-cloud-gray-samples](spring-cloud-gray-samples/README.md)
* [spring-cloud-gray-zookeeper-samples](spring-cloud-gray-zookeeper-samples/README.md)

#### maven 依赖
jar包已经上传到maven中央库,可以通过maven直接从中央库下载
Expand Down
3 changes: 2 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<groupId>cn.springcloud.gray</groupId>
<artifactId>spring-cloud-gray</artifactId>
<packaging>pom</packaging>
<version>1.0.2</version>
<version>1.1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
Expand All @@ -27,6 +27,7 @@
<module>spring-cloud-starter-gray</module>
<module>spring-cloud-starter-gray-server</module>
<module>spring-cloud-gray-samples</module>
<module>spring-cloud-gray-zookeeper-samples</module>
</modules>


Expand Down
2 changes: 1 addition & 1 deletion spring-cloud-bamboo/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>spring-cloud-gray</artifactId>
<groupId>cn.springcloud.gray</groupId>
<version>1.0.2</version>
<version>1.1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
7 changes: 6 additions & 1 deletion spring-cloud-gray-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>spring-cloud-gray</artifactId>
<groupId>cn.springcloud.gray</groupId>
<version>1.0.2</version>
<version>1.1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down Expand Up @@ -37,6 +37,11 @@
<artifactId>spring-cloud-starter-eureka</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import cn.springcloud.bamboo.autoconfig.BambooAutoConfiguration;
import cn.springcloud.gray.DefaultGrayManager;
import cn.springcloud.gray.HttpInformationClient;
import cn.springcloud.gray.InstanceLocalInfo;
import cn.springcloud.gray.RetryableInformationClient;
import cn.springcloud.gray.client.GrayClientInitializingBean;
import cn.springcloud.gray.client.GrayOptionalArgs;
Expand All @@ -13,8 +12,6 @@
import cn.springcloud.gray.core.GrayManager;
import cn.springcloud.gray.core.InformationClient;
import cn.springcloud.gray.decision.DefaultGrayDecisionFactory;
import com.netflix.appinfo.EurekaInstanceConfig;
import com.netflix.discovery.EurekaClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
Expand Down Expand Up @@ -52,18 +49,6 @@ public GrayClientInitializingBean grayClientInitializingBean() {
return new GrayClientInitializingBean();
}


@Bean
public InstanceLocalInfo instanceLocalInfo(@Autowired EurekaClient eurekaClient) {
EurekaInstanceConfig instanceConfig = eurekaClient.getApplicationInfoManager().getEurekaInstanceConfig();
InstanceLocalInfo localInfo = new InstanceLocalInfo();
localInfo.setInstanceId(instanceConfig.getInstanceId());
localInfo.setServiceId(instanceConfig.getAppname());
localInfo.setGray(false);
return localInfo;
}


@Bean
@ConditionalOnMissingBean
public GrayDecisionFactory grayDecisionFactory() {
Expand All @@ -72,14 +57,16 @@ public GrayDecisionFactory grayDecisionFactory() {


@Configuration
@ConditionalOnProperty(prefix = "gray.client", value = "information-client", havingValue = "http", matchIfMissing = true)
@ConditionalOnProperty(prefix = "gray.client", value = "information-client", havingValue = "http", matchIfMissing
= true)
public static class HttpGrayManagerClientConfiguration {
@Autowired
private GrayClientProperties grayClientProperties;

@Bean
public InformationClient informationClient() {
InformationClient client = new HttpInformationClient(grayClientProperties.getServerUrl(), new RestTemplate());
InformationClient client = new HttpInformationClient(grayClientProperties.getServerUrl(), new
RestTemplate());
if (!grayClientProperties.isRetryable()) {
return client;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package cn.springcloud.gray.client.config;

import cn.springcloud.gray.InstanceLocalInfo;
import com.netflix.discovery.EurekaClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
* @Author: duozl
* @Date: 2018/6/5 18:18
*/
@Configuration
@ConditionalOnBean(EurekaClient.class)
public class GrayClientEurekaAutoConfiguration {

@Bean
@ConditionalOnMissingBean
public InstanceLocalInfo instanceLocalInfo(@Autowired EurekaRegistration registration) {
String instanceId = registration.getInstanceConfig().getInstanceId();

InstanceLocalInfo localInfo = new InstanceLocalInfo();
localInfo.setInstanceId(instanceId);
localInfo.setServiceId(registration.getServiceId());
localInfo.setGray(false);
return localInfo;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package cn.springcloud.gray.client.config;

import cn.springcloud.gray.InstanceLocalInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.cloud.zookeeper.discovery.ZookeeperDiscoveryProperties;
import org.springframework.cloud.zookeeper.serviceregistry.ZookeeperRegistration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.naming.ConfigurationException;

/**
* @Author: duozl
* @Date: 2018/6/5 18:18
*/
@Configuration
@ConditionalOnBean(ZookeeperRegistration.class)
public class GrayClientZookeeperAutoConfiguration {
private static final String METADATA_KEY_INSTANCE_ID = "instanceId";

@Bean
@ConditionalOnMissingBean
public InstanceLocalInfo instanceLocalInfo(@Autowired Registration registration,
@Autowired ZookeeperDiscoveryProperties properties)
throws ConfigurationException {
String instanceId;
if (properties.getMetadata().containsKey(METADATA_KEY_INSTANCE_ID)) {
instanceId = properties.getMetadata().get(METADATA_KEY_INSTANCE_ID);
} else {
throw new ConfigurationException("Unable to find config spring.cloud.zookeeper.discovery.metadata" +
".instanceId!");
}

InstanceLocalInfo localInfo = new InstanceLocalInfo();
localInfo.setInstanceId(instanceId);
localInfo.setServiceId(registration.getServiceId());
localInfo.setGray(false);
return localInfo;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,10 @@ public void setRetryNumberOfRetries(int retryNumberOfRetries) {
*/
public class InstanceConfig {

private boolean grayEnroll;
private boolean grayEnroll = false;
private int grayEnrollDealyTimeInMs = 40000;
private boolean useMultiVersion = false;
private String instanceId;

public boolean isGrayEnroll() {
return grayEnroll;
Expand Down Expand Up @@ -118,5 +119,13 @@ public boolean isUseMultiVersion() {
public void setUseMultiVersion(boolean useMultiVersion) {
this.useMultiVersion = useMultiVersion;
}

public String getInstanceId() {
return instanceId;
}

public void setInstanceId(String instanceId) {
this.instanceId = instanceId;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package cn.springcloud.gray.ribbon;

import cn.springcloud.bamboo.BambooAppContext;
import cn.springcloud.bamboo.BambooRequest;
import cn.springcloud.bamboo.BambooRequestContext;
import cn.springcloud.gray.core.GrayDecision;
import cn.springcloud.gray.utils.ServiceUtil;
import com.netflix.loadbalancer.AbstractServerPredicate;
import com.netflix.loadbalancer.PredicateKey;
import com.netflix.niws.loadbalancer.DiscoveryEnabledServer;
import com.netflix.loadbalancer.Server;

import java.util.List;
import java.util.Map;

public class GrayDecisionPredicate extends AbstractServerPredicate {

Expand All @@ -21,10 +24,14 @@ public boolean apply(PredicateKey input) {
if (bambooRequestContext == null || bambooRequestContext.getBambooRequest() == null) {
return false;
}
DiscoveryEnabledServer server = (DiscoveryEnabledServer) input.getServer();
BambooRequest bambooRequest = bambooRequestContext.getBambooRequest();
Server server = input.getServer();
String serviceId = bambooRequest.getServiceId();
Map<String, String> serverMetadata = getServerMetadata(serviceId, server);
String instanceId = ServiceUtil.getInstanceId(server, serverMetadata);

List<GrayDecision> grayDecisions =
getIRule().getGrayManager().grayDecision(bambooRequest.getServiceId(), server.getInstanceInfo().getInstanceId());
getIRule().getGrayManager().grayDecision(serviceId, instanceId);
for (GrayDecision grayDecision : grayDecisions) {
if (grayDecision.test(bambooRequest)) {
return true;
Expand All @@ -38,5 +45,7 @@ protected GrayLoadBalanceRule getIRule() {
return (GrayLoadBalanceRule) this.rule;
}


public Map<String, String> getServerMetadata(String serviceId, Server server) {
return BambooAppContext.getEurekaServerExtractor().getServerMetadata(serviceId, server);
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
package cn.springcloud.gray.ribbon;

import cn.springcloud.bamboo.BambooAppContext;
import cn.springcloud.bamboo.BambooRequestContext;
import cn.springcloud.bamboo.ribbon.loadbalancer.BambooZoneAvoidanceRule;
import cn.springcloud.gray.client.GrayClientAppContext;
import cn.springcloud.gray.client.config.properties.GrayClientProperties;
import cn.springcloud.gray.core.GrayManager;
import cn.springcloud.gray.core.GrayService;
import cn.springcloud.gray.utils.ServiceUtil;
import com.google.common.base.Optional;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.*;
import com.netflix.niws.loadbalancer.DiscoveryEnabledServer;

import java.util.ArrayList;
import java.util.List;

import static cn.springcloud.gray.client.GrayClientAppContext.getGrayClientProperties;

import java.util.Map;

/**
* 灰度发布的负载规则
Expand Down Expand Up @@ -49,14 +48,16 @@ protected void init(){
public Server choose(Object key) {
ILoadBalancer lb = getLoadBalancer();
BambooRequestContext requestContext = BambooRequestContext.currentRequestCentxt();
if (requestContext != null && getGrayManager().isOpen(requestContext.getServiceId())) {
GrayService grayService = getGrayManager().grayService(requestContext.getServiceId());
String serviceId = requestContext.getServiceId();
if (requestContext != null && getGrayManager().isOpen(serviceId)) {
GrayService grayService = getGrayManager().grayService(serviceId);
List<Server> servers = lb.getAllServers();
List<Server> grayServers = new ArrayList<>(grayService.getGrayInstances().size());
List<Server> normalServers = new ArrayList<>(servers.size() - grayService.getGrayInstances().size());
for (Server server : servers) {
DiscoveryEnabledServer disServer = (DiscoveryEnabledServer) server;
if (grayService.getGrayInstance(disServer.getInstanceInfo().getInstanceId()) != null) {
Map<String, String> serverMetadata = getServerMetadata(serviceId, server);
String instanceId = ServiceUtil.getInstanceId(server, serverMetadata);
if (grayService.getGrayInstance(instanceId) != null) {
grayServers.add(server);
} else {
normalServers.add(server);
Expand Down Expand Up @@ -101,8 +102,11 @@ private Server choose(AbstractServerPredicate serverPredicate, List<Server> serv
}
}


public GrayManager getGrayManager() {
return GrayClientAppContext.getGrayManager();
}

public static Map<String, String> getServerMetadata(String serviceId, Server server) {
return BambooAppContext.getEurekaServerExtractor().getServerMetadata(serviceId, server);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package cn.springcloud.gray.utils;

import com.netflix.loadbalancer.Server;
import org.springframework.cloud.zookeeper.discovery.ZookeeperServer;

import java.util.Map;

/**
* @Author: duozl
* @Date: 2018/6/5 15:56
*/
public class ServiceUtil {
private static final String METADATA_KEY_INSTANCE_ID = "instanceId";

public static String getInstanceId(Server server, Map<String, String> serverMetadata) {
try {
if (server instanceof ZookeeperServer) {
if (serverMetadata.containsKey(METADATA_KEY_INSTANCE_ID)) {
return serverMetadata.get(METADATA_KEY_INSTANCE_ID);
} else {
throw new IllegalStateException("Unable to find config spring.cloud.zookeeper.discovery.metadata" +
".instanceId!");
}
}
} catch (Throwable e) {
// do nothing,可能是类找不到等原因,如果引入了zookeeper的依赖,这个不会找不到
}
return server.getMetaInfo().getInstanceId();
}
}
2 changes: 1 addition & 1 deletion spring-cloud-gray-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>spring-cloud-gray</artifactId>
<groupId>cn.springcloud.gray</groupId>
<version>1.0.2</version>
<version>1.1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
2 changes: 1 addition & 1 deletion spring-cloud-gray-dependencies/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

<groupId>cn.springcloud.gray</groupId>
<artifactId>spring-cloud-gray-dependencies</artifactId>
<version>1.0.2</version>
<version>1.1.0</version>
<packaging>pom</packaging>

<licenses>
Expand Down
2 changes: 1 addition & 1 deletion spring-cloud-gray-samples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>spring-cloud-gray</artifactId>
<groupId>cn.springcloud.gray</groupId>
<version>1.0.2</version>
<version>1.1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>spring-cloud-gray-samples</artifactId>
<groupId>cn.springcloud.gray</groupId>
<version>1.0.2</version>
<version>1.1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>spring-cloud-gray-samples</artifactId>
<groupId>cn.springcloud.gray</groupId>
<version>1.0.2</version>
<version>1.1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>spring-cloud-gray-samples</artifactId>
<groupId>cn.springcloud.gray</groupId>
<version>1.0.2</version>
<version>1.1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
Loading