mirror of
https://gitee.com/durcframework/SOP.git
synced 2025-08-12 07:02:14 +08:00
优化灰度预发布
This commit is contained in:
@@ -8,6 +8,8 @@ import com.gitee.sop.gatewaycommon.zuul.loadbalancer.ServiceGrayConfig;
|
||||
*/
|
||||
public interface EnvGrayManager extends BeanInitializer {
|
||||
|
||||
String ENV_GRAY = "sop.env-gray";
|
||||
|
||||
/**
|
||||
* 保存灰度配置
|
||||
* @param serviceGrayConfig 灰度配置
|
||||
|
@@ -42,6 +42,7 @@ public class PreEnvGrayFilter extends BaseZuulFilter {
|
||||
// 如果服务在灰度阶段,返回一个灰度版本号
|
||||
String version = envGrayManager.getVersion(serviceId, nameVersion);
|
||||
if (version != null && envGrayManager.containsKey(serviceId, apiParam.fetchAppKey())) {
|
||||
requestContext.set(EnvGrayManager.ENV_GRAY, true);
|
||||
requestContext.addZuulRequestHeader(ParamNames.HEADER_VERSION_NAME, version);
|
||||
}
|
||||
return null;
|
||||
|
@@ -1,15 +1,20 @@
|
||||
package com.gitee.sop.gatewaycommon.zuul.loadbalancer;
|
||||
|
||||
import com.gitee.sop.gatewaycommon.bean.SpringContext;
|
||||
import com.gitee.sop.gatewaycommon.manager.EnvGrayManager;
|
||||
import com.google.common.base.Optional;
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ZoneAvoidanceRule;
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.ArrayUtils;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 服务实例选择器
|
||||
@@ -47,26 +52,64 @@ public abstract class BaseServerChooser extends ZoneAvoidanceRule {
|
||||
public Server choose(Object key) {
|
||||
ILoadBalancer lb = getLoadBalancer();
|
||||
// 获取服务实例列表
|
||||
List<Server> allServers = lb.getAllServers();
|
||||
List<Server> servers = lb.getReachableServers();
|
||||
HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
|
||||
// 存放预发服务器
|
||||
List<Server> preServers = new ArrayList<>(4);
|
||||
// 存放灰度发布服务器
|
||||
List<Server> grayServers = new ArrayList<>(4);
|
||||
// 存放非预发服务器
|
||||
List<Server> notPreServers = new ArrayList<>(4);
|
||||
|
||||
List<Server> preServers = allServers.stream()
|
||||
.filter(this::isPreServer)
|
||||
.filter(server -> canVisitPre(server, request))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (!preServers.isEmpty()) {
|
||||
return this.doChoose(preServers, key);
|
||||
for (Server server : servers) {
|
||||
// 是否开启了预发模式
|
||||
if (this.isPreServer(server)) {
|
||||
preServers.add(server);
|
||||
} else if (this.isGrayServer(server)) {
|
||||
grayServers.add(server);
|
||||
} else {
|
||||
notPreServers.add(server);
|
||||
}
|
||||
}
|
||||
|
||||
List<Server> grayServers = allServers.stream()
|
||||
.filter(this::isGrayServer)
|
||||
.collect(Collectors.toList());
|
||||
if (!grayServers.isEmpty()) {
|
||||
notPreServers.addAll(grayServers);
|
||||
// 如果没有开启预发布服务和灰度发布,直接用默认的方式
|
||||
if (preServers.isEmpty() && grayServers.isEmpty()) {
|
||||
return super.choose(key);
|
||||
}
|
||||
// 如果是从预发布域名访问过来,则认为是预发布请求
|
||||
if (this.isRequestFromPreDomain(request)) {
|
||||
return doChoose(preServers, key);
|
||||
}
|
||||
// 如果是灰度请求
|
||||
if (this.isRequestGrayServer(RequestContext.getCurrentContext())) {
|
||||
return doChoose(grayServers, key);
|
||||
}
|
||||
|
||||
return super.choose(key);
|
||||
// 到这里说明不能访问预发/灰度服务器,则需要路由到非预发服务器
|
||||
return doChoose(notPreServers, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过判断hostname来确定是否是预发布请求
|
||||
*
|
||||
* @param t t
|
||||
* @return 返回true:可以进入到预发环境
|
||||
*/
|
||||
protected boolean isRequestFromPreDomain(HttpServletRequest t) {
|
||||
String domain = SpringContext.getBean(Environment.class).getProperty("pre.domain");
|
||||
if (StringUtils.isEmpty(domain)) {
|
||||
return false;
|
||||
}
|
||||
String[] domains = domain.split("\\,");
|
||||
return ArrayUtils.contains(domains, getHost(t));
|
||||
}
|
||||
|
||||
protected boolean isRequestGrayServer(RequestContext t) {
|
||||
return t.get(EnvGrayManager.ENV_GRAY) != null;
|
||||
}
|
||||
|
||||
protected String getHost(HttpServletRequest t) {
|
||||
return t.getServerName();
|
||||
}
|
||||
|
||||
protected Server doChoose(List<Server> servers, Object key) {
|
||||
|
Reference in New Issue
Block a user