• 18、优化网站性能


    本地缓存

    • 将数据缓存在应用服务器上,性能最好。(要考虑缓存大小,缓存的过期时间)
    • 常用缓存工具:Ehcache、Guava、Caffeine等。

    分布式缓存

    • 将数据缓存在NoSQL数据库上,跨服务器。
    • 常用缓存工具:MemCache、Redis等。

    多级缓存

    • 一级缓存(本地缓存)> 二级缓存(分布式缓存)> DB

    • 避免缓存雪崩(缓存失效,大量请求直达DB),提高系统的可用性

    本地缓存适合与用户无强关联的信息,Redis可以缓存与用户强关联的信息(如 登录凭证),可以跨服务器,但比本地缓存稍微慢些
    在这里插入图片描述
    两级缓存的过程:
    在这里插入图片描述

    本地缓存

    数据变化频率相对较低的数据比较使用于缓存。将热门帖子列表缓存到本地缓存中。使用Caffeine。

    1、自定义配置

    # caffeine
    caffeine.posts.max-size=15  // 设置缓存空间里缓存多少对象,缓存的列表的对象是page
    caffeine.posts.expire-seconds=180  // 3min
    
    
    • 1
    • 2
    • 3
    • 4

    缓存数据的更新一般有两种方式:1、数据发生更新 2、缓存到了过期时间

    3、优化业务方法,一般是优化Service。
    使用Caffeine 缓存 帖子列表和总的行数

    Caffeine的核心接口是Cache,其有两个子接口 LoadingCache, AsyncLoadingCache。LoadingCache 是同步缓存,AsyncLoadingCache可以实现异步、并发。

        @Value("${caffeine.posts.max-size}")
        private int maxSize;
    
        @Value("${caffeine.posts.expire-seconds}")
        private int expireSeconds;
    
        // Caffeine核心接口: Cache, LoadingCache, AsyncLoadingCache
    
        // 帖子列表缓存
        private LoadingCache<String, List<DiscussPost>> postListCache;
    
        // 帖子总数缓存
        private LoadingCache<Integer, Integer> postRowsCache;
    
        @PostConstruct
        public void init() {
            // 初始化帖子列表缓存
            postListCache = Caffeine.newBuilder()
                    .maximumSize(maxSize)
                    .expireAfterWrite(expireSeconds, TimeUnit.SECONDS)
                    .build(new CacheLoader<String, List<DiscussPost>>() {  
                        @Nullable
                        @Override
                        public List<DiscussPost> load(@NonNull String key) throws Exception {  // 该方法即是 当本地缓存不存在 所需的数据是,从数据库查找,并存入缓存中
                            if (key == null || key.length() == 0) {
                                throw new IllegalArgumentException("参数错误!");
                            }
    
                            String[] params = key.split(":");
                            if (params == null || params.length != 2) {
                                throw new IllegalArgumentException("参数错误!");
                            }
    
                            int offset = Integer.valueOf(params[0]);
                            int limit = Integer.valueOf(params[1]);
    
                            // 可以在这里添加二级缓存: Redis -> mysql
    
                            logger.debug("load post list from DB.");
                            return discussPostMapper.selectDiscussPosts(0, offset, limit, 1);
                        }
                    });
            // 初始化帖子总数缓存
            postRowsCache = Caffeine.newBuilder()
                    .maximumSize(maxSize)
                    .expireAfterWrite(expireSeconds, TimeUnit.SECONDS)
                    .build(new CacheLoader<Integer, Integer>() {
                        @Nullable
                        @Override
                        public Integer load(@NonNull Integer key) throws Exception {
                            logger.debug("load post rows from DB.");
                            return discussPostMapper.selectDiscussPostRows(key);
                        }
                    });
        }
    
        public List<DiscussPost> findDiscussPosts(int userId, int offset, int limit, int orderMode) {
            if (userId == 0 && orderMode == 1) {
            	// 只有当访问首页热门帖子时才从缓存中取数据
                return postListCache.get(offset + ":" + limit);
            }
    
            logger.debug("load post list from DB.");
            return discussPostMapper.selectDiscussPosts(userId, offset, limit, orderMode);
        }
    
        public int findDiscussPostRows(int userId) {
            if (userId == 0) {
                return postRowsCache.get(userId);
            }
    
            logger.debug("load post rows from DB.");
            return discussPostMapper.selectDiscussPostRows(userId);
        }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76

    压力测试

    二级缓存

    19、项目监控

    https://blog.csdn.net/weixin_42033436/article/details/117781598?spm=1001.2014.3001.5502

  • 相关阅读:
    使用归一化盒过滤器对图像进行平滑处理
    MySQL了解视图View (视图篇 一)
    1.1小程序内置tabbar和自定义tabbar区别
    【数据结构】轻松掌握二叉树的基本操作及查找技巧
    03 【流程控制语句】
    解决Elasticsearch集群 master_not_discovered_exception 异常
    Oneid方案
    jsp装修建材管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目
    mybatis根据表名动态批量新增,批量更新的实现方法(附排坑过程+完整源码完全可用)
    春游江淮 乐享五一|跟着《承欢记》来绩溪,治愈系的慢生活
  • 原文地址:https://blog.csdn.net/nice___amusin/article/details/126092868