Commit 584096c3bcc58a2c98d6e98beb34640097f968f9

Authored by miaoguoxin
1 parent 89cac1a5

api metric测试入库

gateway-business/src/main/java/com/diligrp/xtrade/business/XtradeGatewayApplication.java
... ... @@ -16,7 +16,7 @@ import org.springframework.cloud.context.config.annotation.RefreshScope;
16 16 public class XtradeGatewayApplication {
17 17  
18 18 public static void main(String[] args) {
19   - ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.ADVANCED);
  19 + //ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.ADVANCED);
20 20 SpringApplication.run(XtradeGatewayApplication.class, args);
21 21 }
22 22  
... ...
gateway-business/src/main/java/com/diligrp/xtrade/business/application/TestAggregationApplication.java
... ... @@ -4,8 +4,22 @@ import com.diligrp.xtrade.business.domain.TestRequestDto;
4 4 import com.diligrp.xtrade.core.common.annotation.DispatchMapping;
5 5 import com.diligrp.xtrade.core.support.dispatch.DispatchContext;
6 6 import com.diligrp.xtrade.core.support.dispatch.RequestDispatcher;
  7 +import org.springframework.beans.factory.annotation.Autowired;
  8 +import org.springframework.http.server.reactive.ServerHttpRequest;
7 9 import org.springframework.stereotype.Component;
8 10 import org.springframework.validation.annotation.Validated;
  11 +import reactor.core.publisher.Mono;
  12 +import reactor.core.scheduler.Scheduler;
  13 +import reactor.core.scheduler.Schedulers;
  14 +
  15 +import java.time.Duration;
  16 +import java.util.concurrent.CompletableFuture;
  17 +import java.util.concurrent.ExecutionException;
  18 +import java.util.concurrent.TimeUnit;
  19 +import java.util.concurrent.TimeoutException;
  20 +import java.util.function.Consumer;
  21 +import java.util.function.Function;
  22 +import java.util.function.Supplier;
9 23  
10 24 /**
11 25 * @Auther: miaoguoxin
... ... @@ -16,14 +30,17 @@ import org.springframework.validation.annotation.Validated;
16 30 @Component
17 31 @DispatchMapping
18 32 public class TestAggregationApplication {
19   -
  33 + @Autowired
  34 + private ServerHttpRequest request;
20 35 @DispatchMapping("/test")
21   - public String test(DispatchContext<TestRequestDto> dispatchContext) {
  36 + public String test(DispatchContext<TestRequestDto> dispatchContext) throws InterruptedException {
  37 + System.out.println(request.getURI().getRawPath());
  38 + Thread.sleep(10000);
22 39 return "ffff";
23 40 }
24 41  
25 42 @DispatchMapping("test2")
26   - public void test2(@Validated DispatchContext<TestRequestDto> dispatchContext){
  43 + public void test2(@Validated DispatchContext<TestRequestDto> dispatchContext) {
27 44  
28 45 }
29 46  
... ...
gateway-business/src/main/resources/bootstrap-dev.yml
... ... @@ -2,12 +2,12 @@ spring:
2 2 cloud:
3 3 nacos:
4 4 discovery:
5   - username: nacos
6   - password: microtest
7   - server-addr: apitest.51shiban.com:80/n
8   - namespace: c86d8673-4d0a-469f-8bb8-1434c57c236c
  5 + username: xtrade
  6 + password: abcd1234
  7 + server-addr: http://10.28.1.79:8848
  8 + namespace: 35211f71-92a9-4f3e-975e-37b1132e05c8
9 9 config:
10   - username: nacos
11   - password: microtest
12   - server-addr: apitest.51shiban.com:80/n
13   - namespace: c86d8673-4d0a-469f-8bb8-1434c57c236c
  10 + username: xtrade
  11 + password: abcd1234
  12 + server-addr: http://10.28.1.79:8848
  13 + namespace: 35211f71-92a9-4f3e-975e-37b1132e05c8
... ...
gateway-core/src/main/java/com/diligrp/xtrade/core/common/utils/ResponseUtils.java
... ... @@ -18,7 +18,7 @@ public class ResponseUtils {
18 18  
19 19  
20 20 public static Mono<Void> writeForbidden(ServerHttpResponse response){
21   - Message<Object> message = Message.failure(
  21 + Message<Object> message = Message.builder().failure(
22 22 HttpStatus.FORBIDDEN.value(),HttpStatus.FORBIDDEN.toString());
23 23 return writeResponse(response,message);
24 24 }
... ...
gateway-core/src/main/java/com/diligrp/xtrade/core/filters/factory/DispatchGatewayFilterFactory.java
... ... @@ -4,6 +4,7 @@ import com.diligrp.xtrade.core.common.constant.GatewayConst;
4 4 import com.diligrp.xtrade.core.common.utils.ResponseUtils;
5 5 import com.diligrp.xtrade.core.support.dispatch.RequestDispatcher;
6 6 import com.diligrp.xtrade.shared.domain.Message;
  7 +import com.diligrp.xtrade.shared.type.ErrorCode;
7 8 import org.springframework.beans.factory.annotation.Autowired;
8 9 import org.springframework.cloud.gateway.filter.GatewayFilter;
9 10 import org.springframework.cloud.gateway.filter.GatewayFilterChain;
... ... @@ -13,6 +14,9 @@ import org.springframework.http.MediaType;
13 14 import org.springframework.stereotype.Component;
14 15 import org.springframework.web.server.ServerWebExchange;
15 16 import reactor.core.publisher.Mono;
  17 +import reactor.core.scheduler.Schedulers;
  18 +
  19 +import java.time.Duration;
16 20  
17 21 import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR;
18 22  
... ... @@ -23,7 +27,7 @@ import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.O
23 27 */
24 28 @Component
25 29 public class DispatchGatewayFilterFactory extends AbstractGatewayFilterFactory<DispatchGatewayFilterFactory.Config> {
26   -
  30 + private static final Duration EXECUTE_TIMEOUT = Duration.ofSeconds(5);
27 31 @Autowired
28 32 private RequestDispatcher requestDispatcher;
29 33  
... ... @@ -36,8 +40,8 @@ public class DispatchGatewayFilterFactory extends AbstractGatewayFilterFactory&lt;D
36 40 return new DispatchGatewayFilter(requestDispatcher);
37 41 }
38 42  
39   - private static class DispatchGatewayFilter implements GatewayFilter,Ordered{
40   - private final RequestDispatcher requestDispatcher;
  43 + private static class DispatchGatewayFilter implements GatewayFilter, Ordered {
  44 + private final RequestDispatcher requestDispatcher;
41 45  
42 46 public DispatchGatewayFilter(RequestDispatcher requestDispatcher) {
43 47 this.requestDispatcher = requestDispatcher;
... ... @@ -47,10 +51,13 @@ public class DispatchGatewayFilterFactory extends AbstractGatewayFilterFactory&lt;D
47 51 public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
48 52 String rawPath = exchange.getRequest().getURI().getRawPath();
49 53 String paramsJson = exchange.getAttribute(GatewayConst.CACHED_REQUEST_BODY_STR_ATTR);
50   - Message<Object> message = requestDispatcher.executeMethod(rawPath, paramsJson, exchange);
51   - //throw new RuntimeException("gggg");
52 54 exchange.getAttributes().put(ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR, MediaType.APPLICATION_JSON_VALUE);
53   - return ResponseUtils.writeResponse(exchange.getResponse(),message);
  55 + //callable处理,防止阻塞,netty的work thread比较敏感
  56 + return Mono.fromCallable(
  57 + () -> requestDispatcher.executeMethod(rawPath, paramsJson, exchange))
  58 + .subscribeOn(Schedulers.elastic())
  59 + .timeout(EXECUTE_TIMEOUT)
  60 + .flatMap(message -> ResponseUtils.writeResponse(exchange.getResponse(), message));
54 61 }
55 62  
56 63 @Override
... ... @@ -63,4 +70,5 @@ public class DispatchGatewayFilterFactory extends AbstractGatewayFilterFactory&lt;D
63 70 public static class Config {
64 71 }
65 72  
  73 +
66 74 }
... ...
gateway-core/src/main/java/com/diligrp/xtrade/core/filters/global/CacheRequestBodyGlobalFilter.java
... ... @@ -40,7 +40,7 @@ public class CacheRequestBodyGlobalFilter implements GlobalFilter, Ordered {
40 40 @Override
41 41 public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
42 42 String contentType = exchange.getRequest().getHeaders().getFirst(HttpHeaders.CONTENT_TYPE);
43   - if (StringUtils.isNotBlank(contentType) && !contentType.startsWith("multipart")) {
  43 + if (StringUtils.isNotBlank(contentType) && contentType.startsWith("multipart")) {
44 44 return chain.filter(exchange);
45 45 }
46 46 ServerRequest serverRequest = ServerRequest.create(exchange,
... ...
gateway-core/src/main/java/com/diligrp/xtrade/core/filters/web/FacadeWebFilter.java
... ... @@ -21,6 +21,8 @@ import org.springframework.web.server.WebFilter;
21 21 import org.springframework.web.server.WebFilterChain;
22 22 import reactor.core.publisher.Mono;
23 23  
  24 +import java.util.concurrent.TimeoutException;
  25 +
24 26  
25 27 /**
26 28 * @Auther: miaoguoxin
... ... @@ -67,19 +69,23 @@ public class FacadeWebFilter implements WebFilter {
67 69 if (dispatchEx.getCause() != null) {
68 70 return handleException(dispatchEx.getCause());
69 71 } else {
70   - return Message.failure(
  72 + return Message.builder().failure(
71 73 ErrorCode.UNKNOWN_ERROR.getCode(), ErrorCode.UNKNOWN_ERROR.getName());
72 74 }
73 75 } else if (ex instanceof ResponseStatusException) {
74 76 ResponseStatusException statusException = (ResponseStatusException) ex;
75 77 log.warn("response status error:{}", statusException.getMessage());
76   - return Message.failure(statusException.getStatus().value(), ex.getMessage());
  78 + return Message.builder().failure(statusException.getStatus().value(), ex.getMessage());
77 79 } else if (ex instanceof GatewayParamNotValidException) {
78   - return Message.failure(
  80 + return Message.builder().failure(
79 81 ErrorCode.ILLEGAL_PARAMS.getCode(), ex.getMessage());
  82 + } else if (ex instanceof TimeoutException){
  83 + log.error("api处理超时:", ex);
  84 + return Message.builder().failure(
  85 + ErrorCode.UNKNOWN_ERROR.getCode(), "请求超时");
80 86 } else {
81 87 log.error("unknown error:", ex);
82   - return Message.failure(
  88 + return Message.builder().failure(
83 89 ErrorCode.UNKNOWN_ERROR.getCode(), ErrorCode.UNKNOWN_ERROR.getName());
84 90 }
85 91 }
... ...
gateway-core/src/main/java/com/diligrp/xtrade/core/repository/GatewayRepository.java
... ... @@ -2,10 +2,13 @@ package com.diligrp.xtrade.core.repository;
2 2  
3 3 import com.diligrp.xtrade.core.common.constant.GatewayAttrType;
4 4 import com.diligrp.xtrade.core.exception.GatewayRouteResourceException;
  5 +import com.diligrp.xtrade.core.repository.dao.ApiMetricsDao;
5 6 import com.diligrp.xtrade.core.repository.dao.AttrConfigDao;
6 7 import com.diligrp.xtrade.core.repository.dao.RouteDao;
  8 +import com.diligrp.xtrade.core.repository.entity.ApiMetricsInfoEntity;
7 9 import com.diligrp.xtrade.core.repository.entity.GatewayAttrConfig;
8 10 import com.diligrp.xtrade.core.repository.entity.GatewayConfig;
  11 +import com.diligrp.xtrade.core.support.ApiMetricsInfo;
9 12 import com.diligrp.xtrade.shared.util.JsonUtils;
10 13 import com.diligrp.xtrade.shared.util.ReflectUtils;
11 14 import com.fasterxml.jackson.core.type.TypeReference;
... ... @@ -17,6 +20,7 @@ import org.springframework.cloud.gateway.route.RouteDefinition;
17 20 import org.springframework.stereotype.Repository;
18 21 import org.springframework.util.CollectionUtils;
19 22 import org.springframework.web.util.UriComponentsBuilder;
  23 +import reactor.core.publisher.Mono;
20 24  
21 25 import java.lang.reflect.InvocationTargetException;
22 26 import java.net.URI;
... ... @@ -38,25 +42,39 @@ public class GatewayRepository implements IGatewayRepository {
38 42 private RouteDao routeDao;
39 43 @Autowired
40 44 private AttrConfigDao attrConfigDao;
  45 + @Autowired
  46 + private ApiMetricsDao apiMetricsDao;
41 47  
42 48 @Override
43 49 public List<RouteDefinition> getAll() {
44 50 List<GatewayConfig> gatewayConfigs = routeDao.findAllForLoad();
45 51 List<GatewayAttrConfig> allAttrConfigs = attrConfigDao.findAllForLoad();
46   - Map<String , List<GatewayAttrConfig>> attrMap = allAttrConfigs.stream()
  52 + Map<String, List<GatewayAttrConfig>> attrMap = allAttrConfigs.stream()
47 53 .collect(Collectors.groupingBy(GatewayAttrConfig::getServiceId));
48   - gatewayConfigs.forEach(config->{
  54 + gatewayConfigs.forEach(config -> {
49 55 List<GatewayAttrConfig> attrConfigs = attrMap.get(config.getServiceId());
50   - if (!CollectionUtils.isEmpty(attrConfigs)){
  56 + if (!CollectionUtils.isEmpty(attrConfigs)) {
51 57 attrConfigs.sort(Comparator.comparing(GatewayAttrConfig::getSortOrder));
52 58 config.setAttrConfigs(attrConfigs);
53 59 }
54 60 });
55   - return gatewayConfigs.stream()
  61 + return gatewayConfigs.stream()
56 62 .map(this::generateRouteDefinition)
57 63 .collect(Collectors.toList());
58 64 }
59 65  
  66 + @Override
  67 + public void addApiMetrics(List<ApiMetricsInfo> apiMetricsInfos) {
  68 + if (CollectionUtils.isEmpty(apiMetricsInfos)) {
  69 + return;
  70 + }
  71 + List<ApiMetricsInfoEntity> entityList = apiMetricsInfos.stream()
  72 + .map(this::convert2ApiMetricsEntity)
  73 + .collect(Collectors.toList());
  74 + apiMetricsDao.insertBatch(entityList);
  75 + }
  76 +
  77 +
60 78 private RouteDefinition generateRouteDefinition(GatewayConfig gatewayConfig) {
61 79 RouteDefinition definition = new RouteDefinition();
62 80 definition.setId(gatewayConfig.getServiceId());
... ... @@ -70,7 +88,7 @@ public class GatewayRepository implements IGatewayRepository {
70 88 }
71 89 definition.setUri(uri);
72 90 } catch (URISyntaxException e) {
73   - throw new GatewayRouteResourceException("get url failed",e);
  91 + throw new GatewayRouteResourceException("get url failed", e);
74 92 }
75 93 //设置predicate和filter
76 94 this.setPredicatesAndFilters(gatewayConfig, definition);
... ... @@ -86,9 +104,9 @@ public class GatewayRepository implements IGatewayRepository {
86 104 List<FilterDefinition> filterDefinitions = new ArrayList<>();
87 105 for (GatewayAttrConfig gatewayAttrConfig : gatewayAttrConfigs) {
88 106 if (GatewayAttrType.PREDICATE.getValue() == gatewayAttrConfig.getType()) {
89   - predicateDefinitions.add(this.generatePredicateOrFilter(gatewayAttrConfig,PredicateDefinition.class));
  107 + predicateDefinitions.add(this.generatePredicateOrFilter(gatewayAttrConfig, PredicateDefinition.class));
90 108 } else {
91   - filterDefinitions.add(this.generatePredicateOrFilter(gatewayAttrConfig,FilterDefinition.class));
  109 + filterDefinitions.add(this.generatePredicateOrFilter(gatewayAttrConfig, FilterDefinition.class));
92 110 }
93 111 }
94 112 definition.setPredicates(predicateDefinitions);
... ... @@ -96,7 +114,7 @@ public class GatewayRepository implements IGatewayRepository {
96 114 }
97 115  
98 116  
99   - private <T> T generatePredicateOrFilter(GatewayAttrConfig gatewayAttrConfig,Class<T> clazz) {
  117 + private <T> T generatePredicateOrFilter(GatewayAttrConfig gatewayAttrConfig, Class<T> clazz) {
100 118 T target;
101 119 try {
102 120 target = clazz.getDeclaredConstructor().newInstance();
... ... @@ -110,7 +128,8 @@ public class GatewayRepository implements IGatewayRepository {
110 128 if (!Strings.isNullOrEmpty(gatewayAttrConfig.getAttrArgs())) {
111 129 Map<String, String> args = JsonUtils.fromJsonString(
112 130 gatewayAttrConfig.getAttrArgs(),
113   - new TypeReference<LinkedHashMap<String, String>>() {});
  131 + new TypeReference<LinkedHashMap<String, String>>() {
  132 + });
114 133 ReflectUtils.invokeMethod(
115 134 target,
116 135 "setArgs",
... ... @@ -121,11 +140,26 @@ public class GatewayRepository implements IGatewayRepository {
121 140 } catch (IllegalAccessException
122 141 | InvocationTargetException
123 142 | InstantiationException
124   - |NoSuchMethodException e) {
  143 + | NoSuchMethodException e) {
125 144 throw new GatewayRouteResourceException("init gateway resource failed",
126 145 e,
127 146 new Object[]{JsonUtils.toJsonString(gatewayAttrConfig)});
128 147 }
129 148 return target;
130 149 }
  150 +
  151 + private ApiMetricsInfoEntity convert2ApiMetricsEntity(ApiMetricsInfo api) {
  152 + ApiMetricsInfoEntity entity = new ApiMetricsInfoEntity();
  153 + entity.setCode(api.getCode());
  154 + entity.setMessage(api.getMessage());
  155 + entity.setServiceId(api.getServiceId());
  156 + entity.setUrl(api.getUrl());
  157 + entity.setRequestHeader(api.getRequestHeader());
  158 + entity.setRequestBody(api.getRequestBody());
  159 +// Throwable throwable = api.getThrowable();
  160 +// entity.setStackTrace(throwable != null? JsonUtils.toJsonString(throwable.getCause().getStackTrace()) : "");
  161 + entity.setExecuteTime(api.getExecuteTime());
  162 + entity.setCreatedTime(api.getCreatedTime());
  163 + return entity;
  164 + }
131 165 }
... ...
gateway-core/src/main/java/com/diligrp/xtrade/core/repository/IGatewayRepository.java
1 1 package com.diligrp.xtrade.core.repository;
2 2  
  3 +import com.diligrp.xtrade.core.support.ApiMetricsInfo;
3 4 import org.springframework.cloud.gateway.route.RouteDefinition;
4 5  
5 6 import java.util.List;
... ... @@ -17,4 +18,6 @@ public interface IGatewayRepository {
17 18 * @date 2020/4/10
18 19 */
19 20 List<RouteDefinition> getAll();
  21 +
  22 + void addApiMetrics(List<ApiMetricsInfo> apiMetricsInfos);
20 23 }
... ...
gateway-core/src/main/java/com/diligrp/xtrade/core/repository/entity/ApiMetricsInfoEntity.java
1 1 package com.diligrp.xtrade.core.repository.entity;
2 2  
  3 +
3 4 import java.io.Serializable;
  5 +import java.time.LocalDateTime;
4 6  
5 7 /**
6 8 * @Auther: miaoguoxin
7 9 * @Date: 2020/4/18 20:09
8   - * @Description:
  10 + * @Description: t_api_metrics实体
9 11 */
10 12 public class ApiMetricsInfoEntity implements Serializable {
11   - /**服务id*/
  13 + /** 主键id */
  14 + private Long id;
  15 + /**响应code*/
  16 + private Integer code;
  17 + /**响应消息*/
  18 + private String message;
  19 + /**目标服务id*/
12 20 private String serviceId;
  21 + /**目标地址*/
  22 + private String url;
  23 + /**请求头*/
  24 + private String requestHeader;
  25 + /**请求体*/
  26 + private String requestBody;
  27 + /**异常栈跟踪Json信息*/
  28 + private String stackTrace;
  29 + /**方法执行时间,单位:ms*/
  30 + private Long executeTime;
  31 + /**创建时间*/
  32 + private LocalDateTime createdTime;
  33 + /**修改时间*/
  34 + private LocalDateTime modifiedTime;
  35 +
  36 + public Long getId() {
  37 + return id;
  38 + }
  39 +
  40 + public void setId(Long id) {
  41 + this.id = id;
  42 + }
  43 +
  44 + public Integer getCode() {
  45 + return code;
  46 + }
  47 +
  48 + public void setCode(Integer code) {
  49 + this.code = code;
  50 + }
  51 +
  52 + public String getMessage() {
  53 + return message;
  54 + }
  55 +
  56 + public void setMessage(String message) {
  57 + this.message = message;
  58 + }
  59 +
  60 + public String getServiceId() {
  61 + return serviceId;
  62 + }
  63 +
  64 + public void setServiceId(String serviceId) {
  65 + this.serviceId = serviceId;
  66 + }
  67 +
  68 + public String getUrl() {
  69 + return url;
  70 + }
  71 +
  72 + public void setUrl(String url) {
  73 + this.url = url;
  74 + }
  75 +
  76 + public String getRequestHeader() {
  77 + return requestHeader;
  78 + }
  79 +
  80 + public void setRequestHeader(String requestHeader) {
  81 + this.requestHeader = requestHeader;
  82 + }
  83 +
  84 + public String getRequestBody() {
  85 + return requestBody;
  86 + }
  87 +
  88 + public void setRequestBody(String requestBody) {
  89 + this.requestBody = requestBody;
  90 + }
  91 +
  92 + public String getStackTrace() {
  93 + return stackTrace;
  94 + }
  95 +
  96 + public void setStackTrace(String stackTrace) {
  97 + this.stackTrace = stackTrace;
  98 + }
  99 +
  100 + public Long getExecuteTime() {
  101 + return executeTime;
  102 + }
  103 +
  104 + public void setExecuteTime(Long executeTime) {
  105 + this.executeTime = executeTime;
  106 + }
  107 +
  108 + public LocalDateTime getCreatedTime() {
  109 + return createdTime;
  110 + }
  111 +
  112 + public void setCreatedTime(LocalDateTime createdTime) {
  113 + this.createdTime = createdTime;
  114 + }
  115 +
  116 + public LocalDateTime getModifiedTime() {
  117 + return modifiedTime;
  118 + }
  119 +
  120 + public void setModifiedTime(LocalDateTime modifiedTime) {
  121 + this.modifiedTime = modifiedTime;
  122 + }
13 123 }
  124 +
... ...
gateway-core/src/main/java/com/diligrp/xtrade/core/support/ApiMetricsCollector.java
1 1 package com.diligrp.xtrade.core.support;
2 2  
  3 +import com.diligrp.xtrade.core.repository.IGatewayRepository;
3 4 import com.diligrp.xtrade.shared.util.JsonUtils;
4 5 import com.google.common.collect.Queues;
5 6 import org.slf4j.Logger;
6 7 import org.slf4j.LoggerFactory;
  8 +import org.springframework.beans.factory.annotation.Autowired;
7 9 import org.springframework.stereotype.Component;
8 10  
9 11 import javax.annotation.PostConstruct;
... ... @@ -26,6 +28,9 @@ public class ApiMetricsCollector {
26 28  
27 29 private static final BlockingQueue<ApiMetricsInfo> METRICS_QUEUE = new ArrayBlockingQueue<>(1000, true);
28 30  
  31 + @Autowired
  32 + private IGatewayRepository gatewayRepository;
  33 +
29 34 public static void addMetricsInfo(ApiMetricsInfo apiMetricsInfo) {
30 35 METRICS_QUEUE.add(apiMetricsInfo);
31 36 }
... ... @@ -54,9 +59,7 @@ public class ApiMetricsCollector {
54 59 //第五个,指定第四个参数的单位,是秒是分钟还是小时等等
55 60 try {
56 61 Queues.drain(METRICS_QUEUE, metricsInfos, 50, 1, TimeUnit.MINUTES);
57   - for (ApiMetricsInfo metricsInfo : metricsInfos) {
58   - log.info("消费的metrics:{}", JsonUtils.toJsonString(metricsInfo));
59   - }
  62 + gatewayRepository.addApiMetrics(metricsInfos);
60 63 } catch (Exception e) {
61 64 log.error("collect api metrics error:", e);
62 65 }
... ...
gateway-core/src/main/java/com/diligrp/xtrade/core/support/ApiMetricsInfo.java
... ... @@ -35,7 +35,7 @@ public class ApiMetricsInfo {
35 35 /**目标地址*/
36 36 private String url;
37 37 /**请求头*/
38   - private String requestHeaders;
  38 + private String requestHeader;
39 39 /**请求体*/
40 40 private String requestBody;
41 41 /**异常信息*/
... ... @@ -58,7 +58,7 @@ public class ApiMetricsInfo {
58 58 this.message = message;
59 59 this.serviceId = serviceId;
60 60 this.url = url;
61   - this.requestHeaders = requestHeaders;
  61 + this.requestHeader = requestHeaders;
62 62 this.requestBody = requestBody;
63 63 this.throwable = throwable;
64 64 this.executeTime = executeTime;
... ... @@ -78,8 +78,8 @@ public class ApiMetricsInfo {
78 78 return new ApiMetricsInfo(
79 79 message.getCode(),
80 80 message.getMessage(),
81   - uri != null ? uri.toString() : "unknown",
82 81 route != null ? route.getId() : "unknown",
  82 + uri != null ? uri.toString() : "unknown",
83 83 getRequestHeaderJson(exchange.getRequest().getHeaders()),
84 84 requestBody,
85 85 throwable,
... ... @@ -118,8 +118,8 @@ public class ApiMetricsInfo {
118 118 return requestBody;
119 119 }
120 120  
121   - public String getRequestHeaders() {
122   - return requestHeaders;
  121 + public String getRequestHeader() {
  122 + return requestHeader;
123 123 }
124 124  
125 125 public Throwable getThrowable() {
... ...
gateway-core/src/main/java/com/diligrp/xtrade/core/support/dispatch/RequestDispatcher.java
... ... @@ -68,7 +68,7 @@ public class RequestDispatcher {
68 68 }
69 69 //分发逻辑
70 70 Object resultData = this.beginDispatch(matchUri, paramsJson, exchange);
71   - return Message.success(resultData);
  71 + return Message.builder().success(resultData);
72 72 } catch (Throwable e) {
73 73 throw new GatewayDispatchException("dispatch method error", e);
74 74 }
... ...
gateway-core/src/main/resources/mapper/ApiMetricsMapper.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3 +<mapper namespace="com.diligrp.xtrade.core.repository.dao.ApiMetricsDao">
  4 +
  5 + <resultMap type="com.diligrp.xtrade.core.repository.entity.ApiMetricsInfoEntity" id="ApiMetricsMap">
  6 + <result property="id" column="id"/>
  7 + <result property="code" column="code"/>
  8 + <result property="message" column="message"/>
  9 + <result property="serviceId" column="service_id"/>
  10 + <result property="url" column="url"/>
  11 + <result property="requestHeader" column="request_header"/>
  12 + <result property="requestBody" column="request_body"/>
  13 + <result property="stackTrace" column="stack_trace"/>
  14 + <result property="executeTime" column="execute_time"/>
  15 + <result property="createdTime" column="created_time"/>
  16 + <result property="modifiedTime" column="modified_time"/>
  17 + </resultMap>
  18 + <insert id="insertBatch" parameterType="java.util.List">
  19 + INSERT INTO t_api_metrics(code,
  20 + message,
  21 + service_id,
  22 + url,
  23 + request_header,
  24 + request_body,
  25 + stack_trace,
  26 + execute_time,
  27 + created_time,
  28 + modified_time)
  29 + VALUES
  30 + <foreach collection="list" item="item" index="index" separator=",">
  31 + (
  32 + #{item.code},
  33 + #{item.message},
  34 + #{item.serviceId},
  35 + #{item.url},
  36 + #{item.requestHeader},
  37 + #{item.requestBody},
  38 + #{item.stackTrace},
  39 + #{item.executeTime},
  40 + #{item.createdTime},
  41 + now()
  42 + )
  43 + </foreach>
  44 + </insert>
  45 +
  46 + <!--查询单个-->
  47 + <select id="queryById" resultMap="ApiMetricsMap">
  48 + select id,
  49 + code,
  50 + message,
  51 + service_id,
  52 + url,
  53 + request_header,
  54 + request_body,
  55 + stack_trace,
  56 + execute_time,
  57 + created_time,
  58 + modified_time
  59 + from xtrade_gateway.t_api_metrics
  60 + where id = #{id}
  61 + </select>
  62 +
  63 +
  64 +</mapper>
... ...
sql/gateway-1.0.0.sql
... ... @@ -11,7 +11,7 @@ CREATE TABLE `xtrade_gateway`.`t_route`
11 11 ) COMMENT = '路由表';
12 12  
13 13 ALTER TABLE `xtrade_gateway`.`t_route`
14   - ADD UNIQUE INDEX `uni_service_id`(`service_id`) USING BTREE COMMENT 'service_id唯一索引';
  14 + ADD UNIQUE INDEX `uni_service_id` (`service_id`) USING BTREE COMMENT 'service_id唯一索引';
15 15  
16 16 CREATE TABLE `xtrade_gateway`.`t_attr_config`
17 17 (
... ... @@ -32,4 +32,26 @@ ALTER TABLE `xtrade_gateway`.`t_attr_config`
32 32 MODIFY COLUMN `order` smallint(2) NOT NULL DEFAULT 0 COMMENT '排序字段' AFTER `desc`;
33 33  
34 34 ALTER TABLE `xtrade_gateway`.`t_attr_config`
35   - ADD UNIQUE INDEX `uni_service_id&attr_name`(`service_id`, `attr_name`) USING BTREE COMMENT 'service_id和attr_name唯一约束';
  35 + ADD UNIQUE INDEX `uni_service_id&attr_name` (`service_id`, `attr_name`) USING BTREE COMMENT 'service_id和attr_name唯一约束';
  36 +
  37 +CREATE TABLE `t_api_metrics`
  38 +(
  39 + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  40 + `code` int(10) NOT NULL COMMENT 'response code',
  41 + `message` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'response提示消息',
  42 + `service_id` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '服务id',
  43 + `url` varchar(150) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '目标url',
  44 + `request_header` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '请求头json',
  45 + `request_body` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '请求体',
  46 + `stack_trace` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '异常栈跟踪信息json',
  47 + `execute_time` bigint(10) NOT NULL COMMENT 'api执行时间,单位:ms',
  48 + `created_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
  49 + `modified_time` datetime(0) NULL DEFAULT NULL COMMENT '修改时间',
  50 + PRIMARY KEY (`id`) USING BTREE
  51 +) ENGINE = InnoDB
  52 + AUTO_INCREMENT = 1
  53 + CHARACTER SET = utf8mb4
  54 + COLLATE = utf8mb4_general_ci COMMENT = 'api请求指标记录表'
  55 + ROW_FORMAT = Compact;
  56 +
  57 +SET FOREIGN_KEY_CHECKS = 1;
... ...