Skip to content

Commit 18c2b02

Browse files
committed
perf: 微小调整,移除临时变量,尽量减少gc时间
1 parent bdb368a commit 18c2b02

File tree

1 file changed

+37
-48
lines changed

1 file changed

+37
-48
lines changed

src/main/java/top/meethigher/proxy/http/ReverseHttpProxy.java

Lines changed: 37 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package top.meethigher.proxy.http;
22

3-
import io.vertx.core.*;
3+
import io.vertx.core.AsyncResult;
4+
import io.vertx.core.Future;
5+
import io.vertx.core.Handler;
6+
import io.vertx.core.Vertx;
47
import io.vertx.core.http.*;
58
import io.vertx.core.json.JsonObject;
6-
import io.vertx.core.net.SocketAddress;
79
import io.vertx.ext.web.Route;
810
import io.vertx.ext.web.Router;
911
import io.vertx.ext.web.RoutingContext;
@@ -412,10 +414,8 @@ protected boolean isHopByHopHeader(String headerName) {
412414
* 复制请求头。复制的过程中忽略逐跳标头
413415
*/
414416
protected void copyRequestHeaders(RoutingContext ctx, HttpServerRequest realReq, HttpClientRequest proxyReq) {
415-
MultiMap realHeaders = realReq.headers();
416-
MultiMap proxyHeaders = proxyReq.headers();
417-
proxyHeaders.clear();
418-
for (String headerName : realHeaders.names()) {
417+
proxyReq.headers().clear();
418+
for (String headerName : realReq.headers().names()) {
419419
// 若是逐跳标头,则跳过
420420
if (isHopByHopHeader(headerName)) {
421421
continue;
@@ -424,7 +424,7 @@ protected void copyRequestHeaders(RoutingContext ctx, HttpServerRequest realReq,
424424
if ("host".equalsIgnoreCase(headerName)) {
425425
continue;
426426
}
427-
proxyHeaders.set(headerName, realHeaders.get(headerName));
427+
proxyReq.putHeader(headerName, realReq.headers().get(headerName));
428428
}
429429

430430
// 传递真实客户端信息
@@ -451,28 +451,26 @@ protected void copyRequestHeaders(RoutingContext ctx, HttpServerRequest realReq,
451451
* 复制响应头。复制的过程中忽略逐跳标头
452452
*/
453453
protected void copyResponseHeaders(RoutingContext ctx, HttpServerRequest realReq, HttpServerResponse realResp, HttpClientResponse proxyResp) {
454-
MultiMap proxyHeaders = proxyResp.headers();
455-
MultiMap realHeaders = realResp.headers();
456-
realHeaders.clear();
454+
realResp.headers().clear();
457455

458456
Map<String, String> needSetHeaderMap = new LinkedHashMap<>();
459-
for (String headerName : proxyHeaders.names()) {
457+
for (String headerName : proxyResp.headers().names()) {
460458
// 若是逐跳标头,则跳过
461459
if (isHopByHopHeader(headerName)) {
462460
continue;
463461
}
464462
// 保留Cookie
465463
if ("Set-Cookie".equalsIgnoreCase(headerName) || "Set-Cookie2".equalsIgnoreCase(headerName)) {
466464
if (getContextData(ctx, P_PRESERVE_COOKIES) != null && Boolean.parseBoolean(getContextData(ctx, P_PRESERVE_COOKIES).toString())) {
467-
needSetHeaderMap.put(headerName, proxyHeaders.get(headerName));
465+
needSetHeaderMap.put(headerName, proxyResp.headers().get(headerName));
468466
}
469467
}
470468
// 重写重定向Location
471469
else if ("Location".equalsIgnoreCase(headerName)) {
472-
String value = rewriteLocation(ctx, realReq.absoluteURI(), proxyHeaders.get(headerName));
470+
String value = rewriteLocation(ctx, realReq.absoluteURI(), proxyResp.headers().get(headerName));
473471
needSetHeaderMap.put(headerName, value);
474472
} else {
475-
needSetHeaderMap.put(headerName, proxyHeaders.get(headerName));
473+
needSetHeaderMap.put(headerName, proxyResp.headers().get(headerName));
476474
}
477475
}
478476
// 跨域由代理掌控
@@ -504,7 +502,7 @@ else if ("Location".equalsIgnoreCase(headerName)) {
504502

505503

506504
for (String key : needSetHeaderMap.keySet()) {
507-
realHeaders.set(key, needSetHeaderMap.get(key));
505+
realResp.headers().set(key, needSetHeaderMap.get(key));
508506
}
509507
}
510508

@@ -570,10 +568,8 @@ protected Handler<AsyncResult<HttpClientRequest>> connectHandler(RoutingContext
570568
setContextData(ctx, INTERNAL_PROXY_SERVER_CONNECTION_OPEN, true);
571569

572570
// 注册客户端与代理服务之间连接的断开监听事件。可监听主动关闭和被动关闭
573-
HttpConnection connection = clientReq.connection();
574-
SocketAddress localAddress = connection.localAddress();
575-
setContextData(ctx, INTERNAL_CLIENT_LOCAL_ADDR, localAddress.hostAddress() + ":" + localAddress.port());
576-
connection.closeHandler(v -> {
571+
setContextData(ctx, INTERNAL_CLIENT_LOCAL_ADDR, clientReq.connection().localAddress().toString());
572+
clientReq.connection().closeHandler(v -> {
577573
setContextData(ctx, INTERNAL_PROXY_SERVER_CONNECTION_OPEN, false);
578574
log.debug("proxyClient local connection {} closed",
579575
getContextData(ctx, INTERNAL_CLIENT_LOCAL_ADDR).toString());
@@ -592,7 +588,7 @@ protected Handler<AsyncResult<HttpClientRequest>> connectHandler(RoutingContext
592588
}
593589
} else if ((boolean) getContextData(ctx, INTERNAL_PROXY_SERVER_CONNECTION_OPEN) && !(boolean) getContextData(ctx, INTERNAL_CLIENT_CONNECTION_OPEN)) {
594590
// 整体链路连接不可用,释放资源
595-
connection.close();
591+
clientReq.connection().close();
596592
}
597593
} else {
598594
badGateway(ctx, serverResp);
@@ -619,74 +615,67 @@ protected Handler<RoutingContext> routingContextHandler(HttpClient httpClient) {
619615
// vertx的uri()是包含query参数的。而path()才是我们常说的不带有query的uri
620616
// route不是线程安全的。route里的metadata应以路由为单元存储,而不是以请求为单元存储。一个路由会有很多请求。
621617
// 若想要以请求为单元存储数据,应该使用routingContext.put
622-
Route route = ctx.currentRoute();
623618
// 将路由原数据,复制到请求上下文
624-
for (String key : route.metadata().keySet()) {
625-
setContextData(ctx, key, route.getMetadata(key));
619+
for (String key : ctx.currentRoute().metadata().keySet()) {
620+
setContextData(ctx, key, ctx.currentRoute().getMetadata(key));
626621
}
627622

628623
// 记录请求开始时间
629624
setContextData(ctx, INTERNAL_SEND_TIMESTAMP, System.currentTimeMillis());
630625
// 记录连接状态
631626
setContextData(ctx, INTERNAL_CLIENT_CONNECTION_OPEN, true);
632627

633-
634-
HttpServerRequest serverReq = ctx.request();
635-
HttpServerResponse serverResp = ctx.response();
636-
637628
// 暂停流读取
638-
serverReq.pause();
629+
ctx.request().pause();
639630

640631

641632
// 获取代理地址
642-
String proxyUrl = getProxyUrl(ctx, serverReq, serverResp);
633+
String proxyUrl = getProxyUrl(ctx, ctx.request(), ctx.response());
643634
setContextData(ctx, INTERNAL_PROXY_URL, proxyUrl);
644-
setContextData(ctx, INTERNAL_SERVER_HTTP_VERSION, serverReq.version().alpnName());
645-
setContextData(ctx, INTERNAL_METHOD, serverReq.method().name());
646-
setContextData(ctx, INTERNAL_USER_AGENT, serverReq.getHeader("User-Agent"));
647-
setContextData(ctx, INTERNAL_SOURCE_URI, serverReq.uri());
635+
setContextData(ctx, INTERNAL_SERVER_HTTP_VERSION, ctx.request().version().alpnName());
636+
setContextData(ctx, INTERNAL_METHOD, ctx.request().method().name());
637+
setContextData(ctx, INTERNAL_USER_AGENT, ctx.request().getHeader("User-Agent"));
638+
setContextData(ctx, INTERNAL_SOURCE_URI, ctx.request().uri());
648639

649640

650641
// 构建请求参数
651642
RequestOptions requestOptions = new RequestOptions();
652643
requestOptions.setAbsoluteURI(proxyUrl);
653-
requestOptions.setMethod(serverReq.method());
644+
requestOptions.setMethod(ctx.request().method());
654645
requestOptions.setFollowRedirects(getContextData(ctx, P_FOLLOW_REDIRECTS) != null && Boolean.parseBoolean(getContextData(ctx, P_FOLLOW_REDIRECTS).toString()));
655646

656647

657648
// 注册客户端与代理服务之间连接的断开监听事件。可监听主动关闭和被动关闭
658-
HttpConnection connection = serverReq.connection();
659-
SocketAddress remoteAddress = connection.remoteAddress();
660-
setContextData(ctx, INTERNAL_SERVER_REMOTE_ADDR, remoteAddress.hostAddress() + ":" + remoteAddress.port());
649+
setContextData(ctx, INTERNAL_SERVER_REMOTE_ADDR, ctx.request().connection().remoteAddress().toString());
661650

662-
connection.closeHandler(v -> {
651+
ctx.request().connection().closeHandler(v -> {
663652
setContextData(ctx, INTERNAL_CLIENT_CONNECTION_OPEN, false);
664653
log.debug("proxyServer remote connection {} closed", getContextData(ctx, INTERNAL_SERVER_REMOTE_ADDR).toString());
665654
});
666655

667656
// 如果跨域由代理服务接管,那么针对跨域使用的OPTIONS预检请求,就由代理服务接管,而不经过实际的后端服务
668-
if (HttpMethod.OPTIONS.name().equalsIgnoreCase(serverReq.method().name()) &&
657+
if (HttpMethod.OPTIONS.name().equalsIgnoreCase(ctx.request().method().name()) &&
669658
getContextData(ctx, P_CORS_CONTROL) != null && Boolean.parseBoolean(getContextData(ctx, P_CORS_CONTROL).toString()) &&
670659
getContextData(ctx, P_ALLOW_CORS) != null && Boolean.parseBoolean(getContextData(ctx, P_ALLOW_CORS).toString())
671660
) {
672-
String header = serverReq.getHeader("origin");
661+
String header = ctx.request().getHeader("origin");
673662
if (header == null || header.isEmpty()) {
674-
serverResp.putHeader("Access-Control-Allow-Origin", "*");
663+
ctx.response().putHeader("Access-Control-Allow-Origin", "*");
675664
} else {
676-
serverResp.putHeader("Access-Control-Allow-Origin", header);
665+
ctx.response().putHeader("Access-Control-Allow-Origin", header);
677666
}
678-
serverResp.putHeader("Access-Control-Allow-Methods", "*");
679-
serverResp.putHeader("Access-Control-Allow-Headers", "*");
680-
serverResp.putHeader("Access-Control-Allow-Credentials", "true");
681-
serverResp.putHeader("Access-Control-Expose-Headers", "*");
682-
setStatusCode(ctx, serverResp, 200).end();
667+
ctx.response().putHeader("Access-Control-Allow-Methods", "*");
668+
ctx.response().putHeader("Access-Control-Allow-Headers", "*");
669+
ctx.response().putHeader("Access-Control-Allow-Credentials", "true");
670+
ctx.response().putHeader("Access-Control-Expose-Headers", "*");
671+
setStatusCode(ctx, ctx.response(), 200).end();
683672
doLog(ctx);
684673
return;
685674
}
686675

687676
// 请求
688677
if ((boolean) getContextData(ctx, INTERNAL_CLIENT_CONNECTION_OPEN)) {
689-
httpClient.request(requestOptions).onComplete(connectHandler(ctx, serverReq, serverResp, proxyUrl));
678+
httpClient.request(requestOptions).onComplete(connectHandler(ctx, ctx.request(), ctx.response(), proxyUrl));
690679
}
691680
};
692681
}

0 commit comments

Comments
 (0)