Browse Source

Adds attribute for PathContainer to avoid repeating parsePath in PathRoutePredicateFactory

Fixes gh-2884
pull/2918/head
liruihao 2 years ago committed by spencergibb
parent
commit
18e116c1c6
No known key found for this signature in database
GPG Key ID: 7788A47380690861
  1. 11
      spring-cloud-gateway-server/pom.xml
  2. 8
      spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/handler/predicate/PathRoutePredicateFactory.java
  3. 5
      spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtils.java
  4. 78
      spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/handler/predicate/PathRoutePredicatePathContainerAttrBenchMarkTests.java

11
spring-cloud-gateway-server/pom.xml

@ -170,6 +170,17 @@ @@ -170,6 +170,17 @@
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.20</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.20</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>

8
spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/handler/predicate/PathRoutePredicateFactory.java

@ -34,6 +34,7 @@ import org.springframework.web.util.pattern.PathPatternParser; @@ -34,6 +34,7 @@ import org.springframework.web.util.pattern.PathPatternParser;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_PREDICATE_MATCHED_PATH_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_PREDICATE_MATCHED_PATH_ROUTE_ID_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_PREDICATE_PATH_CONTAINER_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_PREDICATE_ROUTE_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.putUriTemplateVariables;
import static org.springframework.http.server.PathContainer.parsePath;
@ -89,7 +90,12 @@ public class PathRoutePredicateFactory extends AbstractRoutePredicateFactory<Pat @@ -89,7 +90,12 @@ public class PathRoutePredicateFactory extends AbstractRoutePredicateFactory<Pat
return new GatewayPredicate() {
@Override
public boolean test(ServerWebExchange exchange) {
PathContainer path = parsePath(exchange.getRequest().getURI().getRawPath());
PathContainer path = (PathContainer) exchange.getAttributes()
.get(GATEWAY_PREDICATE_PATH_CONTAINER_ATTR);
if (path == null) {
path = parsePath(exchange.getRequest().getURI().getRawPath());
exchange.getAttributes().put(GATEWAY_PREDICATE_PATH_CONTAINER_ATTR, path);
}
PathPattern match = null;
for (int i = 0; i < pathPatterns.size(); i++) {

5
spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtils.java

@ -122,6 +122,11 @@ public final class ServerWebExchangeUtils { @@ -122,6 +122,11 @@ public final class ServerWebExchangeUtils {
public static final String GATEWAY_PREDICATE_MATCHED_PATH_ROUTE_ID_ATTR = qualify(
"gatewayPredicateMatchedPathRouteIdAttr");
/**
* Gateway predicate path container attribute name.
*/
public static final String GATEWAY_PREDICATE_PATH_CONTAINER_ATTR = qualify("gatewayPredicatePathContainer");
/**
* Weight attribute name.
*/

78
spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/handler/predicate/PathRoutePredicatePathContainerAttrBenchMarkTests.java

@ -0,0 +1,78 @@ @@ -0,0 +1,78 @@
/*
* Copyright 2013-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.gateway.handler.predicate;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.function.Predicate;
import org.apache.commons.lang3.RandomStringUtils;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.annotations.Warmup;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
import org.springframework.mock.web.server.MockServerWebExchange;
import org.springframework.web.server.ServerWebExchange;
public class PathRoutePredicatePathContainerAttrBenchMarkTests {
private static List<Predicate<ServerWebExchange>> predicates;
private static String PATH_PATTERN_PREFIX;
private final static String HOST = "http://localhost:8080";
private final static int ROUTES_NUM = 2000;
static {
predicates = new LinkedList<>();
PATH_PATTERN_PREFIX = String.format("/%s/%s/", RandomStringUtils.random(20, true, false),
RandomStringUtils.random(10, true, false));
for (int i = 0; i < ROUTES_NUM; i++) {
PathRoutePredicateFactory.Config config = new PathRoutePredicateFactory.Config()
.setPatterns(Collections.singletonList(PATH_PATTERN_PREFIX + i)).setMatchTrailingSlash(true);
Predicate<ServerWebExchange> predicate = new PathRoutePredicateFactory().apply(config);
predicates.add(predicate);
}
}
@Benchmark
@Threads(2)
@Fork(2)
@BenchmarkMode(Mode.All)
@Warmup(iterations = 1, time = 3)
@Measurement(iterations = 10, time = 1)
public void testPathContainerAttr() {
Random random = new Random();
MockServerHttpRequest request = MockServerHttpRequest
.get(HOST + PATH_PATTERN_PREFIX + random.nextInt(ROUTES_NUM)).build();
MockServerWebExchange exchange = MockServerWebExchange.from(request);
for (Predicate<ServerWebExchange> predicate : predicates) {
if (predicate.test(exchange)) {
break;
}
}
}
}
Loading…
Cancel
Save