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