Commit 584096c3bcc58a2c98d6e98beb34640097f968f9
1 parent
89cac1a5
api metric测试入库
Showing
15 changed files
with
315 additions
and
47 deletions
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<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<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<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; | ... | ... |