如果用户所有的请求,都需要Thyleaf渲染后直接返回给用户,后台就存在大量的查询操作,数据库的压力就会骤然上升,请求的时间就会延长,带来极不好用户体验,现在市面上流行的就是页面的静态化处理,下面就来看看,Thymeleaf如何完成页面静态化
一. 什么是静态化?#
静态化就是我们把Thymeleaf渲染后的页面转变成静态页面,并且保存起来,用户每次访问的都是已经存在的静态页,数据库的查询压力也就小了,就比如商品详情页,只要商品的信息没有改变,无论是哪个用户查询的结果都是一样的,所以商品的详情页,完全可以静态化,事实上电商网站也是这样做的
静态化的页面可以保存在nginx,这样做可以提升几个数量级的速度
二 . 如何实现静态化?#
- 回顾一下前后端的交互顺序
- 前端提交请求
- 请求被springMVC收到了,调用持久层查库,把数据放入model
- Thymeleaf把model里面的数据渲染到模板视图里面XXX.html
- 把渲染后的全部信息,全部写入到response里面
其实既然能写到response里面,就能写入到其他路径下,事实上,真的是这样做
- Thymeleaf如何把信息写入到response里?
做这件事的是ThymeleafAutoConfiguration里面的TemplateEngine模板引擎使用下面的方法
process(String template, IContext context, Writer writer)方法
他是如何做的呢?新认识几个概念
1 .Context 上下文
这是块共享的空间,处理用户的请求时,各个servlet可以共享,事实上当我们把数据放入Model ,springMvc就会把model放入Context
- TemplateResolver 模板解析器
@Bean public SpringResourceTemplateResolver defaultTemplateResolver() { SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver(); resolver.setApplicationContext(this.applicationContext); resolver.setPrefix(this.properties.getPrefix()); resolver.setSuffix(this.properties.getSuffix()); resolver.setTemplateMode(this.properties.getMode()); if (this.properties.getEncoding() != null) { resolver.setCharacterEncoding(this.properties.getEncoding().name()); } resolver.setCacheable(this.properties.isCache()); Integer order = this.properties.getTemplateResolverOrder(); if (order != null) { resolver.setOrder(order); } resolver.setCheckExistence(this.properties.isCheckTemplate()); return resolver; }
用来解析和读取配置文件,里面有我们的模拟的后缀以及路径,Thymeleaf的视图解析器依然是依赖它知道的配置信息
有了Context和TemplateResolver万事具备,只差渲染了
TemplateEngine调用process方法,模板引擎依靠context拿到数据,依靠templateResolver拿到配置信息,第三个参数是输出流,也就是我们的目标文件
具体怎么撸?
spring给我们准备好了!
@Autowired TemplateEngine templateEngine; /** * 构建静态化页面 * @param id */ public void createHtml(Long id){ // 1. 上下文 Context context = new Context(); //thymeleaf包下的 // 1.1 存入数据 context.setVariables(loadModel(id)); // 2 输出流 File file = new File("Nginx所在虚拟机下的目标文件", id + ".html"); try(PrintWriter writer = new PrintWriter(file,"UTF-8")){ //流在小括号里面会被自动的释放 //生成HTML templateEngine.process("1",context,writer); }catch (Exception e){ log.error("静态页方法异常"+e); } }
Nginx出场#
nginx的代理静态页面
server { listen 80; server_name www.XXX.com; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; location /item { # 先找本地找root这个文件夹 root html; if (!-f $request_filename) { #请求的文件不存在,就反向代理 request_filename是nginx的内置变量, 值是前段传递过来的id.html proxy_pass http://127.0.0.1:8084; break; } } location / { proxy_pass http://127.0.0.1:9002; proxy_connect_timeout 600; proxy_read_timeout 600; } }
Rabbit出场#
使用Rabbit消息队列,可以第一时间了解什么啥时候更新静态页,啥时候创建新的静态页