diff --git a/changelog.md b/changelog.md index d7202a97..bb93ebb7 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,9 @@ # changelog +## 2.5.11 + +- 优化灰度/预发布请求 + ## 2.5.10 - 优化签名认证,优化校验日志打印 diff --git a/sop-auth/pom.xml b/sop-auth/pom.xml index a17fdc20..2fe15bc3 100644 --- a/sop-auth/pom.xml +++ b/sop-auth/pom.xml @@ -26,7 +26,7 @@ com.gitee.sop sop-service-common - 2.5.10-SNAPSHOT + 2.5.11-SNAPSHOT diff --git a/sop-common/pom.xml b/sop-common/pom.xml index 98e0cf7c..48c9c5f5 100644 --- a/sop-common/pom.xml +++ b/sop-common/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.gitee.sop sop-common - 2.5.10-SNAPSHOT + 2.5.11-SNAPSHOT pom diff --git a/sop-common/sop-gateway-common/pom.xml b/sop-common/sop-gateway-common/pom.xml index 1486cd9f..b0f6ad38 100644 --- a/sop-common/sop-gateway-common/pom.xml +++ b/sop-common/sop-gateway-common/pom.xml @@ -5,11 +5,11 @@ com.gitee.sop sop-common - 2.5.10-SNAPSHOT + 2.5.11-SNAPSHOT ../pom.xml sop-gateway-common - 2.5.10-SNAPSHOT + 2.5.11-SNAPSHOT jar sop-gateway-common diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/EnvGrayManager.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/EnvGrayManager.java index a42030a6..54d36f59 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/EnvGrayManager.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/EnvGrayManager.java @@ -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 灰度配置 diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/configuration/BaseZuulConfiguration.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/configuration/BaseZuulConfiguration.java index ecc2f54f..3b6dbc9f 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/configuration/BaseZuulConfiguration.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/configuration/BaseZuulConfiguration.java @@ -6,14 +6,17 @@ import com.gitee.sop.gatewaycommon.manager.AbstractConfiguration; import com.gitee.sop.gatewaycommon.manager.RouteRepositoryContext; import com.gitee.sop.gatewaycommon.param.ParamBuilder; import com.gitee.sop.gatewaycommon.zuul.ValidateService; +import com.gitee.sop.gatewaycommon.zuul.controller.ConfigChannelController; +import com.gitee.sop.gatewaycommon.zuul.controller.ErrorLogController; +import com.gitee.sop.gatewaycommon.zuul.controller.ZuulIndexController; import com.gitee.sop.gatewaycommon.zuul.filter.ErrorFilter; import com.gitee.sop.gatewaycommon.zuul.filter.FormBodyWrapperFilterExt; import com.gitee.sop.gatewaycommon.zuul.filter.PostResultFilter; +import com.gitee.sop.gatewaycommon.zuul.filter.PreEnvGrayFilter; import com.gitee.sop.gatewaycommon.zuul.filter.PreHttpServletRequestWrapperFilter; import com.gitee.sop.gatewaycommon.zuul.filter.PreLimitFilter; import com.gitee.sop.gatewaycommon.zuul.filter.PreParameterFormatterFilter; import com.gitee.sop.gatewaycommon.zuul.filter.PreValidateFilter; -import com.gitee.sop.gatewaycommon.zuul.filter.PreEnvGrayFilter; import com.gitee.sop.gatewaycommon.zuul.filter.Servlet30WrapperFilterExt; import com.gitee.sop.gatewaycommon.zuul.route.SopRouteLocator; import com.gitee.sop.gatewaycommon.zuul.route.ZuulRouteCache; @@ -39,6 +42,21 @@ public class BaseZuulConfiguration extends AbstractConfiguration { @Autowired protected ServerProperties server; + @Bean + public ConfigChannelController configChannelController() { + return new ConfigChannelController(); + } + + @Bean + public ErrorLogController errorLogController() { + return new ErrorLogController(); + } + + @Bean + public ZuulIndexController zuulIndexController() { + return new ZuulIndexController(); + } + @Bean @ConditionalOnMissingBean ParamBuilder paramBuilder() { diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/configuration/WebappZuulConfiguration.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/configuration/WebappZuulConfiguration.java index ff16de63..1517226e 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/configuration/WebappZuulConfiguration.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/configuration/WebappZuulConfiguration.java @@ -8,6 +8,7 @@ import com.gitee.sop.gatewaycommon.result.CustomDataNameBuilder; * * @author tanghc */ +@Deprecated public class WebappZuulConfiguration extends BaseZuulConfiguration { static { diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/ConfigChannelController.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/controller/ConfigChannelController.java similarity index 72% rename from sop-gateway/src/main/java/com/gitee/sop/gateway/controller/ConfigChannelController.java rename to sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/controller/ConfigChannelController.java index b6a96478..2f1acd07 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/ConfigChannelController.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/controller/ConfigChannelController.java @@ -1,21 +1,21 @@ -package com.gitee.sop.gateway.controller; +package com.gitee.sop.gatewaycommon.zuul.controller; import com.alibaba.fastjson.JSON; -import com.gitee.sop.gateway.manager.DbEnvGrayManager; -import com.gitee.sop.gateway.manager.DbIPBlacklistManager; -import com.gitee.sop.gateway.manager.DbIsvManager; -import com.gitee.sop.gateway.manager.DbIsvRoutePermissionManager; -import com.gitee.sop.gateway.manager.DbLimitConfigManager; -import com.gitee.sop.gateway.manager.DbRouteConfigManager; import com.gitee.sop.gatewaycommon.bean.GatewayPushDTO; import com.gitee.sop.gatewaycommon.bean.NacosConfigs; import com.gitee.sop.gatewaycommon.bean.SpringContext; import com.gitee.sop.gatewaycommon.manager.ChannelMsgProcessor; +import com.gitee.sop.gatewaycommon.manager.EnvGrayManager; +import com.gitee.sop.gatewaycommon.manager.IPBlacklistManager; +import com.gitee.sop.gatewaycommon.manager.IsvRoutePermissionManager; +import com.gitee.sop.gatewaycommon.manager.LimitConfigManager; +import com.gitee.sop.gatewaycommon.manager.RouteConfigManager; +import com.gitee.sop.gatewaycommon.secret.IsvManager; import com.gitee.sop.gatewaycommon.util.RequestUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import java.io.IOException; @@ -26,24 +26,24 @@ import java.util.Map; * @author tanghc */ @Slf4j -@RestController +@Controller public class ConfigChannelController { private static Map> processorMap = new HashMap<>(16); static { - processorMap.put(NacosConfigs.GROUP_CHANNEL + NacosConfigs.DATA_ID_GRAY, DbEnvGrayManager.class); - processorMap.put(NacosConfigs.GROUP_CHANNEL + NacosConfigs.DATA_ID_IP_BLACKLIST, DbIPBlacklistManager.class); - processorMap.put(NacosConfigs.GROUP_CHANNEL + NacosConfigs.DATA_ID_ISV, DbIsvManager.class); - processorMap.put(NacosConfigs.GROUP_CHANNEL + NacosConfigs.DATA_ID_ROUTE_PERMISSION, DbIsvRoutePermissionManager.class); - processorMap.put(NacosConfigs.GROUP_CHANNEL + NacosConfigs.DATA_ID_LIMIT_CONFIG, DbLimitConfigManager.class); - processorMap.put(NacosConfigs.GROUP_CHANNEL + NacosConfigs.DATA_ID_ROUTE_CONFIG, DbRouteConfigManager.class); + processorMap.put(NacosConfigs.GROUP_CHANNEL + NacosConfigs.DATA_ID_GRAY, EnvGrayManager.class); + processorMap.put(NacosConfigs.GROUP_CHANNEL + NacosConfigs.DATA_ID_IP_BLACKLIST, IPBlacklistManager.class); + processorMap.put(NacosConfigs.GROUP_CHANNEL + NacosConfigs.DATA_ID_ISV, IsvManager.class); + processorMap.put(NacosConfigs.GROUP_CHANNEL + NacosConfigs.DATA_ID_ROUTE_PERMISSION, IsvRoutePermissionManager.class); + processorMap.put(NacosConfigs.GROUP_CHANNEL + NacosConfigs.DATA_ID_LIMIT_CONFIG, LimitConfigManager.class); + processorMap.put(NacosConfigs.GROUP_CHANNEL + NacosConfigs.DATA_ID_ROUTE_CONFIG, RouteConfigManager.class); } @Value("${zuul.secret}") private String secret; - @PostMapping("/configChannelMsg") + @PostMapping("/sop/configChannelMsg") public String configChannel(HttpServletRequest request) throws IOException { String requestJson = RequestUtil.getText(request); String sign = request.getHeader("sign"); diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/ErrorLogController.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/controller/ErrorLogController.java similarity index 95% rename from sop-gateway/src/main/java/com/gitee/sop/gateway/controller/ErrorLogController.java rename to sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/controller/ErrorLogController.java index 93ab0dc6..3c773afb 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/ErrorLogController.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/controller/ErrorLogController.java @@ -1,4 +1,4 @@ -package com.gitee.sop.gateway.controller; +package com.gitee.sop.gatewaycommon.zuul.controller; import com.gitee.sop.gatewaycommon.bean.ApiConfig; import com.gitee.sop.gatewaycommon.bean.ErrorEntity; @@ -9,6 +9,7 @@ import com.gitee.sop.gatewaycommon.result.JsonResult; import com.gitee.sop.gatewaycommon.util.RequestUtil; import com.gitee.sop.gatewaycommon.validate.taobao.TaobaoSigner; import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @@ -19,7 +20,7 @@ import java.util.Map; /** * @author tanghc */ -@RestController +@Controller public class ErrorLogController { TaobaoSigner signer = new TaobaoSigner(); diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/RestServlet.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/controller/RestServlet.java similarity index 94% rename from sop-gateway/src/main/java/com/gitee/sop/gateway/controller/RestServlet.java rename to sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/controller/RestServlet.java index b6baadbb..1a1a484e 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/RestServlet.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/controller/RestServlet.java @@ -1,4 +1,4 @@ -package com.gitee.sop.gateway.controller; +package com.gitee.sop.gatewaycommon.zuul.controller; import com.gitee.sop.gatewaycommon.bean.SopConstants; import org.springframework.beans.factory.annotation.Value; @@ -14,7 +14,7 @@ import java.io.IOException; * 传统web开发入口 * @author tanghc */ -@WebServlet(urlPatterns = "/rest/*") +//@WebServlet(urlPatterns = "/rest/*") public class RestServlet extends HttpServlet { private static final String EMPTY_VERSION = ""; diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/ZuulIndexController.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/controller/ZuulIndexController.java similarity index 65% rename from sop-gateway/src/main/java/com/gitee/sop/gateway/controller/ZuulIndexController.java rename to sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/controller/ZuulIndexController.java index 86d01ef9..ac1606e4 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/controller/ZuulIndexController.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/controller/ZuulIndexController.java @@ -1,4 +1,4 @@ -package com.gitee.sop.gateway.controller; +package com.gitee.sop.gatewaycommon.zuul.controller; import com.gitee.sop.gatewaycommon.bean.SopConstants; import com.gitee.sop.gatewaycommon.zuul.ValidateService; @@ -9,8 +9,10 @@ import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; +import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.io.IOException; /** * zuul网关入口 @@ -21,12 +23,17 @@ import javax.servlet.http.HttpServletResponse; @Controller public class ZuulIndexController { + private static final String EMPTY_VERSION = ""; + @Autowired private ValidateService validateService; @Value("${zuul.servlet-path:/zuul}") private String path; + @Value("${sop.restful.path:/rest}") + private String restPath; + /** * 验证回调,可自定义实现接口 */ @@ -49,6 +56,25 @@ public class ZuulIndexController { validateService.validate(request, response, callback); } + /** + * restful入口 + * @param request + * @param response + * @throws ServletException + * @throws IOException + */ + @RequestMapping("/rest/**") + public void rest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + String url = request.getRequestURL().toString(); + int index = url.indexOf(restPath); + // 取/rest的后面部分 + String path = url.substring(index + restPath.length()); + request.setAttribute(SopConstants.REDIRECT_METHOD_KEY, path); + request.setAttribute(SopConstants.REDIRECT_VERSION_KEY, EMPTY_VERSION); + request.setAttribute(SopConstants.SOP_NOT_MERGE, true); + request.getRequestDispatcher(this.path).forward(request, response); + } + @RequestMapping("/{method}/{version}/") public void redirect( @PathVariable("method") String method @@ -60,7 +86,4 @@ public class ZuulIndexController { request.setAttribute(SopConstants.REDIRECT_VERSION_KEY, version); validateService.validate(request, response, callback); } - - - } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreEnvGrayFilter.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreEnvGrayFilter.java index 7245cb74..bc5e00de 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreEnvGrayFilter.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/filter/PreEnvGrayFilter.java @@ -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; diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/BaseServerChooser.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/BaseServerChooser.java index d08db36b..e92a2fb2 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/BaseServerChooser.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/zuul/loadbalancer/BaseServerChooser.java @@ -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 allServers = lb.getAllServers(); - HttpServletRequest request = RequestContext.getCurrentContext().getRequest(); + List servers = lb.getReachableServers(); + RequestContext currentContext = RequestContext.getCurrentContext(); + // 存放预发服务器 + List preServers = new ArrayList<>(4); + // 存放灰度发布服务器 + List grayServers = new ArrayList<>(4); + // 存放非预发服务器 + List notPreServers = new ArrayList<>(4); - List 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 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(currentContext.getRequest())) { + return doChoose(preServers, key); + } + // 如果是灰度请求 + if (this.isRequestGrayServer(currentContext)) { 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 servers, Object key) { diff --git a/sop-common/sop-service-common/pom.xml b/sop-common/sop-service-common/pom.xml index 3abf6f8c..acddbd0c 100644 --- a/sop-common/sop-service-common/pom.xml +++ b/sop-common/sop-service-common/pom.xml @@ -6,11 +6,11 @@ com.gitee.sop sop-common - 2.5.10-SNAPSHOT + 2.5.11-SNAPSHOT ../pom.xml sop-service-common - 2.5.10-SNAPSHOT + 2.5.11-SNAPSHOT jar sop-service-common diff --git a/sop-example/sop-book/sop-book-web/pom.xml b/sop-example/sop-book/sop-book-web/pom.xml index 68c3dfe5..e4254809 100644 --- a/sop-example/sop-book/sop-book-web/pom.xml +++ b/sop-example/sop-book/sop-book-web/pom.xml @@ -28,7 +28,7 @@ com.gitee.sop sop-service-common - 2.5.10-SNAPSHOT + 2.5.11-SNAPSHOT com.gitee.sop diff --git a/sop-example/sop-easyopen/pom.xml b/sop-example/sop-easyopen/pom.xml index 02829e7f..88279bab 100644 --- a/sop-example/sop-easyopen/pom.xml +++ b/sop-example/sop-easyopen/pom.xml @@ -29,7 +29,7 @@ com.gitee.sop sop-service-common - 2.5.10-SNAPSHOT + 2.5.11-SNAPSHOT diff --git a/sop-example/sop-story/sop-story-web/pom.xml b/sop-example/sop-story/sop-story-web/pom.xml index 1df94a82..f877e33a 100644 --- a/sop-example/sop-story/sop-story-web/pom.xml +++ b/sop-example/sop-story/sop-story-web/pom.xml @@ -28,7 +28,7 @@ com.gitee.sop sop-service-common - 2.5.10-SNAPSHOT + 2.5.11-SNAPSHOT com.gitee.sop diff --git a/sop-gateway/pom.xml b/sop-gateway/pom.xml index 79abd906..b5df0fc6 100644 --- a/sop-gateway/pom.xml +++ b/sop-gateway/pom.xml @@ -29,7 +29,7 @@ com.gitee.sop sop-gateway-common - 2.5.10-SNAPSHOT + 2.5.11-SNAPSHOT diff --git a/sop-website/pom.xml b/sop-website/pom.xml index 1e4d8251..a949cadc 100644 --- a/sop-website/pom.xml +++ b/sop-website/pom.xml @@ -35,7 +35,7 @@ com.gitee.sop sop-gateway-common - 2.5.10-SNAPSHOT + 2.5.11-SNAPSHOT