首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >[JWT][JJWT]函数compact()非常慢

[JWT][JJWT]函数compact()非常慢
EN

Stack Overflow用户
提问于 2018-09-07 16:32:06
回答 1查看 460关注 0票数 0

我使用lib JJWT 0.9.0来生成Token。如何更快地运行函数compact(),或者如何更快地生成令牌?我使用JDK7。

我的代码:

代码语言:javascript
复制
public String createJWT(String id, String issuer, String subject, List<T> authories, String loginUserData,
            long ttlMillis) {
        //The JWT signature algorithm we will be using to sign the token
        long startTime = System.currentTimeMillis();
        LOGGER.info("createJWT id=" + id + ";issuer=" + ";subject=" + subject);
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS512;

        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);

        //We will sign our JWT with our ApiKey secret
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(ApiSecretKey.getSecretKey());
        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());

        //Let's set the JWT Claims
        JwtBuilder builder = Jwts.builder().setId(id).setIssuedAt(now).setSubject(subject)
                .setIssuer(issuer);
        if (!CheckObjectUtils.isNullOrEmpty(authories)) {
            builder.claim(AUTHORITIES_KEY, authories);
        }
        if (!CheckObjectUtils.isNullOrEmpty(loginUserData)) {
            builder.claim(LOGIN_USER_DATA_KEY, loginUserData);
        }

        builder.signWith(signatureAlgorithm, signingKey);

        //if it has been specified, let's add the expiration
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp);
        }
        LOGGER.info("createJWT process id=" + id + ";issuer=" + ";subject=" + subject + ";time(ms)="
                + (System.currentTimeMillis() - startTime));
        //Builds the JWT and serializes it to a compact, URL-safe string        
        String token = builder.compact();
        LOGGER.info("createJWT end id=" + id + ";issuer=" + ";subject=" + subject + ";time(ms)="
                + (System.currentTimeMillis() - startTime));
        return token;
    }

JsonWebTokenRestApi<Long> jwtApi = new JsonWebTokenRestApiFactory(
                JsonWebTokenRestApiFactory.JWT_JJWT).getJsonWebTokenByType();
        String jwt = jwtApi.createJWT(null, null, "vinhhc_vsc", null, null, 18000);

我的控制台日志:

代码语言:javascript
复制
createJWT id=null;issuer=;subject=vinhhc_vsc
createJWT process id=null;issuer=;subject=vinhhc_vsc;time(ms)=151
createJWT end id=null;issuer=;subject=vinhhc_vsc;time(ms)=664

谢谢!

EN

回答 1

Stack Overflow用户

发布于 2019-04-11 04:56:35

这是正常的JVM JIT行为-由于JIT优化,初始运行缓慢,随后运行优化/快速是完全正常的。只需在循环中运行compact()调用,看看会发生什么。

以下是使用最“昂贵”的密钥算法HMAC-SHA-512重写的测试作为证明:

代码语言:javascript
复制
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.lang.Collections;
import io.jsonwebtoken.lang.Strings;
import io.jsonwebtoken.security.Keys;

import java.security.Key;
import java.util.Date;
import java.util.List;
import java.util.UUID;

public class Test {

    private static final Key signingKey = Keys.secretKeyFor(SignatureAlgorithm.HS512);

    private static <T> String createJWT(String id, String issuer, String subject, List<T> authories, String loginUserData,
                                       long ttlMillis) {
        //The JWT signature algorithm we will be using to sign the token
        long startTime = System.currentTimeMillis();
        System.out.println("createJWT id=" + id + ";issuer=" + ";subject=" + subject);
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS512;

        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);

        //Let's set the JWT Claims
        JwtBuilder builder = Jwts.builder().setId(id).setIssuedAt(now).setSubject(subject)
                .setIssuer(issuer);
        if (!Collections.isEmpty(authories)) {
            builder.claim("authorities", authories);
        }
        if (!Strings.hasText(loginUserData)) {
            builder.claim("loginUserData", loginUserData);
        }

        builder.signWith(signingKey);

        //if it has been specified, let's add the expiration
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp);
        }
        System.out.println("createJWT process id=" + id + ";issuer=" + ";subject=" + subject + ";time(ms)="
                + (System.currentTimeMillis() - startTime));
        //Builds the JWT and serializes it to a compact, URL-safe string
        String token = builder.compact();
        System.out.println("createJWT end id=" + id + ";issuer=" + ";subject=" + subject + ";time(ms)="
                + (System.currentTimeMillis() - startTime));
        return token;
    }

    public static void main(String[] args) {
        for( int i = 0; i < 10; i++) {
            createJWT(UUID.randomUUID().toString(), "issuer", "subject", null, "random user data", 1000);
        }
    }
}

以下是循环的输出:

代码语言:javascript
复制
createJWT id=983edbec-49f9-4754-9836-bae85c6c26e8;issuer=;subject=subject
createJWT process id=983edbec-49f9-4754-9836-bae85c6c26e8;issuer=;subject=subject;time(ms)=19
createJWT end id=983edbec-49f9-4754-9836-bae85c6c26e8;issuer=;subject=subject;time(ms)=319
createJWT id=ee8fa433-d032-4258-80e8-21f5fa54904c;issuer=;subject=subject
createJWT process id=ee8fa433-d032-4258-80e8-21f5fa54904c;issuer=;subject=subject;time(ms)=0
createJWT end id=ee8fa433-d032-4258-80e8-21f5fa54904c;issuer=;subject=subject;time(ms)=1
createJWT id=b8343d70-39e5-41fd-99e0-0046a0dcdb3c;issuer=;subject=subject
createJWT process id=b8343d70-39e5-41fd-99e0-0046a0dcdb3c;issuer=;subject=subject;time(ms)=0
createJWT end id=b8343d70-39e5-41fd-99e0-0046a0dcdb3c;issuer=;subject=subject;time(ms)=0
createJWT id=a2a81bfc-1bfd-42f8-81e3-dd27ca0bc343;issuer=;subject=subject
createJWT process id=a2a81bfc-1bfd-42f8-81e3-dd27ca0bc343;issuer=;subject=subject;time(ms)=0
createJWT end id=a2a81bfc-1bfd-42f8-81e3-dd27ca0bc343;issuer=;subject=subject;time(ms)=0
createJWT id=4236c531-d370-45d6-98cb-532b863d45af;issuer=;subject=subject
createJWT process id=4236c531-d370-45d6-98cb-532b863d45af;issuer=;subject=subject;time(ms)=0
createJWT end id=4236c531-d370-45d6-98cb-532b863d45af;issuer=;subject=subject;time(ms)=1
createJWT id=c3979b5c-2840-48bd-b72d-1e5d3776916b;issuer=;subject=subject
createJWT process id=c3979b5c-2840-48bd-b72d-1e5d3776916b;issuer=;subject=subject;time(ms)=0
createJWT end id=c3979b5c-2840-48bd-b72d-1e5d3776916b;issuer=;subject=subject;time(ms)=0
createJWT id=155e6ac6-da45-402b-a7a8-e98b358a3525;issuer=;subject=subject
createJWT process id=155e6ac6-da45-402b-a7a8-e98b358a3525;issuer=;subject=subject;time(ms)=0
createJWT end id=155e6ac6-da45-402b-a7a8-e98b358a3525;issuer=;subject=subject;time(ms)=1
createJWT id=f1cdc87c-2054-4ff5-bb5c-4b47384a1285;issuer=;subject=subject
createJWT process id=f1cdc87c-2054-4ff5-bb5c-4b47384a1285;issuer=;subject=subject;time(ms)=0
createJWT end id=f1cdc87c-2054-4ff5-bb5c-4b47384a1285;issuer=;subject=subject;time(ms)=0
createJWT id=0303f53f-9b9a-4e7c-99c6-788dbb883ce2;issuer=;subject=subject
createJWT process id=0303f53f-9b9a-4e7c-99c6-788dbb883ce2;issuer=;subject=subject;time(ms)=0
createJWT end id=0303f53f-9b9a-4e7c-99c6-788dbb883ce2;issuer=;subject=subject;time(ms)=1
createJWT id=701d08c1-cfcf-4f20-9270-5b1800d9a7e0;issuer=;subject=subject
createJWT process id=701d08c1-cfcf-4f20-9270-5b1800d9a7e0;issuer=;subject=subject;time(ms)=0
createJWT end id=701d08c1-cfcf-4f20-9270-5b1800d9a7e0;issuer=;subject=subject;time(ms)=0

请注意,第一次(也只是第一次)运行的开销很大(公平地说,它只有319毫秒),而由于JIT优化,所有其他的运行都非常快。

大多数后续的compact()调用通常只有几微秒(甚至不到1毫秒)!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52218524

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档