From f5048a76ca8b7c167dc49658cd6db0eb9728cccd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E5=BF=97=E5=BC=BA?= Date: Sat, 31 Oct 2020 13:37:25 +0800 Subject: [PATCH 1/3] =?UTF-8?q?1=E3=80=81=E5=8D=87=E7=BA=A7SpringBoot,alib?= =?UTF-8?q?aba,springCloud=E7=89=88=E6=9C=AC=E3=80=82=202=E3=80=81?= =?UTF-8?q?=E7=A7=BB=E9=99=A4=E9=83=A8=E5=88=86=E5=9C=A8SpringBoot?= =?UTF-8?q?=E5=B7=B2=E7=BB=8F=E5=AE=9A=E4=B9=89=E7=9A=84=E4=BE=9D=E8=B5=96?= =?UTF-8?q?=EF=BC=8C=E9=81=BF=E5=85=8D=E7=89=88=E6=9C=AC=E5=86=B2=E7=AA=81?= =?UTF-8?q?=E3=80=82=203=E3=80=81=E5=8D=87=E7=BA=A7guava=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 18 +++++++++--------- .../configuration/ServiceConfiguration.java | 5 +++-- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/pom.xml b/pom.xml index 1f8546a2..f17a2d60 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 2.2.5.RELEASE + 2.3.4.RELEASE @@ -36,17 +36,17 @@ 1.8 - 2.2.5.RELEASE + 2.3.4.RELEASE - Hoxton.SR3 + Hoxton.SR8 - 2.2.1.RELEASE + 2.2.3.RELEASE 1.2.3 - 1.7.5 + 4.11 @@ -58,11 +58,11 @@ 3.8.1 1.11 1.2 - 2.0.1.Final - 6.0.13.Final + + 1.9.1 2.3.0.RELEASE - 27.1-jre + 29.0-jre 1.5.21 2.9.2 2.9.2 @@ -247,4 +247,4 @@ - \ No newline at end of file + diff --git a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/ServiceConfiguration.java b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/ServiceConfiguration.java index 1f302e88..07294768 100644 --- a/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/ServiceConfiguration.java +++ b/sop-common/sop-service-common/src/main/java/com/gitee/sop/servercommon/configuration/ServiceConfiguration.java @@ -1,6 +1,7 @@ package com.gitee.sop.servercommon.configuration; import com.alibaba.cloud.nacos.NacosDiscoveryProperties; +import com.alibaba.cloud.nacos.NacosServiceManager; import com.alibaba.cloud.nacos.discovery.NacosWatch; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.ObjectProvider; @@ -21,7 +22,7 @@ public class ServiceConfiguration extends SpringmvcConfiguration { @Bean @ConditionalOnMissingBean @ConditionalOnProperty("spring.cloud.nacos.discovery.server-addr") - public NacosWatch nacosWatch(NacosDiscoveryProperties nacosDiscoveryProperties, ObjectProvider taskScheduler, Environment environment) { + public NacosWatch nacosWatch(NacosDiscoveryProperties nacosDiscoveryProperties, ObjectProvider taskScheduler, Environment environment, NacosServiceManager nacosServiceManager) { Map metadata = nacosDiscoveryProperties.getMetadata(); String contextPath = environment.getProperty(METADATA_SERVER_CONTEXT_PATH); // 将context-path信息加入到metadata中 @@ -31,7 +32,7 @@ public class ServiceConfiguration extends SpringmvcConfiguration { // 在元数据中新增启动时间,不能修改这个值,不然网关拉取接口会有问题 // 如果没有这个值,网关会忽略这个服务 metadata.put("server.startup-time", String.valueOf(System.currentTimeMillis())); - return new NacosWatch(nacosDiscoveryProperties, taskScheduler); + return new NacosWatch(nacosServiceManager, nacosDiscoveryProperties, taskScheduler); } } From ea1f45d14c43f76c117571e3bdf4713d8a73c9b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E5=BF=97=E5=BC=BA?= Date: Sat, 31 Oct 2020 14:29:52 +0800 Subject: [PATCH 2/3] =?UTF-8?q?1=E3=80=81=E8=B0=83=E6=95=B4Maven=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E5=8C=85=EF=BC=8C=E5=8E=BB=E9=99=A4SpringMvc=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=8F=B7=E7=BB=91=E5=AE=9A=E3=80=82=202=E3=80=81?= =?UTF-8?q?=E5=BC=95=E5=85=A5Actuator=E7=9B=B8=E5=85=B3=E7=9A=84=E5=8C=85?= =?UTF-8?q?=E4=B8=8E=E9=85=8D=E7=BD=AE=203=E3=80=81=E5=BC=95=E5=85=A5Prome?= =?UTF-8?q?theus=E6=8E=A5=E5=8F=A3=E7=AB=AF=E7=82=B9=EF=BC=8C=E5=90=90?= =?UTF-8?q?=E5=87=BA=E7=9B=91=E6=8E=A7=E6=8C=87=E6=A0=87=E3=80=82=204?= =?UTF-8?q?=E3=80=81=E5=A2=9E=E5=8A=A0=E8=B0=83=E7=94=A8=E7=9B=91=E6=8E=A7?= =?UTF-8?q?=E6=8C=87=E6=A0=87=E9=87=87=E9=9B=86=E3=80=82=205=E3=80=81?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=B0=83=E7=94=A8=E6=97=A5=E5=BF=97=E8=BE=93?= =?UTF-8?q?=E5=87=BA=EF=BC=8C=E6=A0=B9=E6=8D=AELogId=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E7=BB=91=E5=AE=9A=E3=80=82=206=E3=80=81=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E5=90=AF=E5=8A=A8=E7=9A=84=E6=89=AB=E6=8F=8F=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=EF=BC=8C=E5=8E=BB=E9=99=A4=E9=87=8D=E5=A4=8D=E6=B3=A8=E5=86=8C?= =?UTF-8?q?=E3=80=82=207=E3=80=81=E8=B0=83=E6=95=B4=E7=8E=B0=E6=9C=89Monit?= =?UTF-8?q?orData=E6=95=B0=E6=8D=AE=EF=BC=8C=E4=BF=AE=E6=94=B9=E4=B8=BALRU?= =?UTF-8?q?Map=EF=BC=8C=E9=81=BF=E5=85=8D=E5=86=85=E5=AD=98=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E8=BF=87=E5=A4=A7=E3=80=82=208=E3=80=81=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E6=8B=A6=E6=88=AA=E5=99=A8=E5=BC=82=E5=B8=B8=E6=97=B6?= =?UTF-8?q?=E7=9A=84=E6=97=A5=E5=BF=97=E8=BE=93=E5=87=BA=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sop-common/sop-gateway-common/pom.xml | 17 ++ .../config/BaseGatewayAutoConfiguration.java | 1 + .../BaseGatewayConfiguration.java | 38 ++-- .../interceptor/LoggerRouteInterceptor.java | 105 +++++++++++ .../interceptor/MetricRouteInterceptor.java | 124 +++++++++++++ .../interceptor/MonitorRouteInterceptor.java | 5 +- .../gatewaycommon/monitor/MonitorInfo.java | 19 +- .../util/RouteInterceptorUtil.java | 2 +- sop-common/sop-service-common/pom.xml | 2 +- sop-gateway/pom.xml | 6 +- .../sop/gateway/SopGatewayApplication.java | 2 +- .../resources/META-INF/gateway.properties | 168 ++++++++++++++++++ 12 files changed, 459 insertions(+), 30 deletions(-) create mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/interceptor/LoggerRouteInterceptor.java create mode 100644 sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/interceptor/MetricRouteInterceptor.java diff --git a/sop-common/sop-gateway-common/pom.xml b/sop-common/sop-gateway-common/pom.xml index feb40b6f..c00149a7 100644 --- a/sop-common/sop-gateway-common/pom.xml +++ b/sop-common/sop-gateway-common/pom.xml @@ -96,6 +96,23 @@ javax.servlet-api provided + + + org.springframework.boot + spring-boot-actuator + + + io.micrometer + micrometer-registry-prometheus + + + + + + org.springframework.boot + spring-boot-configuration-processor + true + diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/config/BaseGatewayAutoConfiguration.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/config/BaseGatewayAutoConfiguration.java index e11c49eb..873c8138 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/config/BaseGatewayAutoConfiguration.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/config/BaseGatewayAutoConfiguration.java @@ -24,6 +24,7 @@ public class BaseGatewayAutoConfiguration { log.info("网关基本配置:{}", JSON.toJSONString(apiConfigProperties)); ApiConfig apiConfig = ApiConfig.getInstance(); BeanUtils.copyProperties(apiConfigProperties, apiConfig); + log.info("网关最终配置:{}", JSON.toJSONString(apiConfig)); } } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/configuration/BaseGatewayConfiguration.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/configuration/BaseGatewayConfiguration.java index f5036d8a..c39466b1 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/configuration/BaseGatewayConfiguration.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/configuration/BaseGatewayConfiguration.java @@ -50,25 +50,25 @@ public class BaseGatewayConfiguration extends AbstractConfiguration { return new IndexFilter(); } - @Bean - public GatewayController gatewayErrorController() { - return new GatewayController(); - } - - @Bean - public ConfigChannelController configChannelController() { - return new ConfigChannelController(); - } - - @Bean - public ErrorLogController errorLogController() { - return new ErrorLogController(); - } - - @Bean - public GatewayMonitorController gatewayMonitorController() { - return new GatewayMonitorController(); - } +// @Bean +// public GatewayController gatewayErrorController() { +// return new GatewayController(); +// } +// +// @Bean +// public ConfigChannelController configChannelController() { +// return new ConfigChannelController(); +// } +// +// @Bean +// public ErrorLogController errorLogController() { +// return new ErrorLogController(); +// } +// +// @Bean +// public GatewayMonitorController gatewayMonitorController() { +// return new GatewayMonitorController(); +// } /** * 自定义异常处理[@@]注册Bean时依赖的Bean,会从容器中直接获取,所以直接注入即可 diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/interceptor/LoggerRouteInterceptor.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/interceptor/LoggerRouteInterceptor.java new file mode 100644 index 00000000..0b3b5a07 --- /dev/null +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/interceptor/LoggerRouteInterceptor.java @@ -0,0 +1,105 @@ +package com.gitee.sop.gatewaycommon.interceptor; + +import com.gitee.sop.gatewaycommon.gateway.ServerWebExchangeUtil; +import com.gitee.sop.gatewaycommon.param.ApiParam; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.gateway.route.Route; +import org.springframework.cloud.gateway.support.ServerWebExchangeUtils; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; + +import java.net.URI; +import java.util.Iterator; +import java.util.LinkedHashSet; + +/** + * . + * + * @author linzhiqiang + * @version Revision 1.0.0 + * @版权: 版权所有 (c) 2011 + * @see: + * @创建日期: 2020/9/11 + * @功能说明: + */ +@Component +@ConditionalOnProperty(prefix = "sop.route.logger", name = "enabled", havingValue = "true", matchIfMissing = true) +public class LoggerRouteInterceptor implements RouteInterceptor { + + private Logger logger = LoggerFactory.getLogger("ROUTELOGGER"); + + @Override + public void preRoute(RouteInterceptorContext context) { + ApiParam apiParam = context.getApiParam(); + ServerWebExchange serverWebExchange = (ServerWebExchange) context.getRequestContext(); + String logId = serverWebExchange.getAttribute(ServerWebExchange.LOG_ID_ATTRIBUTE); + logger.info( + "requestId_#$#_{}_|$|_requestIp_#$#_{}_|$|_interface_#$#_{}_|$|_requestParam_#$#_{}_|$|_requestHeaders_#$#_{}", + logId, apiParam.fetchIp(), apiParam.fetchNameVersion(), apiParam.toJSONString(), + serverWebExchange.getRequest().getHeaders().toString()); + } + + @Override + public void afterRoute(RouteInterceptorContext context) { + ApiParam apiParam = context.getApiParam(); + ServerWebExchange serverWebExchange = (ServerWebExchange) context.getRequestContext(); + String logId = serverWebExchange.getAttribute(ServerWebExchange.LOG_ID_ATTRIBUTE); + String routeId = apiParam.fetchNameVersion(); + long spendTime = context.getFinishTimeMillis() - context.getBeginTimeMillis(); + ServerWebExchange exchange = (ServerWebExchange) context.getRequestContext(); + Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR); + URI uri = null; + LinkedHashSet hashSet = (LinkedHashSet) exchange + .getAttribute(ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR); + if (hashSet != null) { + Iterator it = hashSet.iterator(); + if (it.hasNext()) { + uri = it.next(); + } + } + String oriUrl = StringUtils.trim(uri == null ? "" : uri.toString()); + + URI dest = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR); + String destUrl = "unknown"; + if (dest != null) { + destUrl = dest.toString(); + if (destUrl.indexOf("?") > 0) { + destUrl = destUrl.substring(0, destUrl.indexOf("?")); + } + } + String gRouteId = "unknown"; + String routeUri = "unknown"; + if (route != null) { + gRouteId = route.getId(); + routeUri = route.getUri().toString(); + } + ServiceInstance serviceInstance = context.getServiceInstance(); + String serviceId = "unknown"; + String instanceId = "unknown"; + if (serviceInstance != null) { + serviceId = context.getServiceInstance().getServiceId(); + instanceId = context.getServiceInstance().getInstanceId(); + } + Throwable throwable = ServerWebExchangeUtil.getThrowable(exchange); + String exceptionMsg = ""; + if (throwable != null) { + exceptionMsg = throwable.getMessage(); + } + String errorMsg = context.getServiceErrorMsg(); + logger.info( + "requestId_#$#_{}_|$|_requestResult_#$#_{}_|$|_coastTime_#$#_{}_|$|_interface_#$#_{}_|$|_gatewayRouteId_#$#_{}_|$|_oriUrl_#$#_{}_|$|_destUrl_#$#_{}_|$|_routeUri_#$#_{}_|$|_serviceId_#$#_{}_|$|_instanceId_#$#_{}_|$|_responeStatus_#$#_{}_|$|_responeResult_#$#_{}_|$|_responseHeaders_#$#_{}_|$|_error_#$#_{}", + logId, context.isSuccessRequest(), spendTime, routeId, gRouteId, oriUrl, destUrl, + routeUri, serviceId, instanceId, context.getResponseStatus(), + context.getServiceResult(), serverWebExchange.getResponse().getHeaders().toString(), + StringUtils.isNotBlank(exceptionMsg) ? exceptionMsg : StringUtils.isEmpty(errorMsg) ? "" : errorMsg); + } + + @Override + public int getOrder() { + return 0; + } +} diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/interceptor/MetricRouteInterceptor.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/interceptor/MetricRouteInterceptor.java new file mode 100644 index 00000000..4e4db93e --- /dev/null +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/interceptor/MetricRouteInterceptor.java @@ -0,0 +1,124 @@ +package com.gitee.sop.gatewaycommon.interceptor; + +import com.gitee.sop.gatewaycommon.param.ApiParam; +import io.micrometer.core.instrument.DistributionSummary; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Timer; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.gateway.route.Route; +import org.springframework.cloud.gateway.support.ServerWebExchangeUtils; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; + +import java.net.URI; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +/** + * . + * + * @author linzhiqiang + * @version Revision 1.0.0 + * @版权: 版权所有 (c) 2011 + * @see: + * @创建日期: 2020/9/11 + * @功能说明: + */ +@Component +//@ConditionalOnClass(name = {"io.micrometer.core.instrument.MeterRegistry"}) +public class MetricRouteInterceptor implements RouteInterceptor { + + private Logger logger = LoggerFactory.getLogger(MetricRouteInterceptor.class); + @Autowired + private MeterRegistry meterRegistry; + + public MetricRouteInterceptor() { + logger.info("初始化MetricRouteInterceptor"); + } + + @Override + public void preRoute(RouteInterceptorContext context) { + + } + + @Override + public void afterRoute(RouteInterceptorContext context) { + ApiParam apiParam = context.getApiParam(); + String routeId = apiParam.fetchNameVersion(); + long spendTime = context.getFinishTimeMillis() - context.getBeginTimeMillis(); + ServerWebExchange exchange = (ServerWebExchange) context.getRequestContext(); + Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR); + URI uri = null; + LinkedHashSet hashSet = (LinkedHashSet) exchange + .getAttribute(ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR); + if (hashSet != null) { + Iterator it = hashSet.iterator(); + if (it.hasNext()) { + uri = it.next(); + } + } + String oriUrl = StringUtils.trim(uri == null ? "" : uri.toString()); + if (oriUrl.indexOf("?") > 0) { + oriUrl = oriUrl.substring(0, oriUrl.indexOf("?")); + } + + URI dest = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR); + String destUrl = dest.toString(); + if (destUrl.indexOf("?") > 0) { + destUrl = destUrl.substring(0, destUrl.indexOf("?")); + } + String gRouteId = route.getId(); + String routeUri = route.getUri().toString(); + boolean isSuc = context.isSuccessRequest(); + if (meterRegistry != null) { + Timer timer = Timer.builder("sop.route.timer").description("SOP路由耗时统计") + .tag("requestUri", exchange.getRequest().getURI().getRawPath()) + .tag("routeId", routeId).tag("gRouteId", gRouteId).tag("routeUri", routeUri) + .tag("oriUrl", oriUrl).tag("destUrl", destUrl).tag("serviceId", + context.getServiceInstance() != null ? + context.getServiceInstance().getServiceId() : + "").tag("instanceId", context.getServiceInstance() != null ? + context.getServiceInstance().getInstanceId() : + "").tag("status", Objects.toString(context.getResponseStatus())) + .tag("isSuccess", Objects.toString(isSuc)).publishPercentileHistogram() + .register(meterRegistry); + timer.record(spendTime, TimeUnit.MILLISECONDS); + + DistributionSummary request = DistributionSummary.builder("sop.route.request.size") + .scale(100).tag("requestUri", exchange.getRequest().getURI().getRawPath()) + .tag("routeId", routeId).tag("gRouteId", gRouteId).tag("routeUri", routeUri) + .tag("oriUrl", oriUrl).tag("destUrl", destUrl).tag("serviceId", + context.getServiceInstance() != null ? + context.getServiceInstance().getServiceId() : + "").tag("instanceId", context.getServiceInstance() != null ? + context.getServiceInstance().getInstanceId() : + "").tag("status", Objects.toString(context.getResponseStatus())) + .tag("isSuccess", Objects.toString(isSuc)).register(meterRegistry); + request.record(context.getRequestDataSize()); + + DistributionSummary response = DistributionSummary.builder("sop.route.response.size") + .scale(100).tag("requestUri", exchange.getRequest().getURI().getRawPath()) + .tag("routeId", routeId).tag("gRouteId", gRouteId).tag("routeUri", routeUri) + .tag("oriUrl", oriUrl).tag("destUrl", destUrl).tag("serviceId", + context.getServiceInstance() != null ? + context.getServiceInstance().getServiceId() : + "").tag("instanceId", context.getServiceInstance() != null ? + context.getServiceInstance().getInstanceId() : + "").tag("status", Objects.toString(context.getResponseStatus())) + .tag("isSuccess", Objects.toString(isSuc)).publishPercentileHistogram() + .register(meterRegistry); + response.record(context.getResponseDataSize()); + } + + } + + @Override + public int getOrder() { + return -2; + } +} diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/interceptor/MonitorRouteInterceptor.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/interceptor/MonitorRouteInterceptor.java index e2942743..ddfe3258 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/interceptor/MonitorRouteInterceptor.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/interceptor/MonitorRouteInterceptor.java @@ -4,6 +4,7 @@ import com.gitee.sop.gatewaycommon.bean.ApiConfig; import com.gitee.sop.gatewaycommon.monitor.MonitorInfo; import com.gitee.sop.gatewaycommon.monitor.MonitorManager; import com.gitee.sop.gatewaycommon.param.ApiParam; +import org.springframework.web.server.ServerWebExchange; import java.util.ArrayList; import java.util.concurrent.LinkedBlockingQueue; @@ -54,7 +55,7 @@ public class MonitorRouteInterceptor implements RouteInterceptor { long spendTime = context.getFinishTimeMillis() - context.getBeginTimeMillis(); // 这步操作是线程安全的,底层调用了ConcurrentHashMap.computeIfAbsent MonitorInfo monitorInfo = monitorManager.getMonitorInfo(routeId, (k) -> this.createMonitorInfo(apiParam)); - + ServerWebExchange serverWebExchange = (ServerWebExchange) context.getRequestContext(); monitorInfo.storeMaxTime(spendTime); monitorInfo.storeMinTime(spendTime); monitorInfo.getTotalCount().incrementAndGet(); @@ -66,7 +67,7 @@ public class MonitorRouteInterceptor implements RouteInterceptor { } else { monitorInfo.getErrorCount().incrementAndGet(); String errorMsg = context.getServiceErrorMsg(); - monitorInfo.addErrorMsg(errorMsg); + monitorInfo.addErrorMsg(serverWebExchange.getAttribute(ServerWebExchange.LOG_ID_ATTRIBUTE), errorMsg); } } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/monitor/MonitorInfo.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/monitor/MonitorInfo.java index a05bd56a..c2337412 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/monitor/MonitorInfo.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/monitor/MonitorInfo.java @@ -1,6 +1,9 @@ package com.gitee.sop.gatewaycommon.monitor; +import com.gitee.sop.gatewaycommon.validate.alipay.StringUtils; import lombok.Data; +import org.apache.commons.collections.map.LRUMap; +import org.springframework.util.ObjectUtils; import java.util.List; import java.util.concurrent.atomic.AtomicLong; @@ -13,6 +16,8 @@ import java.util.concurrent.atomic.AtomicLong; @Data public class MonitorInfo { + private AtomicLong atomicLong = new AtomicLong(0); + /** * 接口名 */ @@ -62,6 +67,8 @@ public class MonitorInfo { */ private List errorMsgList; + private LRUMap lruMap = new LRUMap(128); + public synchronized void storeMaxTime(long spendTime) { if (spendTime > maxTime) { maxTime = spendTime; @@ -74,15 +81,21 @@ public class MonitorInfo { } } - public void addErrorMsg(String errorMsg) { + public void addErrorMsg(String logId, String errorMsg) { if (errorMsg == null || "".equals(errorMsg)) { return; } synchronized (this) { - if (errorMsgList != null && errorMsgList.size() < 10) { - errorMsgList.add(errorMsg); + if (StringUtils.isEmpty(logId)) { + logId = ObjectUtils.nullSafeToString(atomicLong.incrementAndGet()); } + lruMap.put(logId, errorMsg); } + // synchronized (this) { + // if (errorMsgList != null && errorMsgList.size() < 10) { + // errorMsgList.add(errorMsg); + // } + // } } } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/util/RouteInterceptorUtil.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/util/RouteInterceptorUtil.java index 54af542f..305c7d1b 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/util/RouteInterceptorUtil.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/util/RouteInterceptorUtil.java @@ -42,7 +42,7 @@ public class RouteInterceptorUtil { } }); } catch (Exception e) { - log.error("执行路由拦截器异常, apiParam:{}", routeInterceptorContext.getApiParam().toJSONString()); + log.error("执行路由拦截器异常, apiParam:{}", routeInterceptorContext.getApiParam().toJSONString(), e); } } diff --git a/sop-common/sop-service-common/pom.xml b/sop-common/sop-service-common/pom.xml index 5633391c..7b06defb 100644 --- a/sop-common/sop-service-common/pom.xml +++ b/sop-common/sop-service-common/pom.xml @@ -65,7 +65,7 @@ org.springframework spring-webmvc - 5.1.4.RELEASE + true diff --git a/sop-gateway/pom.xml b/sop-gateway/pom.xml index 97eed025..33ba62f9 100644 --- a/sop-gateway/pom.xml +++ b/sop-gateway/pom.xml @@ -39,17 +39,17 @@ org.springframework.boot spring-boot-starter-actuator - + + io.projectreactor.netty reactor-netty 0.9.4.RELEASE - + --> net.oschina.durcframework fastmybatis-spring-boot-starter diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/SopGatewayApplication.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/SopGatewayApplication.java index 20b6880a..ebcc7e92 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/SopGatewayApplication.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/SopGatewayApplication.java @@ -3,7 +3,7 @@ package com.gitee.sop.gateway; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -@SpringBootApplication +@SpringBootApplication(scanBasePackages = "com.gitee.sop") public class SopGatewayApplication { public static void main(String[] args) { diff --git a/sop-gateway/src/main/resources/META-INF/gateway.properties b/sop-gateway/src/main/resources/META-INF/gateway.properties index 332006c1..0f6da12f 100644 --- a/sop-gateway/src/main/resources/META-INF/gateway.properties +++ b/sop-gateway/src/main/resources/META-INF/gateway.properties @@ -39,3 +39,171 @@ spring.codec.max-in-memory-size=262144 # 文件上传配置 spring.servlet.multipart.enabled=true spring.servlet.multipart.max-file-size=10MB + + +###开启监控端点 +#终端WEB配置(WebEndpointProperties) +#应包含的终端ID或全部为''*''。 +management.endpoints.web.exposure.include=* +#应该排除的端点ID。 +#management.endpoints.web.exposure.exclude='*' +#Web端点的基本路径。相对于server.controller.context-path或management.server.controller.context-path,如果配置了management.server.port。 +#management.endpoints.web.base-path=/actuators +#端点ID和应该暴露它们的路径之间的映射。 +#management.endpoints.web.path-mapping: + +#ENDPOINTS CORS CONFIGURATION(CorsEndpointProperties) +#management.endpoints.web.cors.allow-credentials=#是否支持凭证。未设置时,不支持凭证。 +#在请求中允许使用逗号分隔的标题列表。''*''允许所有标题。 +management.endpoints.web.cors.allowed-headers='*' +#允许使用逗号分隔的方法列表。''*''允许所有方法。未设置时,默认为GET。 +management.endpoints.web.cors.allowed-methods=GET,POST +#逗号分隔的起源列表允许。''*''允许所有的来源。未设置时,CORS支持被禁用。 +management.endpoints.web.cors.allowed-origins='*' +#包含在响应中的逗号分隔的标题列表。 +#management.endpoints.web.cors.exposed-headers='*' +#客户端可以缓存飞行前请求的响应时间。如果未指定持续时间后缀,则将使用秒。 +management.endpoints.web.cors.max-age=1800s + +#审计事件ENDPOINT(AuditEventsEndpoint) +#响应可以被缓存的最长时间。 +management.endpoint.auditevents.cache.time-to-live=100ms +#是否启用auditevents端点。 +management.endpoint.auditevents.enabled=true + +#BEANS ENDPOINT(BeansEndpoint) +#可以缓存响应的最长时间。 +management.endpoint.beans.cache.time-to-live=60000ms +#是否启用bean端点。 +management.endpoint.beans.enabled=true + +#条件REPORT ENDPOINT(ConditionsReportEndpoint) +#可以缓存响应的最长时间。 +management.endpoint.conditions.cache.time-to-live=0ms +#是否启用条件端点。 +management.endpoint.conditions.enabled=true + +#配置属性报告ENDPOINT(ConfigurationPropertiesReportEndpoint,ConfigurationPropertiesReportEndpointProperties) +#响应可以被缓存的最大时间。 +management.endpoint.configprops.cache.time-to-live=60000ms +#是否启用configprops端点。 +management.endpoint.configprops.enabled=true +#应该清理的密钥。键可以是属性以正则表达式结尾的简单字符串。 +#management.endpoint.configprops.keys-to-sanitize:密码,密钥,密钥,令牌,'*'凭证。'*',vcap_services + +#ENVIRONMENT ENDPOINT(EnvironmentEndpoint,EnvironmentEndpointProperties) +#可以缓存响应的最长时间。 +management.endpoint.env.cache.time-to-live=60000ms +#是否启用env端点。 +management.endpoint.env.enabled=true +#management.endpoint.env.keys-to-sanitize:密码,秘密,密钥,令牌,'*'凭证。'*',vcap_services #应该清理的密钥。键可以是属性以正则表达式结尾的简单字符串。 + +#FLYWAY ENDPOINT(FlywayEndpoint) +#可以缓存响应的最长时间。 +management.endpoint.flyway.cache.time-to-live=0ms +#是否启用飞桥端点。 +management.endpoint.flyway.enabled=true + +#HEALTH ENDPOINT(HealthEndpoint,HealthEndpointProperties) +#可以缓存响应的最长时间。 +management.endpoint.health.cache.time-to-live=0ms +#是否启用运行状况端点。 +management.endpoint.health.enabled=true +#用于确定用户是否有权显示详细信息的角色。当为空时,所有认证的用户都被授权。 +management.endpoint.health.roles= +#何时显示完整健康详情。 +management.endpoint.health.show-details=always + +#HEAP DUMP ENDPOINT(HeapDumpWebEndpoint) +#响应可以被缓存的最长时间。 +management.endpoint.heapdump.cache.time-to-live=60000ms +#是否启用heapdump端点。 +management.endpoint.heapdump.enabled=true + +#HTTP TRACE ENDPOINT(HttpTraceEndpoint) +#响应可以被缓存的最大时间。 +management.endpoint.httptrace.cache.time-to-live=30000ms +#是否启用httptrace端点。 +management.endpoint.httptrace.enabled=true + +#INFO ENDPOINT(InfoEndpoint) +# 描述信息 +#响应可以被缓存的最大时间。 +management.endpoint.info.cache.time-to-live=18000ms +#是否启用信息端点。 +management.endpoint.info.enabled=true + +#JOLOKIA ENDPOINT(JolokiaProperties) +#Jolokia设置。有关更多详细信息,请参阅Jolokia的文档。 +#management.endpoint.jolokia.config.'*': +##是否启用jolokia端点。 +#management.endpoint.jolokia.enabled=true + +#LIQUIBASE ENDPOINT(LiquibaseEndpoint) +#可以缓存响应的最长时间。 +#management.endpoint.liquibase.cache.time-to-live=0ms +#是否启用liquibase端点。 +management.endpoint.liquibase.enabled=false + +#LOG FILE ENDPOINT(LogFileWebEndpoint,LogFileWebEndpointProperties) +#可以缓存响应的最长时间。 +management.endpoint.logfile.cache.time-to-live=0ms +#是否启用日志文件端点。 +management.endpoint.logfile.enabled=true +#要访问的外部日志文件。如果日志文件是由输出重定向写入的,而不是日志记录系统本身,则可以使用。 +#management.endpoint.logfile.external-file: + +#LOGGERS ENDPOINT(LoggersEndpoint) +#响应可以被缓存的最大时间。 +management.endpoint.loggers.cache.time-to-live=0ms +#是否启用记录器端点。 +management.endpoint.loggers.enabled=true + +#请求MAPPING ENDPOINT(MappingsEndpoint) +#可以缓存响应的最长时间。 +management.endpoint.mappings.cache.time-to-live=0ms +#是否启用映射端点。 +management.endpoint.mappings.enabled=true + +#METRICS ENDPOINT(MetricsEndpoint) +#响应可以被缓存的最大时间。 +management.endpoint.metrics.cache.time-to-live=10000ms +#是否启用度量标准端点。 +management.endpoint.metrics.enabled=true + +#PROMETHEUS ENDPOINT(PrometheusScrapeEndpoint) +#可以缓存响应的最长时间。 +management.endpoint.prometheus.cache.time-to-live=0ms +#是否启用普罗米修斯端点。 +management.endpoint.prometheus.enabled=true + +#SCHEDULED TASKS ENDPOINT(ScheduledTasksEndpoint) +#响应可以被缓存的最大时间。 +management.endpoint.scheduledtasks.cache.time-to-live=0ms +#是否启用scheduledtasks端点。 +management.endpoint.scheduledtasks.enabled=true + +#SESSIONS ENDPOINT(SessionsEndpoint) +#是否启用会话端点。 +management.endpoint.sessions.enabled=true + +#SHUTDOWN ENDPOINT(ShutdownEndpoint) +#是否启用关闭端点。 +management.endpoint.shutdown.enabled=false + +#THREAD DUMP ENDPOINT(ThreadDumpEndpoint) +#可以缓存响应的最长时间。 +management.endpoint.threaddump.cache.time-to-live=0ms +#是否启用线程转储端点。 +management.endpoint.threaddump.enabled=true + +#健康指标 +management.health.db.enabled=true +#是否启用数据库健康检查。 +management.health.defaults.enabled=true +#是否启用默认运行状况指示器。 +management.health.livenessstate.enabled=true +management.health.readynessstate.enabled=false +#management.endpoint.logfile.external-file=applogs/App_${POD_NAME:spring.application.name}_all.log +management.metrics.tags.application=${spring.application.name} + From 6ae4995bd31fabc8aec2fe96ec6df40c87f52ead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E5=BF=97=E5=BC=BA?= Date: Sat, 31 Oct 2020 14:33:13 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E6=94=B9=E7=94=A8loggerInterceptor?= =?UTF-8?q?=EF=BC=8C=E5=B1=8F=E8=94=BD=E8=BF=99=E4=B8=AA=E6=8B=A6=E6=88=AA?= =?UTF-8?q?=E5=99=A8=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gitee/sop/gateway/interceptor/MyRouteInterceptor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/interceptor/MyRouteInterceptor.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/interceptor/MyRouteInterceptor.java index 9a017ce9..efbcbcc2 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/interceptor/MyRouteInterceptor.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/interceptor/MyRouteInterceptor.java @@ -13,7 +13,7 @@ import org.springframework.stereotype.Component; * @author tanghc */ @Slf4j -@Component +//@Component public class MyRouteInterceptor implements RouteInterceptor { @Override