为什么使用 nginx-jwt 验证令牌速度如此缓慢?

我正在编写一个非常简单的 Spring 应用程序。

我想比较使用 nginx-jwt(Lua)验证令牌的时间和使用纯 Java(jose4j)验证令牌的时间。 通过对具有身份验证标头的端点进行 POST 请求,端点 / 是我使用 nginx-jwt 进行验证的地方,而 /token-java 是使用 Java 的端点。

nginx-jwt 是一种使用 Lua 脚本验证令牌的工具,我还编写了一个程序来测试使用 java 和 nginx-jwt 进行验证的时间。

public class ComparePerformance {
     private static final String NGINX_VALIDATE_URL = "http://localhost/";
     private static final String JAVA_VALIDATE_URL = "http://localhost/token-java";
     private RestTemplate restTemplate;

    public ComparePerformance() {
        restTemplate = new RestTemplate();
    }

    public long getTimeValidateNginx() {
        return getTimeValidate(NGINX_VALIDATE_URL);
    }

    public long getTimeValidateJava() {
        return getTimeValidate(JAVA_VALIDATE_URL);
    }

    private long getTimeValidate(String url) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", getToken());
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        HttpEntity<String> entity = new HttpEntity<>("parameters", headers);
        long startTime = System.nanoTime();
        for (int i = 0; i < 10; i++) {
            restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
        }
        long endTime = System.nanoTime();
        return endTime - startTime;
    }

    private String getToken() {
        return "Bearer xxxx";
    }

    public static void main(String[] args) {
        ComparePerformance cp = new ComparePerformance();
        long timeNginx = cp.getTimeValidateNginx() / 1_000_000;
        long timeJava = cp.getTimeValidateJava() / 1_000_000;

        LogUtil.log(Level.INFO, cp.getClass(),
            "%nNginx validate time: %dms%n" +
                    "Java validate time: %dms", timeNginx, timeJava);
}

}

这是我的 Nginx 配置:(nginx.conf)

location / {
    access_by_lua '
        local jwt = require("nginx-jwt")
        jwt.auth()
    ';
    proxy_pass http://localhost;
}

location /token-java {
    proxy_pass http://localhost/token-java
}

这是我的 Java 验证,我使用 jose4j 使用 hs256 算法进行验证 - 与 nginx-jwt 相同,以下是验证和解析令牌的方法:

public Map<String, Object> parseToken(String JWTToken) throws InvalidJwtException {

    Key verificationKey = new HmacKey(secretKey.getBytes());
    JwtConsumer secondPassJwtConsumer = new JwtConsumerBuilder()
            .setExpectedIssuer(officialIssuer)
            .setSkipDefaultAudienceValidation()
            .setVerificationKey(verificationKey)
            .setRequireExpirationTime()
            .setAllowedClockSkewInSeconds(30)
            .setRequireSubject()
            .build();
    JwtClaims jwtClaims = secondPassJwtConsumer.processToClaims(JWTToken);

    return jwtClaims.getClaimsMap();
}

这是结果:

Nginx validate time: 9037ms
Java validate time: 57ms

如您所见,Nginx 比 Java 慢得多。

有谁能解释一下吗? 我感到非常困惑,因为我看到一些图片显示 Lua 比 Java 快。

点赞
用户6211518
用户6211518

抱歉要问这个问题。

我发现为什么我的 nginx-jwt 验证令牌如此缓慢。原因很简单,因为我在"/"端点处使用了 limit request。当移除该限制时,nginx 的验证速度不会像使用 Java 应用程序验证一样缓慢。

抱歉要问这个问题。

我发现为什么我的 `nginx-jwt` 验证令牌如此缓慢。原因很简单,因为我在`"/"`端点处使用了 `limit request`。当移除该限制时,`nginx` 的验证速度不会像使用 `Java` 应用程序验证一样缓慢。 
2017-01-18 10:18:29