Search in sources :

Example 1 with VxApiTrackInfos

use of com.szmirren.vxApi.core.entity.VxApiTrackInfos in project VX-API-Gateway by EliMirren.

the class SysVerticle method plusTrackInfos.

/**
 * 添加API追踪信息
 *
 * @param msg
 */
public void plusTrackInfos(Message<JsonObject> msg) {
    if (msg.body() != null) {
        VxApiTrackInfos infos = VxApiTrackInfos.fromJson(msg.body());
        // map的key
        String key = infos.getAppName() + "-" + infos.getApiName();
        // 记录API相关信息
        if (!infos.isSuccessful()) {
            // 记录异常
            errorCount += 1;
            if (requstFailedCount.get(key) == null) {
                requstFailedCount.put(key, 0L);
            }
            requstFailedCount.put(key, requstFailedCount.get(key) + 1);
            LOG.error(MessageFormat.format("应用:{0} , API:{1} ,在执行的过程中发生了异常:{2} ,堆栈信息{3}", infos.getAppName(), infos.getApiName(), infos.getErrMsg(), infos.getErrStackTrace()));
        } else {
            JsonObject json = new JsonObject();
            Duration proc = Duration.between(infos.getStartTime(), infos.getEndTime());
            json.put("time", infos.getStartTime());
            json.put("overallTime", proc.toMillis());
            Duration reqs = Duration.between(infos.getRequestTime(), infos.getResponseTime());
            json.put("requestTime", reqs.toMillis());
            json.put("requestBodyLen", infos.getRequestBufferLen());
            json.put("responseBodyLen", infos.getResponseBufferLen());
            if (trackSucceededMap.get(key) == null) {
                trackSucceededMap.put(key, new LinkedList<>());
            } else {
                if (trackSucceededMap.get(key).size() > 100) {
                    trackSucceededMap.get(key).pollFirst();
                }
            }
            trackSucceededMap.get(key).add(json);
        }
        // 添加请求数量统计
        if (requstCount.get(key) == null) {
            requstCount.put(key, 0L);
        }
        requstCount.put(key, requstCount.get(key) + 1);
    }
}
Also used : VxApiTrackInfos(com.szmirren.vxApi.core.entity.VxApiTrackInfos) JsonObject(io.vertx.core.json.JsonObject) Duration(java.time.Duration)

Example 2 with VxApiTrackInfos

use of com.szmirren.vxApi.core.entity.VxApiTrackInfos in project VX-API-Gateway by EliMirren.

the class VxApiApplication method initExceptionHanlder.

/**
 * 初始化异常Handler
 *
 * @param api
 * @param route
 */
public void initExceptionHanlder(VxApis api, Route route) {
    route.path(api.getPath());
    if (api.getMethod() != HttpMethodEnum.ALL) {
        route.method(HttpMethod.valueOf(api.getMethod().getVal()));
    }
    if (api.getConsumes() != null) {
        api.getConsumes().forEach(va -> route.consumes(va));
    }
    route.failureHandler(rct -> {
        rct.response().putHeader(SERVER, VxApiGatewayAttribute.FULL_NAME).putHeader(CONTENT_TYPE, api.getContentType()).setStatusCode(api.getResult().getFailureStatus()).end(api.getResult().getFailureExample());
        VxApiTrackInfos infos = new VxApiTrackInfos(appName, api.getApiName());
        infos.setErrMsg(rct.failure().getMessage());
        infos.setErrStackTrace(rct.failure().getStackTrace());
        vertx.eventBus().send(thisVertxName + VxApiEventBusAddressConstant.SYSTEM_PLUS_ERROR, infos.toJson());
    });
}
Also used : VxApiTrackInfos(com.szmirren.vxApi.core.entity.VxApiTrackInfos)

Example 3 with VxApiTrackInfos

use of com.szmirren.vxApi.core.entity.VxApiTrackInfos in project VX-API-Gateway by EliMirren.

the class SessionTokenGrantAuthHandler method handle.

@Override
public void handle(RoutingContext rct) {
    // 看有没有可用的服务连接
    if (policy.isHaveService()) {
        // 有可用连接
        // 后台服务连接信息
        VxApiServerURLInfo urlInfo;
        if (serOptions.getBalanceType() == LoadBalanceEnum.IP_HASH) {
            String ip = rct.request().remoteAddress().host();
            urlInfo = policy.getUrl(ip);
        } else {
            urlInfo = policy.getUrl();
        }
        // 执行监控
        VxApiTrackInfos trackInfo = new VxApiTrackInfos(api.getAppName(), api.getApiName());
        trackInfo.setRequestBufferLen(rct.getBody() == null ? 0 : rct.getBody().length());
        String requestPath = urlInfo.getUrl();
        MultiMap headers = new CaseInsensitiveHeaders();
        MultiMap queryParams = new CaseInsensitiveHeaders();
        if (serOptions.getParams() != null) {
            for (VxApiParamOptions p : serOptions.getParams()) {
                String param = "";
                if (p.getType() == 0 || p.getType() == 2) {
                    if (p.getApiParamPosition() == ParamPositionEnum.HEADER) {
                        param = rct.request().getHeader(p.getApiParamName());
                    } else {
                        param = rct.request().getParam(p.getApiParamName());
                    }
                } else if (p.getType() == 1) {
                    if (p.getSysParamType() == ParamSystemVarTypeEnum.CLIENT_HOST) {
                        param = rct.request().remoteAddress().host();
                    } else if (p.getSysParamType() == ParamSystemVarTypeEnum.CLIENT_PORT) {
                        param = Integer.toString(rct.request().remoteAddress().port());
                    } else if (p.getSysParamType() == ParamSystemVarTypeEnum.CLIENT_PATH) {
                        param = rct.request().path() == null ? "" : rct.request().path();
                    } else if (p.getSysParamType() == ParamSystemVarTypeEnum.CLIENT_SESSION_ID) {
                        param = rct.session().id();
                    } else if (p.getSysParamType() == ParamSystemVarTypeEnum.CLIENT_ABSOLUTE_URI) {
                        param = rct.request().absoluteURI();
                    } else if (p.getSysParamType() == ParamSystemVarTypeEnum.CLIENT_REQUEST_SCHEMA) {
                        param = rct.request().scheme();
                    } else if (p.getSysParamType() == ParamSystemVarTypeEnum.SERVER_API_NAME) {
                        param = api.getApiName();
                    } else if (p.getSysParamType() == ParamSystemVarTypeEnum.SERVER_UNIX_TIME) {
                        param = Long.toString(System.currentTimeMillis());
                    } else if (p.getSysParamType() == ParamSystemVarTypeEnum.SERVER_USER_AGENT) {
                        param = VxApiGatewayAttribute.VX_API_USER_AGENT;
                    }
                } else if (p.getType() == 9) {
                    param = p.getParamValue().toString();
                } else {
                    continue;
                }
                if (p.getSerParamPosition() == ParamPositionEnum.HEADER) {
                    headers.add(p.getSerParamName(), param);
                } else if (p.getSerParamPosition() == ParamPositionEnum.PATH) {
                    requestPath.replace(":" + p.getSerParamName(), param);
                } else {
                    queryParams.add(p.getSerParamName(), param);
                }
            }
        }
        HttpRequest<Buffer> request = webClient.requestAbs(serOptions.getMethod(), requestPath).timeout(serOptions.getTimeOut());
        headers.forEach(va -> request.putHeader(va.getKey(), va.getValue()));
        queryParams.forEach(va -> request.addQueryParam(va.getKey(), va.getValue()));
        trackInfo.setRequestTime(Instant.now());
        request.send(res -> {
            trackInfo.setResponseTime(Instant.now());
            if (res.succeeded()) {
                HttpResponse<Buffer> result = res.result();
                Set<String> tranHeaders = api.getResult().getTranHeaders();
                if (tranHeaders != null && tranHeaders.size() > 0) {
                    tranHeaders.forEach(h -> {
                        rct.response().putHeader(h, result.getHeader(h) == null ? "" : result.getHeader(h));
                    });
                }
                HttpServerResponse response = rct.response();
                // 得到后台服务传过来的token
                String token = res.result().getHeader(getTokenName);
                if (token != null && !"".equals(token)) {
                    rct.session().put(saveTokenName, token);
                }
                response.putHeader(HttpHeaderConstant.SERVER, VxApiGatewayAttribute.FULL_NAME).putHeader(HttpHeaderConstant.CONTENT_TYPE, api.getContentType()).setChunked(true).write(result.body());
                if (isNext) {
                    // 告诉后置处理器当前操作成功执行
                    rct.put(VxApiAfterHandler.PREV_IS_SUCCESS_KEY, Future.<Boolean>succeededFuture(true));
                    rct.next();
                } else {
                    response.end();
                }
                trackInfo.setResponseBufferLen(result.body() == null ? 0 : result.body().length());
                trackInfo.setEndTime(Instant.now());
            } else {
                if (isNext) {
                    // 告诉后置处理器当前操作成功执行
                    rct.put(VxApiAfterHandler.PREV_IS_SUCCESS_KEY, Future.<Boolean>failedFuture(res.cause()));
                    rct.next();
                } else {
                    HttpServerResponse response = rct.response().putHeader(HttpHeaderConstant.SERVER, VxApiGatewayAttribute.FULL_NAME).putHeader(HttpHeaderConstant.CONTENT_TYPE, api.getContentType());
                    // 如果是连接异常返回无法连接的错误信息,其他异常返回相应的异常
                    if (res.cause() instanceof ConnectException || res.cause() instanceof TimeoutException) {
                        response.setStatusCode(api.getResult().getCantConnServerStatus()).end(api.getResult().getCantConnServerExample());
                    } else {
                        response.setStatusCode(api.getResult().getFailureStatus()).end(api.getResult().getFailureExample());
                    }
                }
                // 提交连接请求失败
                policy.reportBadService(urlInfo.getIndex());
                trackInfo.setEndTime(Instant.now());
                // 记录与后台交互发生错误
                trackInfo.setSuccessful(false);
                trackInfo.setErrMsg(res.cause().getMessage());
                trackInfo.setErrStackTrace(res.cause().getStackTrace());
            }
            rct.vertx().eventBus().send(thisVertxName + VxApiEventBusAddressConstant.SYSTEM_PLUS_TRACK_INFO, trackInfo.toJson());
        });
        // 判断是否有坏的连接
        if (policy.isHaveBadService()) {
            if (!policy.isCheckWaiting()) {
                policy.setCheckWaiting(true);
                rct.vertx().setTimer(serOptions.getRetryTime(), testConn -> {
                    List<VxApiServerURLInfo> service = policy.getBadService();
                    for (VxApiServerURLInfo urlinfo : service) {
                        webClient.requestAbs(serOptions.getMethod(), urlinfo.getUrl()).timeout(serOptions.getTimeOut()).send(res -> {
                            if (res.succeeded()) {
                                policy.reportGreatService(urlinfo.getIndex());
                            }
                        });
                    }
                    policy.setCheckWaiting(false);
                });
            }
        }
    } else {
        // 无可用连接时,结束当前处理器并尝试重新尝试连接是否可用
        if (isNext) {
            // 告诉后置处理器当前操作执行结果
            rct.put(VxApiAfterHandler.PREV_IS_SUCCESS_KEY, Future.<Boolean>failedFuture(new ConnectException("无法连接上后台交互的服务器")));
            rct.next();
        } else {
            rct.response().putHeader(HttpHeaderConstant.SERVER, VxApiGatewayAttribute.FULL_NAME).putHeader(HttpHeaderConstant.CONTENT_TYPE, api.getContentType()).setStatusCode(api.getResult().getCantConnServerStatus()).end(api.getResult().getCantConnServerExample());
        }
        if (!policy.isCheckWaiting()) {
            policy.setCheckWaiting(true);
            rct.vertx().setTimer(serOptions.getRetryTime(), testConn -> {
                List<VxApiServerURLInfo> service = policy.getBadService();
                for (VxApiServerURLInfo urlinfo : service) {
                    webClient.requestAbs(serOptions.getMethod(), urlinfo.getUrl()).timeout(serOptions.getTimeOut()).send(res -> {
                        if (res.succeeded()) {
                            policy.reportGreatService(urlinfo.getIndex());
                        }
                    });
                }
                policy.setCheckWaiting(false);
            });
        }
    }
}
Also used : VxApiTrackInfos(com.szmirren.vxApi.core.entity.VxApiTrackInfos) Buffer(io.vertx.core.buffer.Buffer) VxApiParamOptions(com.szmirren.vxApi.core.options.VxApiParamOptions) MultiMap(io.vertx.core.MultiMap) CaseInsensitiveHeaders(io.vertx.core.http.CaseInsensitiveHeaders) HttpServerResponse(io.vertx.core.http.HttpServerResponse) VxApiServerURLInfo(com.szmirren.vxApi.core.entity.VxApiServerURLInfo) ConnectException(java.net.ConnectException) TimeoutException(java.util.concurrent.TimeoutException)

Example 4 with VxApiTrackInfos

use of com.szmirren.vxApi.core.entity.VxApiTrackInfos in project VX-API-Gateway by EliMirren.

the class VxApiRouteHandlerHttpServiceImpl method handle.

@Override
public void handle(RoutingContext rct) {
    // 看有没有可用的服务连接
    if (policy.isHaveService()) {
        // 有可用连接
        // 后台服务连接信息
        VxApiServerURLInfo urlInfo;
        if (serOptions.getBalanceType() == LoadBalanceEnum.IP_HASH) {
            String ip = rct.request().remoteAddress().host();
            urlInfo = policy.getUrl(ip);
        } else {
            urlInfo = policy.getUrl();
        }
        // 执行监控
        VxApiTrackInfos trackInfo = new VxApiTrackInfos(appName, api.getApiName());
        // 统计请求内容长度
        String resLen = rct.request().getHeader("Content-Length");
        trackInfo.setRequestBufferLen(resLen == null ? 0 : StrUtil.getintTry(resLen));
        // 获得请求连接与进行请求
        String requestPath = urlInfo.getUrl();
        MultiMap headers = new CaseInsensitiveHeaders();
        if (serOptions.getParams() != null) {
            // 路径参数
            QueryStringEncoder queryParam = new QueryStringEncoder("");
            for (VxApiParamOptions p : serOptions.getParams()) {
                String param = null;
                if (p.getType() == 0 || p.getType() == 2) {
                    if (p.getApiParamPosition() == ParamPositionEnum.HEADER) {
                        param = rct.request().getHeader(p.getApiParamName());
                    } else {
                        param = rct.request().getParam(p.getApiParamName());
                    }
                } else if (p.getType() == 1) {
                    if (p.getSysParamType() == ParamSystemVarTypeEnum.CLIENT_HOST) {
                        param = rct.request().remoteAddress().host();
                    } else if (p.getSysParamType() == ParamSystemVarTypeEnum.CLIENT_PORT) {
                        param = Integer.toString(rct.request().remoteAddress().port());
                    } else if (p.getSysParamType() == ParamSystemVarTypeEnum.CLIENT_PATH) {
                        param = rct.request().path() == null ? "" : rct.request().path();
                    } else if (p.getSysParamType() == ParamSystemVarTypeEnum.CLIENT_SESSION_ID) {
                        param = rct.session().id();
                    } else if (p.getSysParamType() == ParamSystemVarTypeEnum.CLIENT_ABSOLUTE_URI) {
                        param = rct.request().absoluteURI();
                    } else if (p.getSysParamType() == ParamSystemVarTypeEnum.CLIENT_REQUEST_SCHEMA) {
                        param = rct.request().scheme();
                    } else if (p.getSysParamType() == ParamSystemVarTypeEnum.SERVER_API_NAME) {
                        param = api.getApiName();
                    } else if (p.getSysParamType() == ParamSystemVarTypeEnum.SERVER_UNIX_TIME) {
                        param = Long.toString(System.currentTimeMillis());
                    } else if (p.getSysParamType() == ParamSystemVarTypeEnum.SERVER_USER_AGENT) {
                        param = VxApiGatewayAttribute.VX_API_USER_AGENT;
                    }
                } else if (p.getType() == 9) {
                    param = p.getParamValue().toString();
                } else {
                    continue;
                }
                if (p.getSerParamPosition() == ParamPositionEnum.HEADER) {
                    headers.add(p.getSerParamName(), param);
                } else if (p.getSerParamPosition() == ParamPositionEnum.PATH) {
                    requestPath = requestPath.replace(":" + p.getSerParamName(), param);
                } else {
                    queryParam.addParam(p.getSerParamName(), param);
                }
            }
            requestPath += queryParam.toString();
        }
        HttpClientRequest request = httpClient.requestAbs(serOptions.getMethod(), requestPath).setTimeout(serOptions.getTimeOut());
        request.handler(resp -> {
            // 设置请求响应时间
            trackInfo.setResponseTime(Instant.now());
            HttpServerResponse response = rct.response().putHeader(VxApiRouteConstant.SERVER, VxApiGatewayAttribute.FULL_NAME).putHeader(VxApiRouteConstant.CONTENT_TYPE, api.getContentType()).setChunked(true);
            Pump.pump(resp, response).start();
            resp.endHandler(end -> {
                // 透传header
                Set<String> tranHeaders = api.getResult().getTranHeaders();
                if (tranHeaders != null && tranHeaders.size() > 0) {
                    tranHeaders.forEach(h -> {
                        rct.response().putHeader(h, resp.getHeader(h) == null ? "" : resp.getHeader(h));
                    });
                }
                if (isNext) {
                    // 告诉后置处理器当前操作成功执行
                    rct.put(VxApiAfterHandler.PREV_IS_SUCCESS_KEY, Future.<Boolean>succeededFuture(true));
                    rct.next();
                } else {
                    rct.response().end();
                }
                // 统计响应长度
                String repLen = resp.getHeader("Content-Length");
                trackInfo.setResponseBufferLen(repLen == null ? 0 : StrUtil.getintTry(repLen));
                trackInfo.setEndTime(Instant.now());
                rct.vertx().eventBus().send(thisVertxName + VxApiEventBusAddressConstant.SYSTEM_PLUS_TRACK_INFO, trackInfo.toJson());
            });
        });
        // 异常处理
        request.exceptionHandler(e -> {
            if (isNext) {
                // 告诉后置处理器当前操作成功执行
                rct.put(VxApiAfterHandler.PREV_IS_SUCCESS_KEY, Future.<Boolean>failedFuture(e));
                rct.next();
            } else {
                HttpServerResponse response = rct.response().putHeader(VxApiRouteConstant.SERVER, VxApiGatewayAttribute.FULL_NAME).putHeader(VxApiRouteConstant.CONTENT_TYPE, api.getContentType());
                // 如果是连接异常返回无法连接的错误信息,其他异常返回相应的异常
                if (e instanceof ConnectException || e instanceof TimeoutException) {
                    response.setStatusCode(api.getResult().getCantConnServerStatus()).end(api.getResult().getCantConnServerExample());
                } else {
                    response.setStatusCode(api.getResult().getFailureStatus()).end(api.getResult().getFailureExample());
                }
            }
            // 提交连接请求失败
            policy.reportBadService(urlInfo.getIndex());
            trackInfo.setEndTime(Instant.now());
            // 记录与后台交互发生错误
            trackInfo.setSuccessful(false);
            trackInfo.setErrMsg(e.getMessage());
            trackInfo.setErrStackTrace(e.getStackTrace());
            rct.vertx().eventBus().send(thisVertxName + VxApiEventBusAddressConstant.SYSTEM_PLUS_TRACK_INFO, trackInfo.toJson());
        });
        // 设置请求时间
        trackInfo.setRequestTime(Instant.now());
        if (headers != null && headers.size() > 0) {
            request.headers().addAll(headers);
        }
        // 设置User-Agent
        String agnet = request.headers().get("User-Agent");
        if (agnet == null) {
            agnet = VxApiGatewayAttribute.VX_API_USER_AGENT;
        } else {
            agnet += " " + VxApiGatewayAttribute.VX_API_USER_AGENT;
        }
        request.putHeader("User-Agent", agnet);
        request.end();
        // 判断是否有坏的连接
        if (policy.isHaveBadService()) {
            if (!policy.isCheckWaiting()) {
                if (webClient == null) {
                    WebClient.create(rct.vertx());
                }
                policy.setCheckWaiting(true);
                rct.vertx().setTimer(serOptions.getRetryTime(), testConn -> {
                    List<VxApiServerURLInfo> service = policy.getBadService();
                    for (VxApiServerURLInfo urlinfo : service) {
                        webClient.requestAbs(serOptions.getMethod(), urlinfo.getUrl()).timeout(serOptions.getTimeOut()).send(res -> {
                            if (res.succeeded()) {
                                policy.reportGreatService(urlinfo.getIndex());
                            }
                        });
                    }
                    policy.setCheckWaiting(false);
                });
            }
        }
    } else {
        // 无可用连接时,结束当前处理器并尝试重新尝试连接是否可用
        if (isNext) {
            // 告诉后置处理器当前操作执行结果
            rct.put(VxApiAfterHandler.PREV_IS_SUCCESS_KEY, Future.<Boolean>failedFuture(new ConnectException("无法连接上后台交互的服务器")));
            rct.next();
        } else {
            rct.response().putHeader(VxApiRouteConstant.SERVER, VxApiGatewayAttribute.FULL_NAME).putHeader(VxApiRouteConstant.CONTENT_TYPE, api.getContentType()).setStatusCode(api.getResult().getCantConnServerStatus()).end(api.getResult().getCantConnServerExample());
        }
        if (!policy.isCheckWaiting()) {
            policy.setCheckWaiting(true);
            rct.vertx().setTimer(serOptions.getRetryTime(), testConn -> {
                List<VxApiServerURLInfo> service = policy.getBadService();
                for (VxApiServerURLInfo urlinfo : service) {
                    webClient.requestAbs(serOptions.getMethod(), urlinfo.getUrl()).timeout(serOptions.getTimeOut()).send(res -> {
                        if (res.succeeded()) {
                            policy.reportGreatService(urlinfo.getIndex());
                        }
                    });
                }
                policy.setCheckWaiting(false);
            });
        }
    }
}
Also used : VxApiTrackInfos(com.szmirren.vxApi.core.entity.VxApiTrackInfos) VxApiParamOptions(com.szmirren.vxApi.core.options.VxApiParamOptions) MultiMap(io.vertx.core.MultiMap) HttpClientRequest(io.vertx.core.http.HttpClientRequest) CaseInsensitiveHeaders(io.vertx.core.http.CaseInsensitiveHeaders) HttpServerResponse(io.vertx.core.http.HttpServerResponse) VxApiServerURLInfo(com.szmirren.vxApi.core.entity.VxApiServerURLInfo) QueryStringEncoder(io.netty.handler.codec.http.QueryStringEncoder) ConnectException(java.net.ConnectException) TimeoutException(java.util.concurrent.TimeoutException)

Example 5 with VxApiTrackInfos

use of com.szmirren.vxApi.core.entity.VxApiTrackInfos in project VX-API-Gateway by EliMirren.

the class SysVerticle method PlusError.

/**
 * 添加异常的数量
 *
 * @param msg
 */
public void PlusError(Message<JsonObject> msg) {
    errorCount += 1;
    if (msg.body() != null) {
        VxApiTrackInfos infos = VxApiTrackInfos.fromJson(msg.body());
        LOG.error(MessageFormat.format("应用:{0} , API:{1} ,在执行的过程中发生了异常:{2} ,堆栈信息{3}", infos.getAppName(), infos.getApiName(), infos.getErrMsg(), infos.getErrStackTrace()));
    }
}
Also used : VxApiTrackInfos(com.szmirren.vxApi.core.entity.VxApiTrackInfos)

Aggregations

VxApiTrackInfos (com.szmirren.vxApi.core.entity.VxApiTrackInfos)5 VxApiServerURLInfo (com.szmirren.vxApi.core.entity.VxApiServerURLInfo)2 VxApiParamOptions (com.szmirren.vxApi.core.options.VxApiParamOptions)2 MultiMap (io.vertx.core.MultiMap)2 CaseInsensitiveHeaders (io.vertx.core.http.CaseInsensitiveHeaders)2 HttpServerResponse (io.vertx.core.http.HttpServerResponse)2 ConnectException (java.net.ConnectException)2 TimeoutException (java.util.concurrent.TimeoutException)2 QueryStringEncoder (io.netty.handler.codec.http.QueryStringEncoder)1 Buffer (io.vertx.core.buffer.Buffer)1 HttpClientRequest (io.vertx.core.http.HttpClientRequest)1 JsonObject (io.vertx.core.json.JsonObject)1 Duration (java.time.Duration)1