thymleaf静态化+rabbitmq

页面加载方案:

方案一

1.统一跳转到静态页面,然后通过异步加载数据,渲染页面

  • 优点:

 异步加载数据,用户体验好

  • 缺点:

会向服务器发起多次请求,增加服务器压力。

 

方案二

2.将请求交给tomcat,由后台渲染,给不同商品生成页面,并返回给用户

优:后台处理一次数据返回,用户得到的是最终数据,不在继续发生请求

缺:服务器要处理页面,服务器压力大,tomcat并发能力差

 

 

背景:商品详情页使用户访问较多的页面。特别是在秒杀的场景中,用户不断地请求商品详情页,不管采用俩种中的那种,服务器压力都很大

解决:俩者结合地方式

thymleaf生成静态页,并保存下来,下次访问就直去请求静态页

thymleaf中的概念:

Contex:上下文

templateResolver:模板解析器

TemplateEngin:模板引擎

 

上下文: 用来保存模型数据,当模板引擎渲染时,可以从Context上下文中获取数据用于渲染。
当与SpringBoot结合使用时,我们放入Model的数据就会被处理到Context,作为模板渲染的数据使用。

 

模板解析器:用来读取模板相关的配置,例如:模板存放的位置信息,模板文件名称,模板文件的类型等等。
当与SpringBoot结合时,TemplateResolver已经由其创建完成,并且各种配置也都有默认值,比如模板存放位置,其默认值就是:templates。比如模板文件类型,其默认值就是html。

 

模板引擎:用来解析模板的引擎,需要使用到上下文、模板解析器。分别从两者中获取模板中需要的数据,模板文件。然后利用内置的语法规则解析,从而输出解析后的文件。来看下模板引擎进行处理的函数:

templateEngine.process("模板名", context, writer); 

三个参数:

模板名称

上下文:里面包含模型数据

writer:输出目的地的流

在输出时,我们可以指定输出的目的地,如果目的地是Response的流,那就是网络响应。如果目的地是本地文件,那就实现静态化了。
而在SpringBoot中已经自动配置了模板引擎,因此我们不需要关心这个。现在我们做静态化,就是把输出的目的地改成本地文件即可!

代码:

@Service
public class PageServiceImpl implements PageService {

    @Autowired
    private BrandClient brandClient;

    @Autowired
    private CategoryClient categoryClient ;

    @Autowired
    private GoodsClient goodsClient;

    @Autowired
    private SpecificationClient specificationClient;

    //模板引擎
    @Autowired
    private TemplateEngine templateEngine;

    private final Logger log= LoggerFactory.getLogger(PageServiceImpl.class);

    @Override
    public Map<String, Object> loadModel(Long id) {

        Map<String, Object> model = new HashMap<>();

        Spu spu = goodsClient.querySpuById(id);
        List<Sku> skus = spu.getSkus();
        SpuDetail spuDetail = spu.getSpuDetail();
        Brand brand = brandClient.queryBrandById(spu.getBrandId());
        List<Category> categoryList = categoryClient.queryCategoryByIds(Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3()));
        List<SpecGroup> specs = specificationClient.queryListByCid(spu.getCid3());

        //model.put("spu", spu);//不需要spu这么多数据
        model.put("title", spu.getTitle());
        model.put("subTitle", spu.getSubTitle());
        model.put("categories", categoryList);
        model.put("brand",brand);

        model.put("detail", spuDetail);
        model.put("skus", skus);
        model.put("specs", specs);

        return model;
    }

     public void createHtml(Long spuId) {
        //上下文
        Context context = new Context();
        context.setVariables(loadModel(spuId));
        //输出流D:\JAVA全套资料\资料\thymeleaf
        File file = new File("D:\\JAVA全套资料\\资料\\thymeleaf", spuId + "item.html");
        try(PrintWriter writer = new PrintWriter(file,"UTF-8")){
            //输出hml
            templateEngine.process("item",context,writer);

        }catch (Exception e){
        //异常日志
            log.error("静态页生成异常",e);
        }
    }

}

 

 我们可以把生成地页面放进nginx中,

server {

         listen       80;

         server_name www.leyou.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 html;

             if (! -f $request_filename){  #文件不存在就请求服务,渲染页面

                 proxy_pass http://192.168.1.17:8086;

                 break;

             }

             }

         

         location / {

             proxy_pass http://192.168.1.17:9002;

             # (物理机的ip地址)

             proxy_connect_timeout 600;

             proxy_read_timeout 600;

             }

    }/

//如果没有对应静态页才会代理到这
@GetMapping("item/{id}.html")
public String toItemPage(@PathVariable("id") Long id, Model model) {

    //查询数据
    Map<String, Object> attributes = pageService.loadModel(id);
    model.addAllAttributes(attributes);
    pageService.createHtml(id); //创建静态页
    return "item";
}

 

商品更新问题

静态页完成了,但是如果商品信息改变了呢,静态页存在了就会取访问原先地静态页,搜索服务中保存的信息也是原来地商品信息,mysql和搜索服务,静态微服务资源无法同步怎么解决呢?

是不是马上想到,在商品微服务中更新了,就去写搜索和静态页更新地逻辑,但是商品微服务本来就是处理商品地,你有在这里面增加了搜索和金泰也微服务,显然不合理。

那么自然而然想到第二种,搜索和静态页微服务提供对应借口,商品微服务调用接口。这也是一种方案,但是增加了商品微服务和搜索静态页微服务地代码耦合。

 

这里就可以使用消息队列解耦,商品微服务更新商品后发送给消息队列,搜索和静态页微服务取消息队列获取消息然后同步数据。下篇就讲消息队列i

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值