栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Day410&411.商品系统首页 -谷粒商城

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Day410&411.商品系统首页 -谷粒商城

二、商城系统首页

不使用前后端分离开发了,管理后台用vue nginx发给网关集群,网关再路由到微服务

静态资源放到nginx中

  • 依赖

导入thymeleaf依赖、热部署依赖devtools使页面实时生效

achangmall-product/pom.xml


    org.springframework.boot
    spring-boot-devtools
    true


    org.springframework.boot
    spring-boot-starter-thymeleaf

html首页资源index放到achangmall-product下的static文件夹

把index.html放到templates中

  • 关闭thymeleaf缓存,方便开发实时看到更新
  thymeleaf:
    cache: false
    suffix: .html
    prefix: classpath:/templates/
  • web开发放到web包下,原来的controller是前后分离对接手机等访问的,所以可以改成app,对接app应用

com.achang.achangmall.product.web【存放专门用于页面跳转的controller】

com.achang.achangmall.product.app【存放前后端奶粉里的rest风格接口controller】

  • 渲染一级分类菜单 刚导入index.html时,里面的分类菜单都是写死的,我们要访问数据库拿到放到model中,然后在页面foreach填入
@Controller
public class IndexController {

    @Autowired
    private CategoryService categoryService;

    //进入商品首页
    @GetMapping({"/","/index.html"})
    public String indexPage(Model model){
        //查出一级分类
        List categoryEntityList = categoryService.getLevel1Categorys();
		
        //放入域中
        model.addAttribute("categorys",categoryEntityList);
        return "index";
    }

}
@Override
public List getLevel1Categorys() {
    //查询一级分类
    return baseMapper.selectList(new QueryWrapper().eq("cat_level",1));
}
  • 页面引入thymeleft名称空间

xmlns:th="http://www.thymeleaf.org"
  • 因为我们上面引用了热部署的pom

更新页面后,在当前页面按Ctrl+Shift+F9,进行刷新热部署页面

  • 页面遍历菜单数据
  • 家用电器111
    • 渲染三级分类菜单

    com.achang.achangmall.product.vo.Catelog2Vo

    //二级分类vo
    @NoArgsConstructor
    @AllArgsConstructor
    @Data
    public class Catelog2Vo {
        private String catalog1Id; //一级父分类id
        private List catalog3List; //三级子分类
        private String id;//二级分类id
        private String name;
    
        //三级分类vo 静态内部类
        @NoArgsConstructor
        @AllArgsConstructor
        @Data
        public static class Catelog3Vo{
            private String catalog2Id;//二级分类id
            private String id;//三级分类id
            private String name;
        }
    }
    

    com.achang.achangmall.product.web.IndexController

        //index/catalog.json
        @ResponseBody
        @GetMapping("/index/catalog.json")
        public Map>  getCatalogJson(){
            Map>  resultMap = categoryService.getCatelogJson();
            return resultMap;
        }
    

    com.achang.achangmall.product.service.impl.CategoryServiceImpl

    @Override
    public Map>  getCatelogJson() {
        //查出所有分类
        List level1Categorys = getLevel1Categorys();
        //分装数据
        Map> resultMap = level1Categorys.stream().collect(Collectors.toMap(CategoryEntity::getCatId, v -> {
            //每一个的一级分类,查到这个一级分类的二级分类
            List list = baseMapper.selectList(new QueryWrapper().eq("parent_cid", v.getCatId()));
            List catelog2VoList = null;
            if (!StringUtils.isEmpty(list)) {
                catelog2VoList = list.stream().map(item -> {
                    Catelog2Vo catelog2Vo = new Catelog2Vo(v.getCatId().toString(), null, item.getCatId().toString(), item.getName());
                    //封装二级分类的三级分类
                    List entityList = baseMapper.selectList(new QueryWrapper().eq("parent_cid", item.getCatId()));
                    if (!StringUtils.isEmpty(entityList)){
                        List catelog3Vos = entityList.stream().map(m -> {
                            Catelog2Vo.Catelog3Vo catelog3Vo = new Catelog2Vo.Catelog3Vo(item.getCatId().toString(),m.getCatId().toString(),m.getName());
                            return catelog3Vo;
                        }).collect(Collectors.toList());
                        catelog2Vo.setCatalog3List(catelog3Vos);
                    }
    
    
                    return catelog2Vo;
                }).collect(Collectors.toList());
                return catelog2VoList;
            }
            return catelog2VoList;
        }));
    
        return resultMap;
    
    }
    

    1、Nginx配置文件

    • 新增本地DNS映射

    C:WindowsSystem32driversetchosts

    192.168.109.101 achangmall.com
    

    测试访问之前的9200端口

    • nginx配置文件

    	server {
        listen       80;
        server_name  achangmall.com;
    
        #charset koi8-r;
        #access_log  /var/log/nginx/log/host.access.log  main;
    
        location / {
            #又转回到本机
            proxy_pass http://192.168.153.1:10000;
        }
    
    		#error_page  404              /404.html;
    
    		# redirect server error pages to the static page /50x.html
    		#
    		error_page   500 502 503 504  /50x.html;
    		location = /50x.html {
    			root   /usr/share/nginx/html;
    		}
    
    		# proxy the PHP scripts to Apache listening on 127.0.0.1:80
    		#
    		#location ~ .php$ {
    		#    proxy_pass   http://127.0.0.1;
    		#}
    
    		# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    		#
    		#location ~ .php$ {
    		#    root           html;
    		#    fastcgi_pass   127.0.0.1:9000;
    		#    fastcgi_index  index.php;
    		#    fastcgi_param  script_FILENAME  /scripts$fastcgi_script_name;
    		#    include        fastcgi_params;
    		#}
    
    		# deny access to .htaccess files, if Apache's document root
    		# concurs with nginx's one
    		#
    		#location ~ /.ht {
    		#    deny  all;
    		#}
    	}
    
    • 测试访问http://achangmall.com/


    2、Nginx+网关

    • nginx配置
    upstream achangmall{
           server 192.168.153.1:88;
        }
    
    location / {
            #又转回到本机
            # proxy_pass http://192.168.153.1:10000;
           proxy_pass http://achangmall;
        }
    
    • 但是我们测试访问http://achangmall.com/

    nginx转发会丢失掉host中的信息

    • 设置nginx在转发的时候保留host信息

    proxy_set_header Host $host;
    
    • 再次测试访问,http://achangmall.com,测试成功

    • 将nginx路由的网关配置放置在yaml配置最后

    • 最终转发流程


    3、 压力测试
    • Jmeter下载:https://jmeter.apache.org/download_jmeter.cgi

    创建测试计划,添加线程组

    线程数==用户

    ramp-up 多长时间内发送完

    添加-取样器-HTTP请求

    添加-监听器-查看结果树

    添加-监听器-汇总报告

    • 优化

    SQL耗时越小越好,一般情况下微秒级别

    命中率越高越好,一般情况下不能低于95%

    锁等待次数越低越好,等待时间越短越好

    中间件越多,性能损失越大,大多都损失在网络交互


    4、Nginx动静分离

    由于动态资源和静态资源目前都处于服务端,所以为了减轻服务器压力,我们将 js、css、img等静态资源放置在Nginx端,以减轻服务器压力

    • 项目静态资源搬家

    静态文件上传到 mydata/nginx/html/static/index/css,这种格式

    mkdir static
    

    修改index.html的静态资源路径,加上static前缀src="/static/index/img/img_09.png"

    等等等,给index.html页面中的路径都加上/static/

    修改/mydata/nginx/conf/conf.d/gulimall.conf

    如果遇到有/static为前缀的请求,转发至html文件夹

     location /static/ {
         root   /usr/share/nginx/html;
     }
    

    再次测试访问achangmall.com,成功将静态资源由nginx返回


    5、优化三级分类查询

    之前是循环查询数据库,导致有多少跟数据库进行io交互;

    这里我们减少数据库的交互,一次性查询所有的数据,减少io资源消耗

    com.achang.achangmall.product.service.impl.CategoryServiceImpl

    @Override
    public Map>  getCatelogJson() {
    
        //将数据库的多次交互,转为一次,一次性查询所有数据
        List allList = baseMapper.selectList(null);
    
        //查出所有分类
        List level1Categorys = getParent_cid(allList,0L);
        //分装数据
        Map> resultMap = level1Categorys.stream().collect(Collectors.toMap(CategoryEntity::getCatId, v -> {
            //每一个的一级分类,查到这个一级分类的二级分类
            List list = getParent_cid(allList,v.getCatId());
            List catelog2VoList = null;
            if (!StringUtils.isEmpty(list)) {
                catelog2VoList = list.stream().map(item -> {
                    Catelog2Vo catelog2Vo = new Catelog2Vo(v.getCatId().toString(), null, item.getCatId().toString(), item.getName());
                    //封装二级分类的三级分类
                    List entityList = getParent_cid(allList,item.getCatId());
                    if (!StringUtils.isEmpty(entityList)){
                        List catelog3Vos = entityList.stream().map(m -> {
                            Catelog2Vo.Catelog3Vo catelog3Vo = new Catelog2Vo.Catelog3Vo(item.getCatId().toString(),m.getCatId().toString(),m.getName());
                            return catelog3Vo;
                        }).collect(Collectors.toList());
                        catelog2Vo.setCatalog3List(catelog3Vos);
                    }
    
    
                    return catelog2Vo;
                }).collect(Collectors.toList());
                return catelog2VoList;
            }
            return catelog2VoList;
        }));
    
        return resultMap;
    
    }
    
    private List getParent_cid(List allList,Long parent_cid) {
        List collect = allList.stream().filter(item -> {
            return item.getParentCid().equals(parent_cid);
        }).collect(Collectors.toList());
        return collect;
        //        return baseMapper.selectList(new QueryWrapper().eq("parent_cid", v.getCatId()));
    }
    
    转载请注明:文章转载自 www.mshxw.com
    本文地址:https://www.mshxw.com/it/294203.html
    我们一直用心在做
    关于我们 文章归档 网站地图 联系我们

    版权所有 (c)2021-2022 MSHXW.COM

    ICP备案号:晋ICP备2021003244-6号