1.   学习计划

  1、商品详情页面展示,动态展示 jsp + redis

  2、使用freemarker实现网页静态化

  3、ActiveMq同步生成静态网页

  两个方案对比,方案一依赖web容器,redis的引入确实是减轻了数据库的压力,却也有明显的不足,撇开缓存的上限不说,方案一中web容器还是会去编辑和解析jsp页面,从缓存中拿数据,生成html返回给客户端;而方案二完全脱离web容器,不仅减轻了数据库的压力,也减轻了web容器的压力,性能更加优越。

下面分别演示这两种解决方案。这里对搭建工程进行了精简,主要是关注两种方案的网页静态化操作。

2. jsp + redis解决方案

使用redis做缓存,向业务逻辑中添加缓存,减轻数据库的访问压力,可以在一定程度上提高系统的吞吐量。

2.1. 向业务逻辑中添加缓存

2.1.1.    缓存添加分析

使用redis做缓存。

业务逻辑:

1、根据商品id到缓存中命中

2、查到缓存,直接返回。

3、差不到,查询数据库

4、把数据放到缓存中

5、返回数据

缓存中缓存热点数据,提供缓存的使用率。需要设置缓存的有效期。一般是一天的时间,可以根据实际情况跳转。

2.1.2 前缀分割

需要使用String类型来保存商品数据。

可以加前缀方法对象redis中的key进行归类

ITEM_INFO:123456:BASE

ITEM_INFO:123456:DESC

如果把二维表保存到redis中:

1、表名就是第一层

2、主键是第二层

3、字段名第三次

三层使用“:”分隔作为key,value就是字段中的内容。

2.1.3.    添加缓存

商品添加缓存

@Override

      public TbItem getItemById(long itemId) {

           try {

                 //查询缓存

                 String json = jedisClient.get(ITEM_INFO_PRE + ":" + itemId + ":BASE");

                 if (StringUtils.isNotBlank(json)) {

                      //把json转换为java对象

TbItem item = JsonUtils.jsonToPojo(json, TbItem.class);
return item; } } catch (Exception e) { e.printStackTrace(); } //根据商品id查询商品信息 //TbItem tbItem = itemMapper.selectByPrimaryKey(itemId); TbItemExample example = new TbItemExample(); //设置查询条件 Criteria criteria = example.createCriteria(); criteria.andIdEqualTo(itemId); List<TbItem> list = itemMapper.selectByExample(example); if (list != null && list.size() > 0) { TbItem item = list.get(0); try { //把数据保存到缓存

jedisClient.set(ITEM_INFO_PRE + ":" + itemId + ":BASE"
, JsonUtils.objectToJson(item)); //设置缓存的有效期 jedisClient.expire(ITEM_INFO_PRE + ":" + itemId + ":BASE", ITEM_INFO_EXPIRE); } catch (Exception e) { e.printStackTrace(); } return item; } return null; }

取商品描述添加缓存:

@Override

     public TbItemDesc getItemDescById(long itemId) {

         try {

              String json = jedisClient.get(ITEM_INFO_PRE + ":" + itemId + ":DESC");

              //判断缓存是否命中

              if (StringUtils.isNotBlank(json) ) {

                   //转换为java对象

TbItemDesc itemDesc = JsonUtils.jsonToPojo(json, TbItemDesc.class
); return itemDesc; } } catch (Exception e) { e.printStackTrace(); } TbItemDesc itemDesc = itemDescMapper.selectByPrimaryKey(itemId); try { jedisClient.set(ITEM_INFO_PRE + ":" + itemId + ":DESC", JsonUtils.objectToJson(itemDesc)); //设置过期时间

jedisClient.expire(ITEM_INFO_PRE + ":" + itemId + ":DESC"
, ITEM_INFO_EXPIRE); } catch (Exception e) { e.printStackTrace(); } return itemDesc; }

3.   网页静态化

可以使用Freemarker实现网页静态化。

3.0. Freemarker的jar包

把freemarker的jar包添加到工程中。

Maven工程添加依赖

<dependency>

  <groupId>org.freemarker</groupId>

  <artifactId>freemarker</artifactId>

  <version>2.3.23</version>

</dependency>

3.1. 什么是freemarker

FreeMarker是一个用Java语言编写的模板引擎,它基于模板来生成文本输出。FreeMarker与Web容器无关,即在Web运行时,它并不知道Servlet或HTTP。它不仅可以用作表现层的实现技术,而且还可以用于生成XML,JSP或Java 等。

目前企业中:主要用Freemarker做静态页面或是页面展示

3.1.1. 原理:

3.1.2. 模板:

任意一个文本文件,都可以作为模板,模板文件的扩展名一般是ftl,freemarker根据提供的模板,将模板中对应的标记(可以看做key),填充为相应的数据,freemarker不仅仅可以生成静态的html文件,只要给定合适的模板个数据可以生成任何的文本文件。

3.2. freemarker使用步骤:

第一步:创建一个Configuration对象,直接new一个对象。构造方法的参数就是freemarker对于的版本号。

第二步:设置模板文件所在的路径

第三步:设置模板文件使用的字符集。一般就是utf-8.

第四步:加载一个模板,创建一个模板对象。

第五步:创建一个模板使用的数据集,可以是pojo也可以是map。一般是Map

第六步:创建一个Writer对象,一般创建一FileWriter对象,指定生成的文件名。

第七步:调用模板对象的process方法输出文件。

第八步:关闭流

如下面一个简单的例子。

模本文件:

  hello.ftl

内容:

  ${hello}

如下是freemarker加载模板并生成对应html文件。

@Test

     public void genFile() throws Exception {

         // 第一步:创建一个Configuration对象,直接new一个对象。构造方法的参数就是freemarker对于的版本号。

         Configuration configuration = new Configuration(Configuration.getVersion());

         // 第二步:设置模板文件所在的路径。

         configuration.setDirectoryForTemplateLoading(new File("D:/workspaces-itcast/term197/taotao-item-web/src/main/webapp/WEB-INF/ftl"));

         // 第三步:设置模板文件使用的字符集。一般就是utf-8.

         configuration.setDefaultEncoding("utf-8");

         // 第四步:加载一个模板,创建一个模板对象。

         Template template = configuration.getTemplate("hello.ftl");

         // 第五步:创建一个模板使用的数据集,可以是pojo也可以是map。一般是Map。

         Map dataModel = new HashMap<>();

         //向数据集中添加数据

         dataModel.put("hello", "this is my first freemarker test.");

         // 第六步:创建一个Writer对象,一般创建一FileWriter对象,指定生成的文件名。

         Writer out = new FileWriter(new File("D:/temp/term197/out/hello.html"));

         // 第七步:调用模板对象的process方法输出文件。

         template.process(dataModel, out);

         // 第八步:关闭流。

         out.close();

     }

3.3. 模板的语法

3.3.1.    访问map中的key

${key}

3.3.2.    访问pojo中的属性

Student对象。学号、姓名、年龄

${key.property}

3.3.3.    取集合中的数据

<#list studentList as student>

${student.id}/${studnet.name}

</#list>

循环使用格式:

<#list 要循环的数据 as 循环后的数据>

</#list>

3.3.4.    取循环中的下标

<#list studentList as student>

       ${student_index}

</#list>

3.3.5.    判断

<#if student_index % 2 == >

<#else>

</#if>

3.3.6.    日期类型格式化

直接取值:${date}(date是属性名)如果传来的是一个Date型数据会报错

${date?date} 2016-9-13

${date?time} 17:53:55

${date?datetime} 2016-9-13 17:53:55

3.3.7.    Null值的处理

如果直接取一个不存在的值(值为null)时会报异常

${aaa}

处理: ${aaa!”默认值”}或者${aaa! }代表空字符串

3.3.8.    Include标签

<#include “模板名称”>

(相当于jstl中的包含)

3.4. Freemarker整合spring

引入jar包:

Freemarker的jar包

3.4.1.    创建整合spring的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="freemarkerConfig"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/ftl/" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
</beans>

需要编写一Controller进行测试

3.4.2.    Controller

请求的url:/genhtml

参数:无

返回值:ok (String, 需要使用@ResponseBody)

业务逻辑:

1、从spring容器中获得FreeMarkerConfigurer对象。

2、从FreeMarkerConfigurer对象中获得Configuration对象。

3、使用Configuration对象获得Template对象。

4、创建数据集

5、创建输出文件的Writer对象。

6、调用模板对象的process方法,生成文件。

7、关闭流。

加载配置文件:

@Controller
public class HtmlGenController { @Autowired
private FreeMarkerConfigurer freeMarkerConfigurer; @RequestMapping("/genhtml")
@ResponseBody
public String genHtml()throws Exception {
// 1、从spring容器中获得FreeMarkerConfigurer对象。
// 2、从FreeMarkerConfigurer对象中获得Configuration对象。
Configuration configuration = freeMarkerConfigurer.getConfiguration();
// 3、使用Configuration对象获得Template对象。
Template template = configuration.getTemplate("hello.ftl");
// 4、创建数据集
Map dataModel = new HashMap<>();
dataModel.put("hello", "1000");
// 5、创建输出文件的Writer对象。
Writer out = new FileWriter(new File("D:/temp/term197/out/spring-freemarker.html"));
// 6、调用模板对象的process方法,生成文件。
template.process(dataModel, out);
// 7、关闭流。
out.close();
return "OK";
}
}

3.5. 商品详情页面静态化

3.5.1.    网页的静态化方案

输出文件的名称商品id+“.html”

输出文件的路径:工程外部的任意目录。

网页访问:使用nginx访问网页。在此方案下tomcat只有一个作用就是生成静态页面。

工程部署:可以把taotao-item-web部署到多个服务器上。

生成静态页面的时机:商品添加后,生成静态页面。可以使用Activemq,订阅topic(商品添加)

集群环境下,多台服务器提供服务,必须配置一台反向代理服务器,面向用户,对用户的请求进行转发,并提供负载均衡。在这里,http服务器(访问静态资源)和反向代理服务器都是Nginx。

4. 内容总结:

商品详情模块实现

通过solr全文搜索找到商品;通过商品id去redis中找当前id的缓存,找不到去数据库中查找并添加到缓存中;

(为了提高redis的高可用,把不常访问的商品从redis缓存中清除:使用定时)

每次点击都会把key的时间重置,当key在他的生命中没有被点击就会从redis中清除,再次访问时再次添加

两方面影响用户访问速度:

数据库查询

使用缓存

服务器生成html页面

使用freemaker生成静态页面

Freemaker生成静态页面的时机

添加商品后使用activemq广播消息,freemaker监听到消息去数据库查询商品生成静态页面

为什么不去redis中获取商品信息,添加商品时还没有存到redis中

为什么不直接使用商品信息还要到数据库中查询:不在一个项目中传输数据麻烦,也起不到提高效率的作用;而且修改数据时也要修改静态页面

Redis存储数据库表信息;

Key:  表名:id:字段

Value:  字段值

两种方案:

一 redis缓存

二 网页静态化

网页静态化—redis | freemarker的更多相关文章

  1. 网页静态化技术Freemarker的详细介绍

    网页静态化技术Freemarker 一.Freemarker的基本介绍 1.1为什么要使用网页静态化技术 网页静态化解决方案在实际开发中运用比较多,例如新闻网站,门户网站中的新闻频道或者是文章类的频道 ...

  2. 网页静态化解决方案-Freemarker demo+语法

    1.网页静态化技术Freemarker 1.1为什么要使用网页静态化技术 网页静态化解决方案在实际开发中运用比较多,例如新闻网站,门户网站中的新闻频道或者是文章类的频道. 对于电商网站的商品详细页来说 ...

  3. 网页静态化技术--Freemarker入门

    网页静态化技术:为什么要使用网页静态化技术 网页静态化解决方案在实际开发中运用比较多,例如新闻网站,门户网站中的新闻频道或者是文章类的频道. 对于电商网站的商品详细页来说,至少几百万个商品,每个商品又 ...

  4. 网页静态化解决方案-Freemarker

    1.1    技术简介与使用 1.1.1     简介 为什么使用: 1.  减轻数据库的访问压力,静态化比较适合大规模且相对变化不太频繁的数据: 2.  有利于SEO(搜索引擎优化); 纯的HTML ...

  5. 网页静态化技术Freemarker

    1.为什么要使用网页静态化技术 网页静态化解决方案在实际开发中运用比较多,例如新闻网站,门户网站中的新闻频道或者是文章类的频道. 对于电商网站的商品详细页来说,至少几百万个商品,每个商品又有大量的信息 ...

  6. 网页静态化解决方案Freemarker

    序言: 沉淀了三个月,逐步将自己最近两年在公司中用到的技术和知识点,重新整理归纳了下,对比以前可以发现,现在技术更新越来越快,也越来越成熟,在互联网企业,用到的技术也更先进,更领先,比如微服务.分布式 ...

  7. JAVAEE——宜立方商城10:使用freemarker实现网页静态化、ActiveMq同步生成静态网页、Sso单点登录系统分析

    1. 学习计划 1.使用freemarker实现网页静态化 2.ActiveMq同步生成静态网页 2. 网页静态化 可以使用Freemarker实现网页静态化. 2.1. 什么是freemarker ...

  8. 网页静态化技术Freemarkerh简介

    1.1为什么要使用网页静态化技术 网页静态化解决方案在实际开发中运用比较多,例如新闻网站,门户网站中的新闻频道或者是文章类的频道. 对于电商网站的商品详细页来说,至少几百万个商品,每个商品又有大量的信 ...

  9. 【转】使用Freemarker实现网页静态化

    使用Freemarker实现网页静态化 2017年08月20日 20:45:51 阅读数:1981 1.1. 什么是freemarker FreeMarker是一个用Java语言编写的模板引擎,它基于 ...

随机推荐

  1. Serf 了解

    Introduction to Serf Welcome to the intro guide to Serf! This guide will show you what Serf is, expl ...

  2. jsp_include

    jsp__include指令先包含后编译 include 行为 先编译后包含 <jsp:include page="head.jsp"></jsp:include ...

  3. 用vs2010编译vs2013建的工程

    第一步,用文本打开,修改.sln文件 原始: Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2 ...

  4. Centos6.8 安装MySql

        启动Centos6.8   输入命令: yum install mysql mysql-server -y 等待安装完成. 启动MySQL,输入命令: /etc/init.d/mysqld s ...

  5. sourceTree 添加 ssh key 方法【转】

    1.使用 git 客户的生成公私钥:id_rsa.id_rsa.pub 1.1设置Git的user name和email: $ git config --global user.name " ...

  6. Proxool抛出的警告 was active for 365172 milliseconds and has been removed automaticaly

    WARN cetDB:149 - #0005 was active for 365172 milliseconds and has been removed automaticaly. The Thr ...

  7. Renesas 符号地址空间对齐

    对齐方式定义头文件:bsp_compiler_support.h #define BSP_SECTION_STACK ".stack" #define BSP_SECTION_HE ...

  8. java代码-------Runnable的用法

    总结:主要是实现Runnable接口就必须重写run()方法,然后需要创建Thread类的对象,再调用start()方法 package com.s.x; public class testRunna ...

  9. NGUI中LabelA停靠LabelB的方法

    详情看 http://note.youdao.com/noteshare?id=ec901d56341207052b2d19233b5ddba3 这里仅仅贴出文字,完整内容请看上面链接. 有这样一个需 ...

  10. 01:Sysbench 基准压测 IO篇

    line:V1.1 mail: gczheng@139.com date: 2017-11-17 一.Sysench测试前准备 1.1.压测环境 配置 信息 主机 Dell PowerEdge R73 ...