1、导入前端html等文件
2、导航栏以及菜单实现(与fastvue实现方法相同,查找parent_id为0的分类)
//controller
@GetMapping({"/", "index.html"})
public String getIndex(Model model) {
//获取所有的一级分类
List<CategoryEntity> catagories = categoryService.getLevel1();
model.addAttribute("catagories", catagories);
return "index";
}
//service
public List<CategoryEntity> getLevel1() {
return this.baseMapper.selectList(new QueryWrapper<CategoryEntity>().eq("parent_cid",0));
}
前端thymleaf语句
<li th:each="catagory:${catagories}">
<a href="/static/#" class="header_main_left_a" th:attr="ctg-data=${catagory.catId}">
<b th:text="${catagory.name}">家用电器</b></a>
</li>
3、二级分类实现
后端返回json数据
@GetMapping("index/catalogg")
@ResponseBody
public Map<String, List<Catalog2Vo>> getCategoryMap() {
return categoryService.getCatalogJson();
}
public Map<String, List<Catalog2Vo>> getCatalogJson() {
/**
* 多级查询优化
*将数据库的多次查询变为一次,就是查询全表,将全表放到内存中,剩下的查询在内存中完成
*/
List<CategoryEntity> selectList = baseMapper.selectList(null);
List<CategoryEntity> level1 = getParent_cid(selectList,0l);
Map<String, List<Catalog2Vo>> collect = level1.stream().collect(Collectors.toMap(k -> k.getCatId().toString(), v -> {
//1
List<CategoryEntity> entities = getParent_cid(selectList,v.getCatId());
List<Catalog2Vo> catalog2Vos = entities.stream().map(item -> {
Catalog2Vo catalog2Vo = new Catalog2Vo(v.getCatId().toString(),
item.getCatId().toString(), item.getName(), null);
List<Catalog2Vo.Catalog3Vo> catalog3Vos = getParent_cid(selectList,Long.parseLong(catalog2Vo.getId())).stream().map(v3 -> {
return new Catalog2Vo.Catalog3Vo(catalog2Vo.getId(), v3.getCatId().toString(), v3.getName());
}).collect(Collectors.toList());
catalog2Vo.setCatalog3List(catalog3Vos);
return catalog2Vo;
}).collect(Collectors.toList());
return catalog2Vos;
}));
return collect;}
private List<CategoryEntity> getParent_cid(List<CategoryEntity> selectList,Long parent_cid) {
return selectList.stream().filter(v->v.getParentCid()==parent_cid).collect(Collectors.toList());
}
4、nginx反向代理(在谷粒商城中使用nginx反向代理gateway,然后gateway在路径映射到其他微服务中。查了一些资料,有一点疑问,是不是有了gateway网关就不需要nginx了,因为多了一层中间件,肯定会影响性能)
(1)作用:
1、保护服务安全
-
隐藏服务节点的IP;
-
将服务节点置于防火墙之后,避免直接攻击业务节点服务器。
2、服务节点更专注于业务,同时提升性能
-
由于有反向代理的存在,可以让反向代理服务器去实现比如https、gzip压缩等与业务无关的功能;
-
提供动静态分离,将静态文件发往静态服务器或本地文件系统,避免业务节点处理这些与业务无关的请求;
-
提供缓存机制,将一些短时间内不会变化的动态内容,在反向代理服务器这层增加缓存,降低业务服务器的请求量;
-
由于控制权在代理服务这边,完全可以根据服务节点的性能动态分配请求,做到服务节点性能最佳。
(2)实现反向代理
1、配置域名映射规则(下载switchhosts 将虚拟机地址配置上对用域名)
2、修改 nginx 的根配置文件 nginx.conf,将`upstream`映射到我们的网关服务
upstream gulimall{ server 192.168.56.1:88; }
3、修改 nginx 的 server 块配置文件`gulimall.conf`,将以`/`开头的请求转发至我们 配好的`gulimall`的`upstream`,由于 nginx 的转发会丢失`host`头,所以我们添加头信息
location / { proxy_pass http://gulimall; proxy_set_header Host $host; }
4、配置网关路径映射规则
- id: gulimall_host uri: lb://gulimall-product predicates: - Host=**.gulimall.com
(3)实现动静分类
- 由于动态资源和静态资源目前都处于服务端,所以为了减轻服务器压力,我们将 js、css、 img 等静态资源放置在 Nginx 端,以减轻服务器压力
- 在 nginx 的 html 文件夹创建 staic 文件夹,并将 index/css 等静态资源全部上传到该 文件夹中
- 修改 index.html 的静态资源路径,使其全部带有 static 前缀 `src="/static/index/img/img_09.png"`
- 修改 nginx 的配置文件`/mydata/nginx/conf/conf.d/gulimall.conf` 如果遇到有`/static`为前缀的请求,转发至 html 文件夹
location /static { root /usr/share/nginx/html; }
压力测试:
压力测试 | 压测线程数 | 吞吐量 | 95 | 99 |
nginx | 50 | 3377 | 29 | 78 |
gateway | 50 | 6828 | 17 | 39 |
简单服务 | 50 | 8413 | 11 | 23 |
g+简单服务 | 50 | 2462 | 43 | 105 |
全链路 | 50 | 150 | 1023 | 7079 |
首页 | 50 | 300(db,thymleaf) | 300 | 422 |
二级菜单 | 50 | 2(db) | .。 | 。。 |
首页全内容 | 50 | 15(静态资源 ) | ||
首页开缓存 | 50 | 330 | ||
首页开缓存关日志,优化mysql | 50 | 670 | 167 | 240 |
首页全内容 静态资源放到nginx中 | 50 | 88 | ||
中间件越多,性能损失越大 损失在网络交互中 | ||||
db | mysql优化(加索引) | |||
模板渲染 | cpu,缓存(开启thymeleaf缓存) | |||
二级菜单优化 | *将数据库的多次查询变为一次,就是查询全表,将全 表放到内存中,剩下的查询在内存中完成 |