• 谷粒商城-day14-商城业务与压力测试


    整合 thymeleaf

    依赖

    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-thymeleafartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4

    image-20220727155827813

    访问 首页

    image-20220727160123771

    image-20220727160204553

    这里跟雷神讲的 springboot2 也互动了下,哈哈哈哈,前端时间也复习了下

    整合 dev-tools

    <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-devtoolsartifactId>
                <optional>trueoptional>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    yml 关闭 thymeleaf缓存

    这里先取出以及分类

    Controller

    @Controller
    public class IndexController {
    
        @Resource
        CategoryService categoryService;
    
        @GetMapping({"/", "/index.html"})
        public String indexPage(Model model) {
            // TODO 查出所有的分类数据
            List<CategoryEntity> categorys = categoryService.getLevel1Categorys();
    
            // 这里提供过 默认前缀和后缀 thymeleaf
            // 视图解析器
            // 如果之前搞过 springMVC 整合 会对这里很熟悉
    
            model.addAttribute("categorys", categorys);
    
            return "index";
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    service 比较简单就是 parent_id 为 0 的分类数据

    下面把前端渲染的代码简单写下,就是 thymeleaf 的遍历还有属性绑定,熟悉 vue 的这块就会发现就是换了个底层实现

    <li th:each="category : ${categorys}">
                            <a href="#" class="header_main_left_a" th:attr="ctg-data=${category.catId}"><b th:text="${category.name}">b>a>
                        li>
    
    • 1
    • 2
    • 3

    渲染二三级目录

    这个之前做过一次,主要就是要构造符合要求的 json

    controller 代码我贴一下

    @Override
        public Map<String, List<Catelog2Vo>> getCatalogJson() {
            // 1. 查出所有1级分类
            List<CategoryEntity> level1Categorys = getLevel1Categorys();
    
            // 2. 封装数据
            // 1.每一个分类,查到这个一级分类的二级分类
            Map<String, List<Catelog2Vo>> parentCid = level1Categorys.stream().collect(Collectors.toMap(k -> k.getCatId().toString(), v -> {
                // 1.每一个分类,查到这个一级分类的二级分类
                List<CategoryEntity> categoryEntityList = baseMapper.selectList(
                        new QueryWrapper<CategoryEntity>().eq("parent_cid", v.getCatId()));
                // 2. 封装上面的结果
                List<Catelog2Vo> catelog2Vos = null;
                if (categoryEntityList != null) {
                    catelog2Vos = categoryEntityList.stream().map(l2 -> {
                        Catelog2Vo catelog2Vo = new Catelog2Vo(v.getCatId().toString(), null, l2.getCatId().toString(), l2.getName());
    
                        // 1. 找到当前二级分类的三级分类分装成 vo
                        List<CategoryEntity> level3Catalog = baseMapper.selectList(new QueryWrapper<CategoryEntity>().eq("parent_cid", l2.getCatId()));
                        if (level3Catalog!=null) {
                            List<Catelog2Vo.Catelog3Vo> collect = level3Catalog.stream().map(l3 -> {
                                // 2.封装成指定格式
                                Catelog2Vo.Catelog3Vo catelog3Vo = new Catelog2Vo.Catelog3Vo(l2.getCatId().toString(), l3.getCatId().toString(), l3.getName());
                                return catelog3Vo;
                            }).collect(Collectors.toList());
                            catelog2Vo.setCatalog3List(collect);
                        }
    
                        return catelog2Vo;
                    }).collect(Collectors.toList());
                }
                return catelog2Vos;
            }));
    
            return parentCid;
        }
    
    • 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

    搭建域名访问环境

    image-20220728113214030

    image-20220728133207157

    上面是需要实现的效果,简单说下我这边环境,我这边 nginx 没用 docker,本地安装的nginx,然后java服务也在本机

    # /etc/hosts
    127.0.0.1 gulimall.com
    
    # nginx.conf
    upstream gulimall {
    server localhost:88;
    }
    
    # 详细配置
    server {
    listen 80;
    server_name gulimall.com;
    
    location / {
    proxy_set_header Host $host;
    proxy_pass http://gulimall;
    }
    
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
    root /usr/share/nginx/html;
    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    gateway

    - id: gulimall_host_route
      uri: lb://gulimall-product
      predicates:
        - Host=**.gulimall.com,gulimall.com
    
    • 1
    • 2
    • 3
    • 4

    访问 gulimall.com 测试即可

    性能压测

    image-20220728145038748

    这里通过修改 简单测试下吞吐量大小image-20220728145057663

    jvisualvm

    我这边 jdk 自带的里面用不了,去官网重新下载了个 VisualVM: Download

    image-20220728163053233

    装下 visual gc 这个插件

    nginx 动静分离

    image-20220728165024807

    mac 上 Nginx 文件目录是这个 /opt/homebrew/opt/nginx/html

    我们把 thymeleaf 里面的 static 文件夹放到 nginx 下面

    nginx 添加配置

    server {
    listen 80;
    server_name gulimall.com;
    
    location /static/ {
    root /opt/homebrew/opt/nginx/html;
    }
    
    location / {
    proxy_set_header Host $host;
    proxy_pass http://gulimall;
    }
    
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
    root /usr/share/nginx/html;
    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    nginx -s reload

    重启即可

    优化三级分类代码

    总的思路就是减少搜索次数,一次扫表,后续从这个集合 中取,这个我有个项目当中也是这样做的,没缓存情况下很多次搜索io开销很高

    @Override
        public Map<String, List<Catelog2Vo>> getCatalogJson() {
    
            // TODO 将数据库的查询变成一次
            List<CategoryEntity> selectList = baseMapper.selectList(null);
    
            // 1. 查出所有1级分类
            List<CategoryEntity> level1Categorys = getParentCid(selectList, 0L);
    
            // 2. 封装数据
            // 1.每一个分类,查到这个一级分类的二级分类
            Map<String, List<Catelog2Vo>> parentCid = level1Categorys.stream().collect(Collectors.toMap(k -> k.getCatId().toString(), v -> {
                // 1.每一个分类,查到这个一级分类的二级分类
                List<CategoryEntity> categoryEntityList = getParentCid(selectList, v.getCatId());
                // 2. 封装上面的结果
                List<Catelog2Vo> catelog2Vos = null;
                if (categoryEntityList != null) {
                    catelog2Vos = categoryEntityList.stream().map(l2 -> {
                        Catelog2Vo catelog2Vo = new Catelog2Vo(v.getCatId().toString(), null, l2.getCatId().toString(), l2.getName());
    
                        // 1. 找到当前二级分类的三级分类分装成 vo
                        List<CategoryEntity> level3Catalog = getParentCid(selectList, l2.getCatId());
                        if (level3Catalog != null) {
                            List<Catelog2Vo.Catelog3Vo> collect = level3Catalog.stream().map(l3 -> {
                                // 2.封装成指定格式
                                Catelog2Vo.Catelog3Vo catelog3Vo = new Catelog2Vo.Catelog3Vo(l2.getCatId().toString(), l3.getCatId().toString(), l3.getName());
                                return catelog3Vo;
                            }).collect(Collectors.toList());
                            catelog2Vo.setCatalog3List(collect);
                        }
    
                        return catelog2Vo;
                    }).collect(Collectors.toList());
                }
                return catelog2Vos;
            }));
    
            return parentCid;
        }
    
        private List<CategoryEntity> getParentCid(List<CategoryEntity> selectList, Long parentCid) {
            return selectList.stream().filter(item -> {
                return item.getParentCid().equals(parentCid);
            }).collect(Collectors.toList());
        }
    
    • 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

    再次用 jmeter 测试

  • 相关阅读:
    【第六章 final、abstract】
    python中的zip元素在访问后会被自动删除吗?
    python创建虚拟环境及相关配置(windows环境下)
    Docker安装portainer/安装mongodb【亲测有效】
    ClickHouse学习笔记之备份和恢复
    沉睡者IT - 什么是Web3.0?
    idea必装的插件Maven Help(解决依赖冲突)
    【FPGA】FPGA入门 —— 基本开发流程
    前端图片转成base64
    浅谈叉车车载电脑的市场现状
  • 原文地址:https://blog.csdn.net/qq_39007838/article/details/126055007