Commit c8837dd3771d55156e36168c47fa048ad05c023e

Authored by miaoguoxin
1 parent 119865e8

api指标属性

gateway-business/src/main/resources/bootstrap.yml
... ... @@ -25,3 +25,7 @@ mybatis:
25 25 xtrade:
26 26 gateway-loader: cloud
27 27 aggregation-scan-packages: com.diligrp.xtrade.business.application
  28 + api-metrics:
  29 + time-unit: seconds
  30 + collect-num: 5
  31 + timeout: 10
... ...
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},
... ...
sql/gateway-1.0.0.sql
... ... @@ -55,3 +55,6 @@ CREATE TABLE `t_api_metrics`
55 55 ROW_FORMAT = Compact;
56 56  
57 57 SET FOREIGN_KEY_CHECKS = 1;
  58 +
  59 +ALTER TABLE `xtrade_gateway`.`t_api_metrics`
  60 + ADD COLUMN client_ip` varchar(40) NULL COMMENT '客户端ip' AFTER `url`;
... ...