一、简介
1.什么是页面静态化?
静态化是指把动态生成的HTML页面变成静态内容来保存,之后用户的请求到来,直接访问静态页面,不再经过服务的渲染。静态的HTML页面时可以部署在nginx中,从而极大地提高并发访问能力,减小tomcat压力。
2.如何实现静态化?
静态化页面都是通过模板引擎来生成的,而后保存到nginx服务器部署,常用的模板引擎有:
- Freemarker
- Velocity
- Thymeleaf
本文将使用Thymeleaf模板引擎。Thymeleaf除了可以把渲染结果写入Response,也可以写到本地文件,从而实现静态化。
二、实现静态化
1. ThymeLeaf概念
- Context:运行上下文
- TemplateResolver:模板解析器
- TemplateEngine:模板引擎
Context
上下文: 用来保存模型数据,当模板引擎渲染时,可以从Context上下文中获取数据用于渲染。
当与SpringBoot结合使用时,我们放入Model的数据就会被处理到Context,作为模板渲染的数据使用。
TemplateResolver
模板解析器:用来读取模板相关的配置,例如:模板存放的位置信息,模板文件名称,模板文件的类型等等。
当与SpringBoot结合时,TemplateResolver已经由其创建完成,并且各种配置也都有默认值,比如模板存放位置,其默认值就是:templates。比如模板文件类型,其默认值就是html。
TemplateEngine
模板引擎:用来解析模板的引擎,需要使用到上下文、模板解析器。分别从两者中获取模板中需要的数据,模板文件。然后利用内置的语法规则解析,从而输出解析后的文件。来看下模板引擎进行处理的函数:
templateEngine.process("模板名", context, writer);
三个参数:
- 模板名称
- 上下文:里面包含模型数据
- writer:输出目的地的流
在输出时,我们可以指定输出的目的地,如果目的地是Response的流,那就是网络响应。如果目的地是本地文件,那就实现静态化了。
而在SpringBoot中已经自动配置了模板引擎,因此我们不需要关心这个。现在我们做静态化,就是把输出的目的地改成本地文件即可!
2.代码实现
@Override
public void createHTML(Long spuId) {
PrintWriter printWriter = null;
try {
// 1.获取页面的数据
Map<String, Object> data = this.loadData(spuId);
Context thymeLeafContext = new Context();
// 2.将数据放入上下文
thymeLeafContext.setVariables(data);
// 3.创建文件,输出
File file = new File("F:\\Java\\nginx-1.14.0\\html\\item" + spuId + ".html");
printWriter = new PrintWriter(file);
// 4.执行页面静态化
templateEngine.process("item", thymeLeafContext, printWriter);
} catch (Exception e) {
LOGGER.error("页面静态化出错:{},"+ e, spuId);
} finally {
if (printWriter != null) {
printWriter.close();
}
}
我们直接将处理完的静态静态页面保存到nginx服务器的html
目录下,使用完printWriter
要记得将其关闭。
当我们在保存静态页面的使用,为了避免io阻塞,我们可以使用多线程来解决这个问题。
/**
* 新建线程处理页面静态化
* @param spuId
*/
public void asyncExecute(Long spuId) {
ThreadUtils.execute(()->createHTML(spuId));
}
ThreadUtils类如下:
package com.youmei.goods.web.util;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadUtils {
private static final ExecutorService es = Executors.newFixedThreadPool(10);
public static void execute(Runnable runnable) {
es.submit(runnable);
}
}
3. nginx配置路由规则
我们可以对指定路径的请求进行监听,直接路由到本地静态页面,如果本地没找到文件,再反向代理。
location /item {
# 先找本地html文件夹下面
root html;
if (!-f $request_filename) { #请求的文件不存在,就反向代理
proxy_pass http://127.0.0.1:8084;
break;
}
}
三、总结
页面静态化代码我们实现了,当前台第一次调用到后端的接口的时候,我们就可以去创建静态页面了。之后如果再访问,nginx服务器会直接路由到硬盘上的静态页面。