博客缓存的那些事?

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介:

一、写在前面

最近博客的前端展示系统基本高一段落了,切换一下数据源,看看连接生产的数据试试效果,结果不是很理想,光一个首页就触发很多sql语句,为了能够缩短首页的加载时间,特做了几点优化。

1b745c599db48f33e25aea734e2e2b8a10493c2a

 ●   系统启动时,加载常用的变量
 ●   service做了一层通用的缓存拦截控制

二、系统启动加载缓存

 
  1. @Component

  2. @Order(1)

  3. public class CacheInit implements CommandLineRunner {

  4. private static final Logger log = LoggerFactory.getLogger(CacheInit.class);

  5. @Autowired

  6. private RedisTemplate<String,Object> redisTemplate;

  7. @Autowired

  8. private WpOptionsService wpOptionsService;

  9. /**

  10. * @param args

  11. * @throws Exception

  12. * @see org.springframework.boot.CommandLineRunner#run(java.lang.String[])

  13. */

  14. @Override

  15. public void run(String args) throws Exception {

  16. log.info(“>>>>>>>>>>>>>加载缓存数据开始<<<<<<<<<<<<<<<<<<<<<<“);

  17. Map<String,String> map= new HashMap<String,String>();

  18. List<WpOptions> list =wpOptionsService.autoloadConfig();

  19. for(WpOptions wpOptions:list){

  20. if(!StringUtils.isEmpty(wpOptions.getOptionValue())){

  21. map.put(wpOptions.getOptionName(), wpOptions.getOptionValue());

  22. }

  23. }

  24. log.info(“加载系统配置信息:”+list.size());

  25. redisTemplate.opsForValue().set(RedisConstant.autoloadConfig, map);

  26. //Object test =redisTemplate.opsForValue().get(“test”);

  27. //log.info(“取出缓存数据:”+test.toString());

  28. log.info(“>>>>>>>>>>>>>初始化缓存数据 结束<<<<<<<<<<<<<<<<<<<<<<“);

  29. }

  30. }

三、Service实现通用缓存控制:

大概思路如下:

1.新增一个注解,针对特定的注解进行拦截
2.设置一个通用的key生成算法
3.对缓存进行逻辑的判断

新增一个注解@RedisCache,对有需要的缓存的方法进行添加设置

 
  1. @Target({ElementType.METHOD})

  2. @Retention(RetentionPolicy.RUNTIME)

  3. @Inherited

  4. public @interface RedisCache {

  5. /**

  6. * 业务的名称

  7. */

  8. String value() default “”;

  9. /**

  10. * redis缓存的Key(默认类名-方法名-自定义key)

  11. */

  12. String key() default “”;

  13. /**

  14. * 是否刷新缓存,默认false

  15. */

  16. boolean flush() default false;

  17. /**

  18. * 缓存失效时间,默认30

  19. */

  20. long expire() default 30L;

  21. /**

  22. * 缓存时间单位,默认天

  23. */

  24. TimeUnit unit() default TimeUnit.DAYS;

  25. }

拦截代码

 
  1. @Pointcut(value = @annotation(cn.liuhaihua.web.annotation.RedisCache)”)

  2. public void pointcut() {

  3. }

key通用的生成算法

 
  1. /**

  2. * 获取切面缓存的key

  3. *

  4. * @param point

  5. * 当前切面执行的方法

  6. * @param extra

  7. * 额外的参数 (非必选)

  8. * @param prefix

  9. * key前缀 (非必选)

  10. * @throws NoSuchMethodException

  11. */

  12. public static String getKey(ProceedingJoinPoint point, String extra, String prefix) throws NoSuchMethodException {

  13. Method currentMethod = AspectUtil.getMethod(point);

  14. String methodName = currentMethod.getName();

  15. StringBuilder key = new StringBuilder();

  16. key.append(getKeyOfClassPrefix(point, prefix));

  17. key.append(“_”);

  18. key.append(methodName);

  19. key.append(getMethodParamsKey(point.getArgs()));

  20. key.append(null == extra ? “” : extra);

  21. return key.toString();

  22. }

对拦截的方法进行缓存逻辑处理

 
  1. @Around(“pointcut()”)

  2. public Object handle(ProceedingJoinPoint point) throws Throwable {

  3. Method currentMethod = AspectUtil.getMethod(point);

  4. //获取操作名称

  5. RedisCache cache = currentMethod.getAnnotation(RedisCache.class);

  6. boolean flush = cache.flush();

  7. if (flush) {

  8. String classPrefix = AspectUtil.getKeyOfClassPrefix(point, BIZ_CACHE_PREFIX);

  9. log.info(“清空缓存 {}*”, classPrefix);

  10. redisService.delBatch(classPrefix);

  11. return point.proceed();

  12. }

  13. //通用缓存

  14. String key = AspectUtil.getKey(point, cache.key(), BIZ_CACHE_PREFIX);

  15. log.info(“生成的KEY名字:{}”, key);

  16. boolean hasKey = redisService.hasKey(key);

  17. if (hasKey) {

  18. try {

  19. log.info(“{}从缓存中获取数据”, key);

  20. return redisService.get(key);

  21. } catch (Exception e) {

  22. log.error(“从缓存中获取数据失败!”, e);

  23. }

  24. }

  25. //先执行业务

  26. Object result = point.proceed();

  27. redisService.set(key, result, cache.expire(), cache.unit());

  28. log.info(“{}从数据库中获取数据”, key);

  29. return result;

  30. }

四、如何使用

代码如下

 
  1. @Override

  2. @RedisCache

  3. public List<WpLinks> getLinks(String linkrel) {

  4. if(StringUtils.isEmpty(linkrel) ){

  5. return wpLinksMapper.selectAll();

  6. }else{

  7. Example example = new Example(WpLinks.class);

  8. Criteria criteria = example.createCriteria();

  9. criteria.andEqualTo(“linkRel”, LinkConstant.LINK_REL_FRIEND);

  10. return wpLinksMapper.selectByExample(example);

  11. }

  12. }

效果

 
  1. INFO | 2018-11-26 14:06:57,264 | JWordpres-v2.0 | [http-nio-8090-exec-1-14] (c.l.w.a.RedisCacheAspect:70) | 生成的KEY名字:biz_cache_cn_liuhaihua_web_service_impl_WpLinksServiceImpl_getLinks(‘friend’)

  2. INFO | 2018-11-26 14:06:57,281 | JWordpres-v2.0 | [http-nio-8090-exec-1-14] (c.l.w.a.RedisCacheAspect:74) | biz_cache_cn_liuhaihua_web_service_impl_WpLinksServiceImpl_getLinks(‘friend’)从缓存中获取数据


原文发布时间为:2018-11-27

本文作者:HARRIES

本文来自云栖社区合作伙伴“Java杂记”,了解相关信息可以关注“Java杂记”。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
9月前
|
程序员
写博客的好处
写博客,其实是一件费力费时的事情,现实中没有多少人能长期坚持下来。我自己也是断断续续地写,也没有写坚持下来。在实践的过程中,我本身却是收益良多。我养成了记录的习惯,记录确实提高我的工作效率。
|
4月前
【博客项目】—数据分页(十)
【博客项目】—数据分页(十)
|
6月前
|
前端开发
前端好的博客收藏
前端好的博客收藏
35 0
|
7月前
|
存储 对象存储
博客优化差不多了
博客优化差不多了
|
存储 缓存 NoSQL
为你的Typecho使用Redis缓存,优化访问速度-织音博客
前言 Typecho虽然轻量,但终究仍是PHP动态脚本,访问时需要频繁调取数据库的信息,导致并发值一高,CPU就100%占用,无法处理新的请求信息。这时,我们可以用Redis来设置缓存,从而不用频繁调动数据库,来达到加速访问的目的。注意:Redis仅支持 Linux 系统,如果你是Windows系统,可考虑其他软件。 Redis介绍 Redis缓存是一个开源的使用ANSIC语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的api。 支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。 不仅仅支持简单的key-value类型
187 0
为你的Typecho使用Redis缓存,优化访问速度-织音博客
|
关系型数据库 MySQL PHP
Z-BlogPHP博客程序
Z-BlogPHP支持PHP 5.2 - 7.4、8.0,可运行在市面上所有的操作系统和WEB服务器之上。
81 0
Z-BlogPHP博客程序
坚持在简书写博客的好处
简书写到了200篇, 多少能感受到, 坚持写博客的好处 打发时间 在大学的开始写博客, 对一个不怎么擅长"到处浪浪浪"的大学生, 周末往往是最难熬的, 打游戏太菜, 看电影太困,玩手机太废, 出去玩太穷.
1312 0
从现在开始主要博客文章转移到oldpan.me博客站点
要经常写作!!! 要喜欢折腾!!! 以后博客更新内容都会在oldpan.me中!!!
1097 0
成功的博客都有好的内容
是什么让一个博客变得成功?相当的文章数不胜数,但不论怎样,所有的人都会同意这个观点:伟大的博客都有伟大的内容。 “内容才是王道”的呼声在站长界回响了数年的时间,虽然我认为一个博客要要想成功仅凭这句话是不够的,但“内容”的确是一个成功的博客必不可少的关键因素。
1045 0