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);
}
}
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());
});
}
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);
});
}
}
}
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);
});
}
}
}
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()));
}
}
Aggregations