Commit c8837dd3771d55156e36168c47fa048ad05c023e
1 parent
119865e8
api指标属性
Showing
12 changed files
with
138 additions
and
8 deletions
gateway-business/src/main/resources/bootstrap.yml
gateway-core/src/main/java/com/diligrp/xtrade/core/common/utils/HttpUtils.java
0 → 100644
1 | +package com.diligrp.xtrade.core.common.utils; | |
2 | + | |
3 | +import org.springframework.http.HttpHeaders; | |
4 | +import org.springframework.http.server.reactive.ServerHttpRequest; | |
5 | + | |
6 | +import javax.servlet.http.HttpServletRequest; | |
7 | + | |
8 | +/** | |
9 | + * @Auther: miaoguoxin | |
10 | + * @Date: 2020/4/24 10:23 | |
11 | + */ | |
12 | +public class HttpUtils { | |
13 | + /** | |
14 | + * @Description: 获取客户端IP地址 | |
15 | + */ | |
16 | + public static String getIpAddr(ServerHttpRequest request) { | |
17 | + if (request==null){ | |
18 | + return "127.0.0.1"; | |
19 | + } | |
20 | + HttpHeaders headers = request.getHeaders(); | |
21 | + String ip = headers.getFirst("x-forwarded-for"); | |
22 | + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { | |
23 | + ip = headers.getFirst("Proxy-Client-IP"); | |
24 | + } | |
25 | + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { | |
26 | + ip = headers.getFirst("WL-Proxy-Client-IP"); | |
27 | + } | |
28 | + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { | |
29 | + ip = request.getRemoteAddress() == null ? "unknown" : request.getRemoteAddress().getHostString(); | |
30 | + } | |
31 | + return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip; | |
32 | + } | |
33 | +} | ... | ... |
gateway-core/src/main/java/com/diligrp/xtrade/core/common/utils/ResponseUtils.java
... | ... | @@ -18,12 +18,12 @@ public class ResponseUtils { |
18 | 18 | |
19 | 19 | |
20 | 20 | public static Mono<Void> writeForbidden(ServerHttpResponse response){ |
21 | - Message message = Message.failure( | |
21 | + Message<?> message = Message.failure( | |
22 | 22 | HttpStatus.FORBIDDEN.value(),HttpStatus.FORBIDDEN.toString()); |
23 | 23 | return writeResponse(response,message); |
24 | 24 | } |
25 | 25 | |
26 | - public static Mono<Void> writeResponse(ServerHttpResponse response,Message<Object> message){ | |
26 | + public static Mono<Void> writeResponse(ServerHttpResponse response,Message<?> message){ | |
27 | 27 | String respJson = JsonUtils.toJsonString(message); |
28 | 28 | response.getHeaders().setContentLength( |
29 | 29 | respJson.getBytes(StandardCharsets.UTF_8).length); | ... | ... |
gateway-core/src/main/java/com/diligrp/xtrade/core/config/property/ApiMetricsProperties.java
0 → 100644
1 | +package com.diligrp.xtrade.core.config.property; | |
2 | + | |
3 | +import org.springframework.boot.context.properties.ConfigurationProperties; | |
4 | +import org.springframework.stereotype.Component; | |
5 | +import org.springframework.validation.annotation.Validated; | |
6 | + | |
7 | +import javax.validation.constraints.Min; | |
8 | +import javax.validation.constraints.NotNull; | |
9 | +import java.util.concurrent.TimeUnit; | |
10 | + | |
11 | +/** | |
12 | + * @Auther: miaoguoxin | |
13 | + * @Date: 2020/4/24 10:54 | |
14 | + * @Description: api指标收集配置属性 | |
15 | + */ | |
16 | +@Component | |
17 | +@ConfigurationProperties(prefix = "xtrade.api-metrics") | |
18 | +@Validated | |
19 | +public class ApiMetricsProperties { | |
20 | + /**每次收集多少个*/ | |
21 | + @NotNull | |
22 | + @Min(value = 1) | |
23 | + private Integer collectNum = 50; | |
24 | + /**收集超时时间,表示若每次不满collectNum,但超过了该时间,也会进行收集*/ | |
25 | + @NotNull | |
26 | + @Min(value = 1) | |
27 | + private Long timeout = 10L; | |
28 | + @NotNull | |
29 | + private TimeUnit timeUnit = TimeUnit.SECONDS; | |
30 | + | |
31 | + public Integer getCollectNum() { | |
32 | + return collectNum; | |
33 | + } | |
34 | + | |
35 | + public void setCollectNum(Integer collectNum) { | |
36 | + this.collectNum = collectNum; | |
37 | + } | |
38 | + | |
39 | + public Long getTimeout() { | |
40 | + return timeout; | |
41 | + } | |
42 | + | |
43 | + public void setTimeout(Long timeout) { | |
44 | + this.timeout = timeout; | |
45 | + } | |
46 | + | |
47 | + public TimeUnit getTimeUnit() { | |
48 | + return timeUnit; | |
49 | + } | |
50 | + | |
51 | + public void setTimeUnit(TimeUnit timeUnit) { | |
52 | + this.timeUnit = timeUnit; | |
53 | + } | |
54 | +} | ... | ... |
gateway-core/src/main/java/com/diligrp/xtrade/core/filters/factory/DispatchGatewayFilterFactory.java
... | ... | @@ -3,8 +3,6 @@ package com.diligrp.xtrade.core.filters.factory; |
3 | 3 | 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 | -import com.diligrp.xtrade.shared.domain.Message; | |
7 | -import com.diligrp.xtrade.shared.type.ErrorCode; | |
8 | 6 | import org.springframework.beans.factory.annotation.Autowired; |
9 | 7 | import org.springframework.cloud.gateway.filter.GatewayFilter; |
10 | 8 | import org.springframework.cloud.gateway.filter.GatewayFilterChain; | ... | ... |
gateway-core/src/main/java/com/diligrp/xtrade/core/filters/web/FacadeWebFilter.java
... | ... | @@ -51,7 +51,7 @@ public class FacadeWebFilter implements WebFilter { |
51 | 51 | ReactiveExchangeContextHolder.put(exchange); |
52 | 52 | return chain.filter(exchange) |
53 | 53 | .onErrorResume(throwable -> { |
54 | - Message<Object> message = handleException(throwable); | |
54 | + Message<?> message = handleException(throwable); | |
55 | 55 | exchange.getAttributes().putIfAbsent(GatewayConst.GATEWAY_EXCEPTION_ATTR, throwable); |
56 | 56 | exchange.getAttributes().putIfAbsent(GatewayConst.CACHED_RESPONSE_BODY_STR_ATTR, JsonUtils.toJsonString(message)); |
57 | 57 | return ResponseUtils.writeResponse(exchange.getResponse(), message); |
... | ... | @@ -63,7 +63,7 @@ public class FacadeWebFilter implements WebFilter { |
63 | 63 | } |
64 | 64 | |
65 | 65 | |
66 | - private static Message handleException(Throwable ex) { | |
66 | + private static Message<?> handleException(Throwable ex) { | |
67 | 67 | if (ex instanceof GatewayDispatchException) { |
68 | 68 | GatewayDispatchException dispatchEx = (GatewayDispatchException) ex; |
69 | 69 | if (dispatchEx.getCause() != null) { | ... | ... |
gateway-core/src/main/java/com/diligrp/xtrade/core/repository/GatewayRepository.java
... | ... | @@ -154,6 +154,7 @@ public class GatewayRepository implements IGatewayRepository { |
154 | 154 | entity.setMessage(api.getMessage()); |
155 | 155 | entity.setServiceId(api.getServiceId()); |
156 | 156 | entity.setUrl(api.getUrl()); |
157 | + entity.setClientIp(api.getClientIp()); | |
157 | 158 | entity.setRequestHeader(api.getRequestHeader()); |
158 | 159 | entity.setRequestBody(api.getRequestBody()); |
159 | 160 | // Throwable throwable = api.getThrowable(); | ... | ... |
gateway-core/src/main/java/com/diligrp/xtrade/core/repository/entity/ApiMetricsInfoEntity.java
... | ... | @@ -20,6 +20,8 @@ public class ApiMetricsInfoEntity implements Serializable { |
20 | 20 | private String serviceId; |
21 | 21 | /**目标地址*/ |
22 | 22 | private String url; |
23 | + /**客户端Ip*/ | |
24 | + private String clientIp; | |
23 | 25 | /**请求头*/ |
24 | 26 | private String requestHeader; |
25 | 27 | /**请求体*/ |
... | ... | @@ -33,6 +35,14 @@ public class ApiMetricsInfoEntity implements Serializable { |
33 | 35 | /**修改时间*/ |
34 | 36 | private LocalDateTime modifiedTime; |
35 | 37 | |
38 | + public String getClientIp() { | |
39 | + return clientIp; | |
40 | + } | |
41 | + | |
42 | + public void setClientIp(String clientIp) { | |
43 | + this.clientIp = clientIp; | |
44 | + } | |
45 | + | |
36 | 46 | public Long getId() { |
37 | 47 | return id; |
38 | 48 | } | ... | ... |
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.config.property.ApiMetricsProperties; | |
3 | 4 | import com.diligrp.xtrade.core.repository.IGatewayRepository; |
4 | 5 | import com.diligrp.xtrade.shared.util.JsonUtils; |
5 | 6 | import com.google.common.collect.Queues; |
... | ... | @@ -16,6 +17,7 @@ import java.util.TimerTask; |
16 | 17 | import java.util.concurrent.ArrayBlockingQueue; |
17 | 18 | import java.util.concurrent.BlockingQueue; |
18 | 19 | import java.util.concurrent.TimeUnit; |
20 | +import java.util.concurrent.atomic.AtomicBoolean; | |
19 | 21 | |
20 | 22 | /** |
21 | 23 | * @Auther: miaoguoxin |
... | ... | @@ -28,8 +30,12 @@ public class ApiMetricsCollector { |
28 | 30 | |
29 | 31 | private static final BlockingQueue<ApiMetricsInfo> METRICS_QUEUE = new ArrayBlockingQueue<>(1000, true); |
30 | 32 | |
33 | + private static final AtomicBoolean HAS_INIT = new AtomicBoolean(false); | |
34 | + | |
31 | 35 | @Autowired |
32 | 36 | private IGatewayRepository gatewayRepository; |
37 | + @Autowired | |
38 | + private ApiMetricsProperties apiMetricsProperties; | |
33 | 39 | |
34 | 40 | public static void addMetricsInfo(ApiMetricsInfo apiMetricsInfo) { |
35 | 41 | METRICS_QUEUE.add(apiMetricsInfo); |
... | ... | @@ -37,6 +43,9 @@ public class ApiMetricsCollector { |
37 | 43 | |
38 | 44 | @PostConstruct |
39 | 45 | public void start() { |
46 | + if (!HAS_INIT.compareAndSet(false, true)) { | |
47 | + return; | |
48 | + } | |
40 | 49 | Timer timer = new Timer(); |
41 | 50 | TimerTask task = new TimerTask() { |
42 | 51 | @Override |
... | ... | @@ -58,7 +67,10 @@ public class ApiMetricsCollector { |
58 | 67 | // 那按道理就不会消费,但是这样显然不合理,所以需要指定当超多多长时间,即使当前队列中数据低于我们设定的阈值也会消费 |
59 | 68 | //第五个,指定第四个参数的单位,是秒是分钟还是小时等等 |
60 | 69 | try { |
61 | - Queues.drain(METRICS_QUEUE, metricsInfos, 50, 1, TimeUnit.MINUTES); | |
70 | + Queues.drain(METRICS_QUEUE, metricsInfos, | |
71 | + apiMetricsProperties.getCollectNum(), | |
72 | + apiMetricsProperties.getTimeout(), | |
73 | + apiMetricsProperties.getTimeUnit()); | |
62 | 74 | gatewayRepository.addApiMetrics(metricsInfos); |
63 | 75 | } catch (Exception e) { |
64 | 76 | log.error("collect api metrics error:", e); | ... | ... |
gateway-core/src/main/java/com/diligrp/xtrade/core/support/ApiMetricsInfo.java
1 | 1 | package com.diligrp.xtrade.core.support; |
2 | 2 | |
3 | 3 | import com.diligrp.xtrade.core.common.constant.GatewayConst; |
4 | +import com.diligrp.xtrade.core.common.utils.HttpUtils; | |
4 | 5 | import com.diligrp.xtrade.shared.domain.Message; |
5 | 6 | import com.diligrp.xtrade.shared.util.JsonUtils; |
6 | 7 | import com.fasterxml.jackson.annotation.JsonIgnore; |
... | ... | @@ -11,6 +12,7 @@ import org.slf4j.LoggerFactory; |
11 | 12 | import org.springframework.cloud.gateway.route.Route; |
12 | 13 | import org.springframework.cloud.gateway.support.ServerWebExchangeUtils; |
13 | 14 | import org.springframework.http.HttpHeaders; |
15 | +import org.springframework.http.server.reactive.ServerHttpRequest; | |
14 | 16 | import org.springframework.web.server.ServerWebExchange; |
15 | 17 | |
16 | 18 | import java.net.URI; |
... | ... | @@ -34,6 +36,8 @@ public class ApiMetricsInfo { |
34 | 36 | private String serviceId; |
35 | 37 | /**目标地址*/ |
36 | 38 | private String url; |
39 | + /**请求客户端的ip*/ | |
40 | + private String clientIp; | |
37 | 41 | /**请求头*/ |
38 | 42 | private String requestHeader; |
39 | 43 | /**请求体*/ |
... | ... | @@ -50,6 +54,7 @@ public class ApiMetricsInfo { |
50 | 54 | String message, |
51 | 55 | String serviceId, |
52 | 56 | String url, |
57 | + String clientIp, | |
53 | 58 | String requestHeaders, |
54 | 59 | String requestBody, |
55 | 60 | Throwable throwable, |
... | ... | @@ -58,6 +63,7 @@ public class ApiMetricsInfo { |
58 | 63 | this.message = message; |
59 | 64 | this.serviceId = serviceId; |
60 | 65 | this.url = url; |
66 | + this.clientIp = clientIp; | |
61 | 67 | this.requestHeader = requestHeaders; |
62 | 68 | this.requestBody = requestBody; |
63 | 69 | this.throwable = throwable; |
... | ... | @@ -71,6 +77,7 @@ public class ApiMetricsInfo { |
71 | 77 | if (Strings.isNotBlank(responseJson)) { |
72 | 78 | Message<Object> message = JsonUtils.fromJsonString(responseJson, new TypeReference<>() { |
73 | 79 | }); |
80 | + ServerHttpRequest request = exchange.getRequest(); | |
74 | 81 | URI uri = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR); |
75 | 82 | Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR); |
76 | 83 | String requestBody = exchange.getAttribute(GatewayConst.CACHED_REQUEST_BODY_STR_ATTR); |
... | ... | @@ -80,7 +87,8 @@ public class ApiMetricsInfo { |
80 | 87 | message.getMessage(), |
81 | 88 | route != null ? route.getId() : "unknown", |
82 | 89 | uri != null ? uri.toString() : "unknown", |
83 | - getRequestHeaderJson(exchange.getRequest().getHeaders()), | |
90 | + HttpUtils.getIpAddr(request), | |
91 | + getRequestHeaderJson(request.getHeaders()), | |
84 | 92 | requestBody, |
85 | 93 | throwable, |
86 | 94 | time); |
... | ... | @@ -114,6 +122,10 @@ public class ApiMetricsInfo { |
114 | 122 | return url; |
115 | 123 | } |
116 | 124 | |
125 | + public String getClientIp() { | |
126 | + return clientIp; | |
127 | + } | |
128 | + | |
117 | 129 | public String getRequestBody() { |
118 | 130 | return requestBody; |
119 | 131 | } | ... | ... |
gateway-core/src/main/resources/mapper/ApiMetricsMapper.xml
... | ... | @@ -8,6 +8,7 @@ |
8 | 8 | <result property="message" column="message"/> |
9 | 9 | <result property="serviceId" column="service_id"/> |
10 | 10 | <result property="url" column="url"/> |
11 | + <result property="clientIp" column="client_ip"/> | |
11 | 12 | <result property="requestHeader" column="request_header"/> |
12 | 13 | <result property="requestBody" column="request_body"/> |
13 | 14 | <result property="stackTrace" column="stack_trace"/> |
... | ... | @@ -20,6 +21,7 @@ |
20 | 21 | message, |
21 | 22 | service_id, |
22 | 23 | url, |
24 | + client_ip, | |
23 | 25 | request_header, |
24 | 26 | request_body, |
25 | 27 | stack_trace, |
... | ... | @@ -33,6 +35,7 @@ |
33 | 35 | #{item.message}, |
34 | 36 | #{item.serviceId}, |
35 | 37 | #{item.url}, |
38 | + #{item.clientIp}, | |
36 | 39 | #{item.requestHeader}, |
37 | 40 | #{item.requestBody}, |
38 | 41 | #{item.stackTrace}, | ... | ... |