mirror of
https://gitee.com/durcframework/SOP.git
synced 2025-08-11 21:57:56 +08:00
支持预发布、灰度发布
This commit is contained in:
@@ -211,6 +211,7 @@ public class ServiceApi {
|
|||||||
registryService.setMetadata(param.buildServiceInstance(), envPre.getKey(), envPre.getValue());
|
registryService.setMetadata(param.buildServiceInstance(), envPre.getKey(), envPre.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String serviceId = param.getServiceId();
|
||||||
String instanceId = param.getInstanceId();
|
String instanceId = param.getInstanceId();
|
||||||
String userKeyContent = param.getUserKeyContent();
|
String userKeyContent = param.getUserKeyContent();
|
||||||
String nameVersionContent = param.getNameVersionContent();
|
String nameVersionContent = param.getNameVersionContent();
|
||||||
@@ -218,6 +219,7 @@ public class ServiceApi {
|
|||||||
ConfigGrayUserkey configGrayUserkey = configGrayUserkeyMapper.getByColumn("instance_id", instanceId);
|
ConfigGrayUserkey configGrayUserkey = configGrayUserkeyMapper.getByColumn("instance_id", instanceId);
|
||||||
if (configGrayUserkey == null) {
|
if (configGrayUserkey == null) {
|
||||||
configGrayUserkey = new ConfigGrayUserkey();
|
configGrayUserkey = new ConfigGrayUserkey();
|
||||||
|
configGrayUserkey.setServiceId(serviceId);
|
||||||
configGrayUserkey.setInstanceId(instanceId);
|
configGrayUserkey.setInstanceId(instanceId);
|
||||||
configGrayUserkey.setUserKeyContent(userKeyContent);
|
configGrayUserkey.setUserKeyContent(userKeyContent);
|
||||||
configGrayUserkey.setNameVersionContent(nameVersionContent);
|
configGrayUserkey.setNameVersionContent(nameVersionContent);
|
||||||
|
@@ -25,6 +25,9 @@ public class ConfigGrayUserkey {
|
|||||||
/** 数据库字段:id */
|
/** 数据库字段:id */
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
/** serviceId, 数据库字段:service_id */
|
||||||
|
private String serviceId;
|
||||||
|
|
||||||
/** instanceId, 数据库字段:instance_id */
|
/** instanceId, 数据库字段:instance_id */
|
||||||
private String instanceId;
|
private String instanceId;
|
||||||
|
|
||||||
|
@@ -10,13 +10,13 @@ import com.gitee.sop.gatewaycommon.manager.DefaultIsvRoutePermissionManager;
|
|||||||
import com.gitee.sop.gatewaycommon.manager.DefaultLimitConfigManager;
|
import com.gitee.sop.gatewaycommon.manager.DefaultLimitConfigManager;
|
||||||
import com.gitee.sop.gatewaycommon.manager.DefaultRouteConfigManager;
|
import com.gitee.sop.gatewaycommon.manager.DefaultRouteConfigManager;
|
||||||
import com.gitee.sop.gatewaycommon.manager.DefaultServiceErrorManager;
|
import com.gitee.sop.gatewaycommon.manager.DefaultServiceErrorManager;
|
||||||
import com.gitee.sop.gatewaycommon.manager.DefaultUserKeyManager;
|
import com.gitee.sop.gatewaycommon.manager.DefaultEnvGrayManager;
|
||||||
import com.gitee.sop.gatewaycommon.manager.IPBlacklistManager;
|
import com.gitee.sop.gatewaycommon.manager.IPBlacklistManager;
|
||||||
import com.gitee.sop.gatewaycommon.manager.IsvRoutePermissionManager;
|
import com.gitee.sop.gatewaycommon.manager.IsvRoutePermissionManager;
|
||||||
import com.gitee.sop.gatewaycommon.manager.LimitConfigManager;
|
import com.gitee.sop.gatewaycommon.manager.LimitConfigManager;
|
||||||
import com.gitee.sop.gatewaycommon.manager.RouteConfigManager;
|
import com.gitee.sop.gatewaycommon.manager.RouteConfigManager;
|
||||||
import com.gitee.sop.gatewaycommon.manager.ServiceErrorManager;
|
import com.gitee.sop.gatewaycommon.manager.ServiceErrorManager;
|
||||||
import com.gitee.sop.gatewaycommon.manager.UserKeyManager;
|
import com.gitee.sop.gatewaycommon.manager.EnvGrayManager;
|
||||||
import com.gitee.sop.gatewaycommon.param.ParamBuilder;
|
import com.gitee.sop.gatewaycommon.param.ParamBuilder;
|
||||||
import com.gitee.sop.gatewaycommon.result.DataNameBuilder;
|
import com.gitee.sop.gatewaycommon.result.DataNameBuilder;
|
||||||
import com.gitee.sop.gatewaycommon.result.DefaultDataNameBuilder;
|
import com.gitee.sop.gatewaycommon.result.DefaultDataNameBuilder;
|
||||||
@@ -127,7 +127,7 @@ public class ApiConfig {
|
|||||||
/**
|
/**
|
||||||
* 用户key管理
|
* 用户key管理
|
||||||
*/
|
*/
|
||||||
private UserKeyManager userKeyManager = new DefaultUserKeyManager();
|
private EnvGrayManager userKeyManager = new DefaultEnvGrayManager();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建数据节点名称
|
* 构建数据节点名称
|
||||||
|
@@ -83,7 +83,7 @@ public class AbstractConfiguration implements ApplicationContextAware {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
UserKeyManager userKeyManager() {
|
EnvGrayManager userKeyManager() {
|
||||||
return ApiConfig.getInstance().getUserKeyManager();
|
return ApiConfig.getInstance().getUserKeyManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -4,18 +4,33 @@ import com.gitee.sop.gatewaycommon.zuul.loadbalancer.ServiceGrayConfig;
|
|||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author tanghc
|
* @author tanghc
|
||||||
*/
|
*/
|
||||||
public class DefaultUserKeyManager implements UserKeyManager {
|
public class DefaultEnvGrayManager implements EnvGrayManager {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* KEY:instanceId
|
* KEY:instanceId
|
||||||
*/
|
*/
|
||||||
private Map<String, ServiceGrayConfig> serviceUserKeyMap = Maps.newConcurrentMap();
|
private Map<String, ServiceGrayConfig> serviceUserKeyMap = Maps.newConcurrentMap();
|
||||||
|
|
||||||
|
private Map<String, List<String>> serviceInstanceIdMap = Maps.newConcurrentMap();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addServiceInstance(String serviceId, String instanceId) {
|
||||||
|
List<String> instanceIdList = serviceInstanceIdMap.computeIfAbsent(serviceId, key -> new ArrayList<>());
|
||||||
|
instanceIdList.add(instanceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> listGrayInstanceId(String serviceId) {
|
||||||
|
return serviceInstanceIdMap.get(serviceId);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean containsKey(String instanceId, Object userKey) {
|
public boolean containsKey(String instanceId, Object userKey) {
|
||||||
if (instanceId == null || userKey == null) {
|
if (instanceId == null || userKey == null) {
|
||||||
@@ -34,14 +49,12 @@ public class DefaultUserKeyManager implements UserKeyManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ServiceGrayConfig getServiceGrayConfig(String instanceId) {
|
public ServiceGrayConfig getServiceGrayConfig(String instanceId) {
|
||||||
ServiceGrayConfig serviceGrayConfig = serviceUserKeyMap.get(instanceId);
|
return serviceUserKeyMap.computeIfAbsent(instanceId, key -> {
|
||||||
if (serviceGrayConfig == null) {
|
ServiceGrayConfig serviceGrayConfig = new ServiceGrayConfig();
|
||||||
serviceGrayConfig = new ServiceGrayConfig();
|
|
||||||
serviceGrayConfig.setUserKeys(Sets.newConcurrentHashSet());
|
serviceGrayConfig.setUserKeys(Sets.newConcurrentHashSet());
|
||||||
serviceGrayConfig.setGrayNameVersion(Maps.newConcurrentMap());
|
serviceGrayConfig.setGrayNameVersion(Maps.newConcurrentMap());
|
||||||
serviceUserKeyMap.put(instanceId, serviceGrayConfig);
|
|
||||||
}
|
|
||||||
return serviceGrayConfig;
|
return serviceGrayConfig;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@@ -3,10 +3,17 @@ package com.gitee.sop.gatewaycommon.manager;
|
|||||||
import com.gitee.sop.gatewaycommon.bean.BeanInitializer;
|
import com.gitee.sop.gatewaycommon.bean.BeanInitializer;
|
||||||
import com.gitee.sop.gatewaycommon.zuul.loadbalancer.ServiceGrayConfig;
|
import com.gitee.sop.gatewaycommon.zuul.loadbalancer.ServiceGrayConfig;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author tanghc
|
* @author tanghc
|
||||||
*/
|
*/
|
||||||
public interface UserKeyManager extends BeanInitializer {
|
public interface EnvGrayManager extends BeanInitializer {
|
||||||
|
|
||||||
|
void addServiceInstance(String serviceId, String instanceId);
|
||||||
|
|
||||||
|
List<String> listGrayInstanceId(String serviceId);
|
||||||
|
|
||||||
boolean containsKey(String instanceId, Object userKey);
|
boolean containsKey(String instanceId, Object userKey);
|
||||||
|
|
||||||
String getVersion(String instanceId, String nameVersion);
|
String getVersion(String instanceId, String nameVersion);
|
@@ -0,0 +1,53 @@
|
|||||||
|
package com.gitee.sop.gatewaycommon.zuul.filter;
|
||||||
|
|
||||||
|
import com.gitee.sop.gatewaycommon.bean.TargetRoute;
|
||||||
|
import com.gitee.sop.gatewaycommon.manager.EnvGrayManager;
|
||||||
|
import com.gitee.sop.gatewaycommon.manager.RouteRepositoryContext;
|
||||||
|
import com.gitee.sop.gatewaycommon.param.ApiParam;
|
||||||
|
import com.gitee.sop.gatewaycommon.param.ParamNames;
|
||||||
|
import com.gitee.sop.gatewaycommon.zuul.ZuulContext;
|
||||||
|
import com.netflix.zuul.context.RequestContext;
|
||||||
|
import com.netflix.zuul.exception.ZuulException;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author tanghc
|
||||||
|
*/
|
||||||
|
public class PreVersionDecisionFilter extends BaseZuulFilter {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EnvGrayManager envGrayManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected FilterType getFilterType() {
|
||||||
|
return FilterType.PRE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getFilterOrder() {
|
||||||
|
return PRE_LIMIT_FILTER_ORDER + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Object doRun(RequestContext requestContext) throws ZuulException {
|
||||||
|
ApiParam apiParam = ZuulContext.getApiParam();
|
||||||
|
String nameVersion = apiParam.fetchNameVersion();
|
||||||
|
TargetRoute targetRoute = RouteRepositoryContext.getRouteRepository().get(nameVersion);
|
||||||
|
if (targetRoute == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String serviceId = targetRoute.getServiceRouteInfo().getServiceId();
|
||||||
|
List<String> instanceIdList = envGrayManager.listGrayInstanceId(serviceId);
|
||||||
|
|
||||||
|
for (String instanceId : instanceIdList) {
|
||||||
|
String version = envGrayManager.getVersion(instanceId, nameVersion);
|
||||||
|
if (version != null) {
|
||||||
|
requestContext.addZuulRequestHeader(ParamNames.HEADER_VERSION_NAME, version);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@@ -6,11 +6,10 @@ import com.netflix.loadbalancer.Server;
|
|||||||
import com.netflix.loadbalancer.ZoneAvoidanceRule;
|
import com.netflix.loadbalancer.ZoneAvoidanceRule;
|
||||||
import com.netflix.zuul.context.RequestContext;
|
import com.netflix.zuul.context.RequestContext;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.util.CollectionUtils;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 服务实例选择器
|
* 服务实例选择器
|
||||||
@@ -37,31 +36,88 @@ public abstract class BaseServerChooser extends ZoneAvoidanceRule {
|
|||||||
*/
|
*/
|
||||||
protected abstract boolean canVisit(Server server, HttpServletRequest request);
|
protected abstract boolean canVisit(Server server, HttpServletRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否是预发布服务器
|
||||||
|
* @param server 服务器
|
||||||
|
* @return true:是
|
||||||
|
*/
|
||||||
|
protected abstract boolean isPreServer(Server server);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否是灰度发布服务器
|
||||||
|
* @param server 服务器
|
||||||
|
* @return true:是
|
||||||
|
*/
|
||||||
|
protected abstract boolean isGrayServer(Server server);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 能否访问预发布
|
||||||
|
* @param server 预发布服务器
|
||||||
|
* @param request request
|
||||||
|
* @return true:能
|
||||||
|
*/
|
||||||
|
protected abstract boolean canVisitPre(Server server, HttpServletRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 能否访问灰度服务器
|
||||||
|
* @param server 灰度服务器
|
||||||
|
* @param request request
|
||||||
|
* @return true:能
|
||||||
|
*/
|
||||||
|
protected abstract boolean canVisitGray(Server server, HttpServletRequest request);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Server choose(Object key) {
|
public Server choose(Object key) {
|
||||||
ILoadBalancer lb = getLoadBalancer();
|
ILoadBalancer lb = getLoadBalancer();
|
||||||
// 获取服务实例列表
|
// 获取服务实例列表
|
||||||
List<Server> allServers = new ArrayList<>(lb.getAllServers());
|
List<Server> allServers = lb.getAllServers();
|
||||||
int index = -1;
|
HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
|
||||||
for (int i = 0; i < allServers.size(); i++) {
|
|
||||||
Server server = allServers.get(i);
|
List<Server> preServers = allServers.stream()
|
||||||
if (match(server)) {
|
.filter(this::isPreServer)
|
||||||
index = i;
|
.filter(server -> canVisitPre(server, request))
|
||||||
if (canVisit(server, RequestContext.getCurrentContext().getRequest())) {
|
.collect(Collectors.toList());
|
||||||
return server;
|
// int index = -1;
|
||||||
}
|
// for (int i = 0; i < allServers.size(); i++) {
|
||||||
|
// Server server = allServers.get(i);
|
||||||
|
// if (isPreServer(server)) {
|
||||||
|
// preServers.add(server);
|
||||||
|
// }
|
||||||
|
// if (match(server)) {
|
||||||
|
// index = i;
|
||||||
|
// if (canVisit(server, RequestContext.getCurrentContext().getRequest())) {
|
||||||
|
// return server;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (!preServers.isEmpty()) {
|
||||||
|
return this.doChoose(preServers, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Server> grayServers = allServers.stream()
|
||||||
|
.filter(this::isGrayServer)
|
||||||
|
.filter(server -> canVisitGray(server, request))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (!grayServers.isEmpty()) {
|
||||||
|
return doChoose(grayServers, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return super.choose(key);
|
||||||
// 调用默认的算法
|
// 调用默认的算法
|
||||||
// 如果选出了特殊环境服务器,需要移除命中的服务器
|
// 如果选出了特殊环境服务器,需要移除命中的服务器
|
||||||
if (index > -1) {
|
// if (index > -1) {
|
||||||
allServers.remove(index);
|
// allServers.remove(index);
|
||||||
|
// }
|
||||||
|
// if (CollectionUtils.isEmpty(allServers)) {
|
||||||
|
// log.error("无可用服务实例,key:", key);
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
if (CollectionUtils.isEmpty(allServers)) {
|
|
||||||
log.error("无可用服务实例,key:", key);
|
protected Server doChoose(List<Server> servers, Object key) {
|
||||||
return null;
|
Optional<Server> server = getPredicate().chooseRoundRobinAfterFiltering(servers, key);
|
||||||
}
|
|
||||||
Optional<Server> server = getPredicate().chooseRoundRobinAfterFiltering(allServers, key);
|
|
||||||
if (server.isPresent()) {
|
if (server.isPresent()) {
|
||||||
return server.get();
|
return server.get();
|
||||||
} else {
|
} else {
|
||||||
|
@@ -1,23 +0,0 @@
|
|||||||
package com.gitee.sop.gatewaycommon.zuul.loadbalancer;
|
|
||||||
|
|
||||||
import com.gitee.sop.gatewaycommon.param.ParamNames;
|
|
||||||
import org.springframework.http.HttpRequest;
|
|
||||||
import org.springframework.http.client.ClientHttpRequestExecution;
|
|
||||||
import org.springframework.http.client.ClientHttpRequestInterceptor;
|
|
||||||
import org.springframework.http.client.ClientHttpResponse;
|
|
||||||
import org.springframework.http.client.support.HttpRequestWrapper;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author tanghc
|
|
||||||
*/
|
|
||||||
public class EnvHttpRequestInterceptor implements ClientHttpRequestInterceptor {
|
|
||||||
@Override
|
|
||||||
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
|
|
||||||
HttpRequestWrapper requestWrapper = new HttpRequestWrapper(request);
|
|
||||||
String newVersion = HystrixRequestVariableContext.getVersion();
|
|
||||||
requestWrapper.getHeaders().add(ParamNames.GRAY_HEADER_VERSION_NAME, newVersion);
|
|
||||||
return execution.execute(requestWrapper, body);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,18 +0,0 @@
|
|||||||
package com.gitee.sop.gatewaycommon.zuul.loadbalancer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author tanghc
|
|
||||||
*/
|
|
||||||
public class HystrixRequestVariableContext {
|
|
||||||
// private static final HystrixRequestVariableDefault<String> VERSION_HOLDER = new HystrixRequestVariableDefault<>();
|
|
||||||
private static final ThreadLocal<String> VERSION_HOLDER = new ThreadLocal<>();
|
|
||||||
|
|
||||||
public static void setVersion(String version) {
|
|
||||||
VERSION_HOLDER.set(version);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getVersion() {
|
|
||||||
return VERSION_HOLDER.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,4 +1,4 @@
|
|||||||
package com.gitee.sop.websiteserver.bean;
|
package com.gitee.sop.registryapi.bean;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@@ -110,7 +110,7 @@ public class HttpTool {
|
|||||||
* @return
|
* @return
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public String request(String url, Map<String, String> form, Map<String, String> header, HTTPMethod method) throws IOException {
|
public String request(String url, Map<String, ?> form, Map<String, String> header, HTTPMethod method) throws IOException {
|
||||||
Request.Builder requestBuilder = buildRequestBuilder(url, form, method);
|
Request.Builder requestBuilder = buildRequestBuilder(url, form, method);
|
||||||
// 添加header
|
// 添加header
|
||||||
addHeader(requestBuilder, header);
|
addHeader(requestBuilder, header);
|
||||||
@@ -153,7 +153,7 @@ public class HttpTool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Request.Builder buildRequestBuilder(String url, Map<String, String> form, HTTPMethod method) {
|
public static Request.Builder buildRequestBuilder(String url, Map<String, ?> form, HTTPMethod method) {
|
||||||
switch (method) {
|
switch (method) {
|
||||||
case GET:
|
case GET:
|
||||||
return new Request.Builder()
|
return new Request.Builder()
|
||||||
@@ -178,18 +178,18 @@ public class HttpTool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HttpUrl buildHttpUrl(String url, Map<String, String> form) {
|
public static HttpUrl buildHttpUrl(String url, Map<String, ?> form) {
|
||||||
HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder();
|
HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder();
|
||||||
for (Map.Entry<String, String> entry : form.entrySet()) {
|
for (Map.Entry<String, ?> entry : form.entrySet()) {
|
||||||
urlBuilder.addQueryParameter(entry.getKey(), entry.getValue());
|
urlBuilder.addQueryParameter(entry.getKey(), String.valueOf(entry.getValue()));
|
||||||
}
|
}
|
||||||
return urlBuilder.build();
|
return urlBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FormBody buildFormBody(Map<String, String> form) {
|
public static FormBody buildFormBody(Map<String, ?> form) {
|
||||||
FormBody.Builder paramBuilder = new FormBody.Builder(StandardCharsets.UTF_8);
|
FormBody.Builder paramBuilder = new FormBody.Builder(StandardCharsets.UTF_8);
|
||||||
for (Map.Entry<String, String> entry : form.entrySet()) {
|
for (Map.Entry<String, ?> entry : form.entrySet()) {
|
||||||
paramBuilder.add(entry.getKey(), entry.getValue());
|
paramBuilder.add(entry.getKey(), String.valueOf(entry.getValue()));
|
||||||
}
|
}
|
||||||
return paramBuilder.build();
|
return paramBuilder.build();
|
||||||
}
|
}
|
||||||
|
@@ -11,7 +11,6 @@ import com.gitee.sop.registryapi.bean.HttpTool;
|
|||||||
import com.gitee.sop.registryapi.bean.ServiceInfo;
|
import com.gitee.sop.registryapi.bean.ServiceInfo;
|
||||||
import com.gitee.sop.registryapi.bean.ServiceInstance;
|
import com.gitee.sop.registryapi.bean.ServiceInstance;
|
||||||
import com.gitee.sop.registryapi.service.RegistryService;
|
import com.gitee.sop.registryapi.service.RegistryService;
|
||||||
import okhttp3.OkHttpClient;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
@@ -29,8 +28,6 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
public class RegistryServiceNacos implements RegistryService {
|
public class RegistryServiceNacos implements RegistryService {
|
||||||
|
|
||||||
OkHttpClient client = new OkHttpClient();
|
|
||||||
|
|
||||||
static HttpTool httpTool = new HttpTool();
|
static HttpTool httpTool = new HttpTool();
|
||||||
|
|
||||||
@Value("${registry.nacos-server-addr:}")
|
@Value("${registry.nacos-server-addr:}")
|
||||||
|
@@ -42,8 +42,6 @@ public class ParamNames {
|
|||||||
/** 请求参数的集合,最大长度不限,除公共参数外所有请求参数都必须放在这个参数中传递,具体参照各产品快速接入文档 */
|
/** 请求参数的集合,最大长度不限,除公共参数外所有请求参数都必须放在这个参数中传递,具体参照各产品快速接入文档 */
|
||||||
public static String BIZ_CONTENT_NAME = "biz_content";
|
public static String BIZ_CONTENT_NAME = "biz_content";
|
||||||
|
|
||||||
public static String HEADER_VERSION_NAME = "sop_gray_version";
|
|
||||||
|
|
||||||
/** 时间戳格式 */
|
/** 时间戳格式 */
|
||||||
public static String TIMESTAMP_PATTERN = "yyyy-MM-dd HH:mm:ss";
|
public static String TIMESTAMP_PATTERN = "yyyy-MM-dd HH:mm:ss";
|
||||||
|
|
||||||
|
@@ -25,6 +25,9 @@ public class ConfigGrayUserkey {
|
|||||||
/** 数据库字段:id */
|
/** 数据库字段:id */
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
/** serviceId, 数据库字段:service_id */
|
||||||
|
private String serviceId;
|
||||||
|
|
||||||
/** instanceId, 数据库字段:instance_id */
|
/** instanceId, 数据库字段:instance_id */
|
||||||
private String instanceId;
|
private String instanceId;
|
||||||
|
|
||||||
|
@@ -1,15 +1,13 @@
|
|||||||
package com.gitee.sop.gateway.loadbalancer;
|
package com.gitee.sop.gateway.loadbalancer;
|
||||||
|
|
||||||
import com.gitee.sop.gateway.manager.DbUserKeyManager;
|
import com.gitee.sop.gateway.manager.DbEnvGrayManager;
|
||||||
import com.gitee.sop.gatewaycommon.bean.SpringContext;
|
import com.gitee.sop.gatewaycommon.bean.SpringContext;
|
||||||
import com.gitee.sop.gatewaycommon.param.ApiParam;
|
import com.gitee.sop.gatewaycommon.param.ApiParam;
|
||||||
import com.gitee.sop.gatewaycommon.param.Param;
|
import com.gitee.sop.gatewaycommon.param.Param;
|
||||||
import com.gitee.sop.gatewaycommon.param.ParamNames;
|
|
||||||
import com.gitee.sop.gatewaycommon.zuul.ZuulContext;
|
import com.gitee.sop.gatewaycommon.zuul.ZuulContext;
|
||||||
import com.gitee.sop.gatewaycommon.zuul.loadbalancer.BaseServerChooser;
|
import com.gitee.sop.gatewaycommon.zuul.loadbalancer.BaseServerChooser;
|
||||||
import com.netflix.loadbalancer.Server;
|
import com.netflix.loadbalancer.Server;
|
||||||
import com.netflix.niws.loadbalancer.DiscoveryEnabledServer;
|
import com.netflix.niws.loadbalancer.DiscoveryEnabledServer;
|
||||||
import com.netflix.zuul.context.RequestContext;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
@@ -30,6 +28,24 @@ public class EnvironmentServerChooser extends BaseServerChooser {
|
|||||||
*/
|
*/
|
||||||
private static final String PRE_DOMAIN = "localhost";
|
private static final String PRE_DOMAIN = "localhost";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isPreServer(Server server) {
|
||||||
|
String env = getEnvValue(server);
|
||||||
|
return ENV_PRE_VALUE.equals(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isGrayServer(Server server) {
|
||||||
|
String env = getEnvValue(server);
|
||||||
|
return ENV_GRAY_VALUE.equals(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getEnvValue(Server server) {
|
||||||
|
// eureka存储的metadata
|
||||||
|
Map<String, String> metadata = ((DiscoveryEnabledServer) server).getInstanceInfo().getMetadata();
|
||||||
|
return metadata.get(MEDATA_KEY_ENV);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean match(Server server) {
|
protected boolean match(Server server) {
|
||||||
// eureka存储的metadata
|
// eureka存储的metadata
|
||||||
@@ -70,6 +86,7 @@ public class EnvironmentServerChooser extends BaseServerChooser {
|
|||||||
* @param request request
|
* @param request request
|
||||||
* @return 返回true:可以进入到预发环境
|
* @return 返回true:可以进入到预发环境
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
protected boolean canVisitPre(Server server, HttpServletRequest request) {
|
protected boolean canVisitPre(Server server, HttpServletRequest request) {
|
||||||
String serverName = request.getServerName();
|
String serverName = request.getServerName();
|
||||||
return PRE_DOMAIN.equals(serverName);
|
return PRE_DOMAIN.equals(serverName);
|
||||||
@@ -83,19 +100,19 @@ public class EnvironmentServerChooser extends BaseServerChooser {
|
|||||||
*/
|
*/
|
||||||
protected boolean canVisitGray(Server server, HttpServletRequest request) {
|
protected boolean canVisitGray(Server server, HttpServletRequest request) {
|
||||||
ApiParam apiParam = ZuulContext.getApiParam();
|
ApiParam apiParam = ZuulContext.getApiParam();
|
||||||
DbUserKeyManager userKeyManager = SpringContext.getBean(DbUserKeyManager.class);
|
DbEnvGrayManager userKeyManager = SpringContext.getBean(DbEnvGrayManager.class);
|
||||||
boolean canVisit = false;
|
boolean canVisit = false;
|
||||||
if (this.isGrayUser(apiParam, userKeyManager, server, request)) {
|
/*if (this.isGrayUser(apiParam, userKeyManager, server, request)) {
|
||||||
// 指定灰度版本号
|
// 指定灰度版本号
|
||||||
String instanceId = server.getMetaInfo().getInstanceId();
|
String instanceId = server.getMetaInfo().getInstanceId();
|
||||||
String newVersion = userKeyManager.getVersion(instanceId, apiParam.fetchNameVersion());
|
String newVersion = userKeyManager.getVersion(instanceId, apiParam.fetchNameVersion());
|
||||||
if (newVersion != null) {
|
if (newVersion != null) {
|
||||||
// 在header中设置新的版本号,然后微服务端先获取这个新版本号
|
// 在header中设置新的版本号,然后微服务端先获取这个新版本号
|
||||||
RequestContext.getCurrentContext().addZuulRequestHeader(ParamNames.GRAY_HEADER_VERSION_NAME, newVersion);
|
RequestContext.getCurrentContext().addZuulRequestHeader(ParamNames.HEADER_VERSION_NAME, newVersion);
|
||||||
canVisit = true;
|
canVisit = true;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
return canVisit;
|
return this.isGrayUser(apiParam, userKeyManager, server, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -108,7 +125,7 @@ public class EnvironmentServerChooser extends BaseServerChooser {
|
|||||||
* @param request request
|
* @param request request
|
||||||
* @return true:是
|
* @return true:是
|
||||||
*/
|
*/
|
||||||
protected boolean isGrayUser(Param param, DbUserKeyManager userKeyManager, Server server, HttpServletRequest request) {
|
protected boolean isGrayUser(Param param, DbEnvGrayManager userKeyManager, Server server, HttpServletRequest request) {
|
||||||
String instanceId = server.getMetaInfo().getInstanceId();
|
String instanceId = server.getMetaInfo().getInstanceId();
|
||||||
// 这里的灰度用户为appKey,包含此appKey则为灰度用户,允许访问
|
// 这里的灰度用户为appKey,包含此appKey则为灰度用户,允许访问
|
||||||
String appKey = param.fetchAppKey();
|
String appKey = param.fetchAppKey();
|
||||||
|
@@ -6,7 +6,7 @@ import com.gitee.sop.gateway.entity.ConfigGrayUserkey;
|
|||||||
import com.gitee.sop.gateway.mapper.ConfigGrayUserkeyMapper;
|
import com.gitee.sop.gateway.mapper.ConfigGrayUserkeyMapper;
|
||||||
import com.gitee.sop.gatewaycommon.bean.ChannelMsg;
|
import com.gitee.sop.gatewaycommon.bean.ChannelMsg;
|
||||||
import com.gitee.sop.gatewaycommon.bean.UserKeyDefinition;
|
import com.gitee.sop.gatewaycommon.bean.UserKeyDefinition;
|
||||||
import com.gitee.sop.gatewaycommon.manager.DefaultUserKeyManager;
|
import com.gitee.sop.gatewaycommon.manager.DefaultEnvGrayManager;
|
||||||
import com.gitee.sop.gatewaycommon.manager.ZookeeperContext;
|
import com.gitee.sop.gatewaycommon.manager.ZookeeperContext;
|
||||||
import com.gitee.sop.gatewaycommon.zuul.loadbalancer.ServiceGrayConfig;
|
import com.gitee.sop.gatewaycommon.zuul.loadbalancer.ServiceGrayConfig;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -29,7 +29,7 @@ import java.util.stream.Stream;
|
|||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class DbUserKeyManager extends DefaultUserKeyManager {
|
public class DbEnvGrayManager extends DefaultEnvGrayManager {
|
||||||
|
|
||||||
private static final int STATUS_ENABLE = 1;
|
private static final int STATUS_ENABLE = 1;
|
||||||
|
|
||||||
@@ -46,6 +46,7 @@ public class DbUserKeyManager extends DefaultUserKeyManager {
|
|||||||
List<ConfigGrayUserkey> list = configGrayUserkeyMapper.list(query);
|
List<ConfigGrayUserkey> list = configGrayUserkeyMapper.list(query);
|
||||||
for (ConfigGrayUserkey configGrayUserkey : list) {
|
for (ConfigGrayUserkey configGrayUserkey : list) {
|
||||||
this.setServiceGrayConfig(configGrayUserkey);
|
this.setServiceGrayConfig(configGrayUserkey);
|
||||||
|
this.addServiceInstance(configGrayUserkey.getServiceId(), configGrayUserkey.getInstanceId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@@ -14,6 +14,6 @@ public class ManagerInitializer {
|
|||||||
apiConfig.setRouteConfigManager(new DbRouteConfigManager());
|
apiConfig.setRouteConfigManager(new DbRouteConfigManager());
|
||||||
apiConfig.setLimitConfigManager(new DbLimitConfigManager());
|
apiConfig.setLimitConfigManager(new DbLimitConfigManager());
|
||||||
apiConfig.setIpBlacklistManager(new DbIPBlacklistManager());
|
apiConfig.setIpBlacklistManager(new DbIPBlacklistManager());
|
||||||
apiConfig.setUserKeyManager(new DbUserKeyManager());
|
apiConfig.setUserKeyManager(new DbEnvGrayManager());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -110,7 +110,7 @@ public class HttpTool {
|
|||||||
* @return
|
* @return
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public String request(String url, Map<String, String> form, Map<String, String> header, HTTPMethod method) throws IOException {
|
public String request(String url, Map<String, ?> form, Map<String, String> header, HTTPMethod method) throws IOException {
|
||||||
Request.Builder requestBuilder = buildRequestBuilder(url, form, method);
|
Request.Builder requestBuilder = buildRequestBuilder(url, form, method);
|
||||||
// 添加header
|
// 添加header
|
||||||
addHeader(requestBuilder, header);
|
addHeader(requestBuilder, header);
|
||||||
@@ -153,7 +153,7 @@ public class HttpTool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Request.Builder buildRequestBuilder(String url, Map<String, String> form, HTTPMethod method) {
|
public static Request.Builder buildRequestBuilder(String url, Map<String, ?> form, HTTPMethod method) {
|
||||||
switch (method) {
|
switch (method) {
|
||||||
case GET:
|
case GET:
|
||||||
return new Request.Builder()
|
return new Request.Builder()
|
||||||
@@ -178,18 +178,18 @@ public class HttpTool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HttpUrl buildHttpUrl(String url, Map<String, String> form) {
|
public static HttpUrl buildHttpUrl(String url, Map<String, ?> form) {
|
||||||
HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder();
|
HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder();
|
||||||
for (Map.Entry<String, String> entry : form.entrySet()) {
|
for (Map.Entry<String, ?> entry : form.entrySet()) {
|
||||||
urlBuilder.addQueryParameter(entry.getKey(), entry.getValue());
|
urlBuilder.addQueryParameter(entry.getKey(), String.valueOf(entry.getValue()));
|
||||||
}
|
}
|
||||||
return urlBuilder.build();
|
return urlBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FormBody buildFormBody(Map<String, String> form) {
|
public static FormBody buildFormBody(Map<String, ?> form) {
|
||||||
FormBody.Builder paramBuilder = new FormBody.Builder(StandardCharsets.UTF_8);
|
FormBody.Builder paramBuilder = new FormBody.Builder(StandardCharsets.UTF_8);
|
||||||
for (Map.Entry<String, String> entry : form.entrySet()) {
|
for (Map.Entry<String, ?> entry : form.entrySet()) {
|
||||||
paramBuilder.add(entry.getKey(), entry.getValue());
|
paramBuilder.add(entry.getKey(), String.valueOf(entry.getValue()));
|
||||||
}
|
}
|
||||||
return paramBuilder.build();
|
return paramBuilder.build();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user