1.多级缓存API封装我们的业务数据,比如商品分类、门店、商品基本信息等,都可以在本地进行适当的缓存,以提升性能。在多实例的情况下,不仅会使用本地缓存,还会使用分布式缓存,因此需要适当的API封装来简化缓存操作。1.本地缓存初始化publicclassLocalCacheInitServiceextendsBaseService{@OverridepublicvoidafterPropertiesSet()throwsException{//商品类别缓存CachecategoryCache=CacheBuilder.newBuilder().softValues().maximumSize(1000000).expireAfterWrite(Switches.CATEGORY.CATEGORY)/2,TimeUnit.SECONDS).build();addCache(CacheKeys.CATEGORY_KEY,categoryCache);}privatevoidaddCache(Stringkey,Cache,?>cache){localCacheService.addCache(key,cache);}}本地缓存过期时间采用分布式缓存过期时间的一半,防止本地缓存数据缓存时间过长导致多个实例间数据不一致。另外缓存KEY前缀与本地缓存相关联,这样就可以通过匹配缓存KEY前缀找到关联的本地缓存。2.写缓存API包先写入本地缓存,如果需要写入分布式缓存,则异步更新分布式缓存。publicvoidset(finalStringkey,finalObjectvalue,finalintremoteCacheExpiresInSeconds)throwsRuntimeException{if(value==null){return;}//复制value对象//本地缓存是引用,分布式缓存需要序列化//如果没有复制,假设Changing后的数据会导致本地缓存和分布式缓存不一致finalObjectfinalValue=copy(value);//如果配置了写本地缓存,根据KEY获取相关的本地缓存,然后写入if(writeLocalCache){CachelocalCache=getLocalCache(key);if(localCache!=null){localCache.put(key,finalValue);}}//如果分布式缓存没有写入,直接返回if(!writeRemoteCache){return;}//异步更新分布式缓存asyncTaskExecutor.execute(()->{try{redisCache.set(key,JSONUtils.toJSON(finalValue),remoteCacheExpiresInSeconds);}catch(Exceptione){LOG.error("updaterediscacheerror,key:{}",key,e);}});}这里使用异步更新,让用户请求尽快返回。并且因为有本地缓存??,即使分布式缓存更新慢,出现回源,也可以把***缓存到本地。3、读缓存API包先读取本地缓存,如果本地缓存不完善,再批量查询分布式缓存,查询分布式缓存时通过分区批量查询。privateMapinnerMget(Listkeys,Listtypes)throwsException{Mapresult=Maps.newHashMap();ListmissKeys=Lists.newArrayList();ListmissTypes=Lists。newArrayList();//如果配置了读取本地缓存,则先读取本地缓存if(readLocalCache){for(inti=0;imissResult=Maps.newHashMap();//对于KEY分区,不要一次调用过多的batchfinalList>keysPage=Lists.partition(missKeys,10);List>>pageFutures=Lists.newArrayList();try{//批量获取分布式缓存数据for(finalListpartitionKeys:keysPage){pageFutures.add(asyncTaskExecutor.提交(()->redisCache.mget(partitionKeys)));}for(Future