关于git:eladmin代码贡献2w人star

https://github.com/elunez/eladmin/graphs/contributors id:itdzr

优化点
将用户信息缓存,晋升同账户(利用场景:admin)的并发和同一用户屡次登录状况下的性能,无需每次登陆都查询数据库,首次查问利用future task(申请数据库作为task,future task作为缓存的value,uid为key)执行异步查问,后续的线程因为缓存key存在会期待首次的查问后果(get办法),缩小了数据库资源的耗费。
初始登陆时,因为没有缓存,因为拜访数据库资源须要工夫,如果不必future,那么当第一个线程未返回后果时,那么缓存仍未有记录,则高并发下第二个线程仍会去拜访数据库资源。
分布式缓存尽量用redis,数据量小的的用本地缓存。
缓存选用,思考redis,concurrentHashmap也可,redis更优,

次要思维
高并发状况下比拟耗费资源的计算能够作为future task。防止同时的反复计算。本场景更适宜计算场景,无状态的场景。concurrentHashmap能够定时革除。

代码

concurrentHashmap<uid/uname,Future<udto>> userDtoCache;
 Future<JwtUserDto> future=userDtoCache.get(uid);

 if ( future!=null) {
            try {
                jwtUserDto=future.get();
            }catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }

            // 查看dataScope是否批改
            List<Long> dataScopes = jwtUserDto.getDataScopes();
            dataScopes.clear();
            dataScopes.addAll(dataService.getDeptIds(jwtUserDto.getUser()));
        }else{
            Callable<JwtUserDto> call=()->getJwtBySearchDB(username);
            FutureTask<JwtUserDto> ft=new FutureTask<>(call);
            future=userDtoCache.putIfAbsent(username,ft);
            if(future==null){
               future=ft;
               executor.submit(ft);
            }
            try{
                return future.get();

            }catch(CancellationException e){
                userDtoCache.remove(username);
            }catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }

        return jwtUserDto;

putIfAbsent 如果传入key对应的value曾经存在,就返回存在的value,不进行替换。如果不存在,就增加key和value,返回null

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理