从构建分布式秒杀系统聊聊商品详情页静态化

307 阅读3分钟
原文链接: mp.weixin.qq.com

前言

大家都知道淘宝、天猫、京东以及聚美之类的电商网站,她们的商品页会存在多套模板,各套模板的元数据是一样的,只是展示方式不一样。特别是对于店主而言商品详情页个性化需求非常多,就商品单页各个维度信息来说,数据来源也是非常多的。这时候,如果我们再实时的去查询各个数据源组织数据,对于数据库来说开销是巨大的,秒杀更是如此。

静态化

在这里我们就做一个简单商品详情页静态页生成,大家工作中根据实际情况做调整优化。后面如果大家对商品详情页架构感兴趣,可以去了解下《亿级流量网站架构核心技术》书中的如何构建需求响应式亿级商品详情页,毕竟前人栽树后人乘凉,里面还是有很多大家可以借鉴的地方。

我们选用freemarker做模板,pom.xml引入:

  1. <!-- freemarker 模版 生成静态页 -->

  2. <dependency>

  3.    <groupId>org.springframework.boot</groupId>

  4.    <artifactId>spring-boot-starter-freemarker</artifactId>

  5. </dependency>

application.properties配置相关参数:

  1. #freemarker(用于商品静态页生成简化版)

  2. spring.freemarker.template-loader-path=classpath:/static/template/

  3. spring.freemarker.suffix=.flt

  4. spring.freemarker.enabled=true

  5. spring.freemarker.cache=false

  6. spring.freemarker.charset=UTF-8

  7. spring.freemarker.content-type=text/html

  8. spring.freemarker.allow-request-override=false

  9. spring.freemarker.check-template-location=true

  10. spring.freemarker.expose-request-attributes=false

  11. spring.freemarker.expose-session-attributes=false

  12. spring.freemarker.expose-spring-macro-helpers=false

  13. #商品静态页

  14. spring.freemarker.html.path = D://file//

goods.flt定义商品单页模板:

  1. # 模板太大了,这里不做展示,请自行参考源码

  2. static/template/goods.flt

ICreateHtmlService静态化接口:

  1. /**

  2. * 生成商品静态页

  3. * 创建者  小柒2012

  4. */

  5. public interface ICreateHtmlService {

  6.    Result createAllHtml();

  7. }

CreateHtmlServiceImpl静态化实现:

  1. @Service

  2. public class CreateHtmlServiceImpl implements ICreateHtmlService {

  3.    private static int corePoolSize = Runtime.getRuntime().availableProcessors();

  4.    //多线程生成静态页面

  5.    private static ThreadPoolExecutor executor  = new ThreadPoolExecutor(corePoolSize, corePoolSize+1, 10l, TimeUnit.SECONDS,

  6.            new LinkedBlockingQueue<Runnable>(1000));

  7.    @Autowired

  8.    public Configuration configuration;

  9.    @Autowired

  10.    private SeckillRepository seckillRepository;

  11.    @Value("${spring.freemarker.html.path}")

  12.    private String path;

  13.    @Override

  14.    public Result createAllHtml() {

  15.        List<Seckill> list = seckillRepository.findAll();

  16.        final List<Future<String>> resultList = new ArrayList<Future<String>>();

  17.        for(Seckill seckill:list){

  18.            resultList.add(executor.submit(new createhtml(seckill)));

  19.        }

  20.       for (Future<String> fs : resultList) {

  21.           try {

  22.                System.out.println(fs.get());//打印各个线任务执行的结果,调用future.get() 阻塞主线程,获取异步任务的返回结果

  23.            } catch (InterruptedException e) {

  24.                e.printStackTrace();

  25.            } catch (ExecutionException e) {

  26.                e.printStackTrace();

  27.            }

  28.       }

  29.        return Result.ok();

  30.    }

  31.    class createhtml implements Callable<String>  {

  32.        Seckill seckill;

  33.        public createhtml(Seckill seckill) {

  34.            this.seckill = seckill;

  35.        }

  36.        @Override

  37.        public String call() throws Exception {

  38.            Template template = configuration.getTemplate("goods.flt");

  39.            File file= new File(path+seckill.getSeckillId()+".html");

  40.            Writer  writer = new OutputStreamWriter(new FileOutputStream(file), "UTF-8");

  41.            template.process(seckill, writer);

  42.            return "success";

  43.        }

  44.    }

  45. }

最后通过swagger-ui页面执行以下生成商品页操作,不出意外目录下会生成四个商品页面,打开如下图所示:

思考

  • 为什么要构建静态商品页,说出你的理由?

  • Nginx处理静态页的速度为什么会优于Tomcat?

  • 多维度的商品页,单个维度的变动如何不影响全局?

文章推荐

1

SpringBoot开发案例构建分布式日志处理系统

2

SpringBoot开发案例从0到1构建分布式秒杀系统

3

JavaWeb在线租车服务系统项目源码(福利)

4

JavaWeb天下陶网络商城SSH项目源码(福利)

5

公司内网搭建代理DNS使用内网域名代替ip地址