【图解秒杀系列】秒杀技术点——静态化
【图解秒杀系列】秒杀技术点——静态化
- 什么是静态化、静态化的作用
- 如何实现静态化
- FreeMarker、Thymleaf
- 处理流程
- 问题
- OpenResty + Lua
- lua_shared_dict & lua-resty-template
- 处理流程
- 具体操作
什么是静态化、静态化的作用
静态化就是指通过某种静态化技术,将原本需要动态渲染生成的HTML页面固定下来变成一个静态页面文件,后续请求该页面都直接返回该静态页面。

首先要有模板和数据,然后根据给定的模板和数据,通过模板引擎,就能生成对应的静态HTML文件。

生成的静态HTML页面,可以推到Nginx上缓存到Nginx本地。当用户请求访问对应的页面时,Nginx直接返回缓存在本地的静态页面,这样响应速度就大大提升。
在秒杀场景中,商品详情页就可以进行静态化处理,提升商品详情页的访问速度。
如何实现静态化
FreeMarker、Thymleaf
一种方式是通过FreeMarker、Thymleaf这种Java语言的模板引擎实现。
处理流程
FreeMarker、Thymleaf需要跑在一个Tomcat进程里面,当接收到请求时,通过Freemarker、Thymleaf等模板引擎技术,根据指定的模板和数据,生成静态HTML页面,返回客户端。
另外,我们可以监听MQ上的修改操作消息,当监听到有修改操作发生时,就在异步工程里面使用模板引擎生成静态HTML页面,然后推到Nginx上缓存到Nginx本地。

问题
但是这种方案会有几个问题。
首先第一个问题是,如果我们修改了模板,那么使用该模板生成的静态HTML页面全部都要删除或刷新。

第二个问题是如果我们有多个Nginx,则要同时推送给多个Nginx。

如果是多Nginx场景下,碰上批量刷新,那这个操作就很复杂了。
OpenResty + Lua
为了解决上面的问题,就有了一个更好的解决方案,那就是OpenResty加Lua脚本。
OpenResty是基于Nginx进行二次开发的Web平台,支持执行Lua脚本,并且内部集成了许多Lua库和第三方模块。
lua_shared_dict & lua-resty-template
在这个方案下,我们用到OpenResty的两个重要的东西,一个是“lua_shared_dict”指令、lua-resty-template模块。
lua_shared_dict用于声明一个共享内存区域,可以将其作为缓存空间使用,比如“lua_shared_dict my_cache 128m;”表示声明一个128m大小名为“my_cache”的内存共享区域。
而lua-resty-template模块的作用就是一个模板引擎,它的作用与FreeMarker或者Thymleaf类似,只是它是跑在OpenResty内部而不是后端服务。
处理流程
那么此时处理流程如下:

- 客户端的请求被OpenResty接收
- OpenResty在location块中通过content_by_lua_file命令指定执行的lua脚本
- lua脚本被执行,首先判断lua_shared_dict命令声明的缓存空间中是否缓存了对应的数据
- 如果缓存命中,则直接通过lua-resty-template模块进行模板渲染生成静态html文件并返回
- 如果缓存不命中,则请求后端服务获取对应数据,再缓存到lua_shared_dict命令声明的缓存空间中,然后再进行模板渲染生成静态html文件并返回
这么做的好处就是:
- 即使模板变了,我们只需要更新OpenResty上的模板即可,由于最终的html文件是由OpenResty动态渲染生成的,所以只要更新了模板,生成的html就会更新。
- 由于是OpenResty自己通过模板渲染生成的html,而不是后端服务生成的,因此不再需要推送ng的这一步操作。
具体操作
在nginx.conf文http模块中加入:
lua_package_path '../lualib/?.lua;;';
lua_package_cpath '../lualib/?.so;;';
include lua.conf;
lua.conf:
lua_shared_dict my_cache 128m;
server {listen 222;set $template_location "/templates";set $template_root "D:/ProgramData/nginx/";location /product {default_type 'text/html;charset=UTF‐8';lua_code_cache on;content_by_lua_file D:/ProgramData/nginx/product.lua;}
}
product.lua:
local uri_args = ngx.req.get_uri_args()local productId = uri_args["productId"]local cache_ngx = ngx.shared.my_cachelocal productCacheKey = "product_info_"..productIdlocal productCache = cache_ngx:get(productCacheKey)if productCache == "" or productCache == nil thenlocal http = require("resty.http")local httpc = http.new()local resp, err = httpc:request_uri("http://127.0.0.1:8866",{method = "GET",path = "/pms/productInfo/"..productId})productCache = resp.bodylocal expireTime = math.random(600,1200)cache_ngx:set(productCacheKey, productCache, expireTime)endlocal cjson = require("cjson")local productCacheJSON =cjson.decode(productCache)ngx.say(productCache);local context = {id = productCacheJSON.data.id,name = productCacheJSON.data.name,price = productCacheJSON.data.price,pic = productCacheJSON.data.pic,detailHtml = productCacheJSON.data.detailHtml}local template = require("resty.template")template.render("product.html", context)
html模板:
<html><head><meta http‐equiv="Content‐Type" content="text/html; charset=utf‐8" /></head><body><h1>商品id: {* id *}<br/>商品名称: {* name *}<br/>商品价格: {* price *}<br/>商品库存: <img src={* pic *}/><br/>商品描述: {* detailHtml *}<br/></h1></body>
</html>
相关文章:
【图解秒杀系列】秒杀技术点——静态化
【图解秒杀系列】秒杀技术点——静态化 什么是静态化、静态化的作用如何实现静态化FreeMarker、Thymleaf处理流程问题 OpenResty Lualua_shared_dict & lua-resty-template处理流程具体操作 什么是静态化、静态化的作用 静态化就是指通过某种静态化技术,将原本…...
Simple RPC - 05 从零开始设计一个客户端(下)_ 依赖倒置和SPI
文章目录 Pre概述依赖倒置原则与解耦设计与实现1. 定义接口来隔离调用方与实现类2. 实现类DynamicStubFactory3. 调用方与实现类的解耦 依赖注入与SPI的解耦依赖注入SPI(Service Provider Interface) 总结 Pre Simple RPC - 01 框架原理及总体架构初探 …...
2024新型数字政府综合解决方案(三)
新型数字政府综合解决方案通过融合人工智能、大数据和云计算技术,建立了一个智能化、互联互通的政府服务平台,旨在提升政府服务效率与透明度。该方案通过全面数字化政务流程,实现数据的实时共享和自动化处理,使公众能够便捷地访问…...
计算机毕业设计hadoop+spark+hive知识图谱音乐推荐系统 音乐数据分析可视化大屏 音乐爬虫 LSTM情感分析 大数据毕设 深度学习 机器学习
流程: 1.Python采集网易云音乐歌手、歌词、音乐、评论等约10-20万海量数据,存入mysql数据库; 2.使用pandasnumpy/MapReduce对mysql中四类数据进行数据清洗,写入.csv文件并上传至hdfs(含评论NLP文本分类/lsm情感分析); 3.使用hive建…...
值类型与引用类型
值类型 在Swift中,如果一个对象是用struct实现的,则该对象为值类型,在被赋值给常量或者变量时或者作为参数传递给函数时,值类型总是被复制,复制后的对象与之前的对象指向不同的内存。 Swift的基本类型(Array、Dictio…...
C++STL初阶(12):stack和queue的初阶实现
1. stack的选型 对于栈的实现是我们非常熟悉的过程: C语言基础数据结构——栈和队列_栈和队列 插入取出数据-CSDN博客 _top表示下标,_capacity表示空间大小: 那么按照我们原来的思路,利用_top和_capacity T*来给stack构形。 temp…...
汽车IVI中控OS Linux driver开发实操(二十三):驱动的设备probe及匹配
第一个函数:probe linux驱动模型是分成三个部分的,设备(结构体device),驱动(结构体device_driver),总线(结构体bus_type)。在Linux内核中,设备驱动通常会实现一个probe函数,它是...
华为od(D卷)二叉树计算
文章目录 题目描述输入描述输出描述示例1思路代码 题目描述 给出一个二叉树如下图所示: 6/ \7 9\ / -2 6 请由该二叉树生成一个新的二叉树,它满足其树中的每个节点将包含原始树中的左子树和右子树的和。 20 (7-296)/ \-2 6\ / 0 0 左子树…...
技术爱好者完全用台式机部件定制游戏笔记本电脑
高端笔记本电脑的功能强大到令人难以置信的地步,但大多数笔记本电脑在至少几个关键性能方面仍然落后于台式机。一位 YouTuber 对这种情况感到厌倦,为了抹除这种差距,他开始了为期 14 个月的旅程,使用真正的台式机硬件打造自己的笔…...
100个练习学习Rust!if・Panic・演练
之前的文章 【0】准备 【1】构文・整数・变量 ← 上回 【2】 if・Panic・演练 ← 本次 这是“100 Exercise To Learn Rust”的第2次练习!本次的主题包括 if 表达式、panic 机制,以及对前面内容的总结练习。 本次相关的页面如下: 2.3. Bran…...
MODELSIM仿真报错解决记录
目录 问题:Modelsim报错:Error (10228): Verilog HDL error at Line_Shift_RAM_1Bit.v(39): module “Line_Shift_RAM_1 原因:创建的IP核放到了别的位置 解决方法:删掉IP核以及QIP等文件,将IP核创建到工程目录下 问…...
day33-负载均衡实战
01.问题总结 1.rsync同步注意目录加/和不加/的区别 2.安装wordpress过程中禁止使用IP安装,解析成域名安装 比如安装过程 10.0.0.7--->填写数据库信息--->写入数据库中 如果安装完成后再使用www.wp.com访问,不能访问页面乱码的问题。 3.挂载wordpress挂载uplo…...
网络接口 eno1 未连接或未托管
网络接口 eno1 未连接或未托管,通常意味着该接口没有被识别或没有被配置为自动连接到网络。以下是一些可能的解决方案: 检查物理连接: 确保您的以太网电缆正确连接到 eno1 接口和调制解调器/路由器。 启用网络接口: 使用以下命令…...
Linux I/O 多路复用机制详解
文章目录 1 文件描述符(File Descriptor)1.1 什么是文件描述符?1.2 文件描述符与文件的关系 2 文件描述符集合(File Descriptor Set)2.1 什么是文件描述符集合?2.2 fd_set 结构体 3 select() 函数的工作原理…...
第43课 Scratch入门篇:雪花随风飘
雪花随风飘 故事背景: 雪花轻轻地从灰蒙蒙的天空中飘落下来,它们像是天空中飘洒下来的羽毛,又像是冬日的精灵在翩翩起舞。每一片雪花都独一无二,它们在空中旋转、飘荡,最终缓缓降落在屋顶、树枝、街道和行人的肩头。 程序原理: 众多的雪花肯定是克隆功能,降落过程是通过…...
VueUse 基于 Vue 3 Composition API 的高质量 Hooks 库
VueUse 是什么? VueUse 是基于 Vue 3 Composition API 的高质量 Hooks 库。例如获取滚动的距离 VueUse 官网:VueUse | VueUse VueUse 什么使用? 1、通过npm安装 VueUse npm i @vueuse/core 2、搜索需要使用的函数,例如搜索 useScroll 滚动 3、使用useScroll 滚动函数 …...
ARM CoreLink 系列 5.1.1 -- CI-700 System Address Map 】
文章目录 System Address MapRN SAMRN SAM memory regions and target typesSAM memory region size configurationRN SAM target ID selectionSystem Address Map 所有的CHI 命令都包含一个 Source ID 和 Target ID, 其中 Source ID 可以来自于 RN Node, Target ID 可以来自…...
【数据结构】二叉树(一)
目录 1. 树型结构 概念 树的表示形式 编辑 2. 二叉树(重点) 2.1 概念 2.2 二叉树的性质 2.3 二叉树的存储 2.4 二叉树的遍历 前中后序遍历 层序遍历: 2.5二叉树的基本操作 本篇主要理解树和二叉树相关概念,二叉树遍…...
使用duplicate搭建备库或者级联备库
使用duplicate搭建备库或者级联备库: 主库或者源端: 1. 创建pfile,更改&添加部分参数、传输到备库; 2. 主库(或者源端)的tnsnames.ora文件添加 备库的连接信息 备库: 1. 备库添加静态监听 2…...
【存储学习笔记】4:快照(Snapshot)技术的实现方式
1 快照 1.1 动机 在上一篇《备份》里提到,热备份就是在执行操作时,服务器需要正常处理来自用户或应用对数据的更新,这样能够保证数据7*24小时可用(在很多服务里这是必要的)。 而热备份的困难就是如何保证数据的一致…...
2026年好用的录音转文字工具怎么选?从链接提取到实时转写的完整方案
做会议记录、课堂笔记或内容创作时,经常卡在两个问题上:一是录音文件堆积成山不知道从何整理,二是转完文字还要花时间校对和调整。微信里有个叫提词匠的小程序在这类需求里效率比较实用,下面会重点拆解它怎么用,同时也…...
用Python搞定常微分方程:从显式RK4到隐式IRK6,一个类全搞定(附完整代码)
用Python搞定常微分方程:从显式RK4到隐式IRK6,一个类全搞定(附完整代码) 在工程计算和科学研究中,常微分方程(ODE)的数值求解是一个无法回避的问题。无论是模拟电路中的电流变化,还是…...
零代码物联网实战:用WipperSnapper与Adafruit IO快速采集模拟与I2C传感器数据
1. 项目概述与核心价值在嵌入式开发和物联网项目的起步阶段,很多开发者,尤其是刚接触硬件的朋友,常常会卡在两个看似基础却至关重要的环节上:如何让微控制器“感知”到物理世界的连续变化,以及如何高效、可靠地读取那些…...
Zotero Duplicates Merger终极教程:3步自动化清理文献重复项
Zotero Duplicates Merger终极教程:3步自动化清理文献重复项 【免费下载链接】ZoteroDuplicatesMerger A zotero plugin to automatically merge duplicate items 项目地址: https://gitcode.com/gh_mirrors/zo/ZoteroDuplicatesMerger 还在为Zotero文献库中…...
自建个人数字图书馆:基于Go+Vue+SQLite的Alexandria部署与优化指南
1. 项目概述:一个现代数字图书馆的诞生如果你和我一样,是个重度数字内容爱好者,硬盘里塞满了从各种渠道收集的电子书、论文、技术文档、漫画,甚至是整理好的网页存档,那你一定体会过那种“找东西”的痛苦。文件散落在不…...
Claude Code出质量事故了?Anthropic发了一篇有诚意的复盘|AI新岗位FDE爆火
每天更新,带你读懂科技圈。 今日看点: Anthropic 正式回应 Claude Code 质量下降的社区讨论,披露三条幕后原因;FDE(Forward Deployed Engineer)正在成为 AI 公司争抢的新岗位;Figma 自研 Redis …...
VideoDownloadHelper终极指南:三分钟掌握免费视频下载插件
VideoDownloadHelper终极指南:三分钟掌握免费视频下载插件 【免费下载链接】VideoDownloadHelper Chrome Extension to Help Download Video for Some Video Sites. 项目地址: https://gitcode.com/gh_mirrors/vi/VideoDownloadHelper VideoDownloadHelper是…...
如何快速掌握BepInEx插件开发:面向初学者的完整指南
如何快速掌握BepInEx插件开发:面向初学者的完整指南 【免费下载链接】BepInEx Unity / XNA game patcher and plugin framework 项目地址: https://gitcode.com/GitHub_Trending/be/BepInEx BepInEx是Unity游戏插件开发的终极框架,让普通玩家也能…...
本地AI小镇Alicization-Town部署指南:从零搭建多智能体模拟环境
1. 项目概述与核心价值最近在社区里看到不少朋友在讨论一个名为“Alicization-Town”的项目,它源自GitHub上的一个仓库ceresOPA/Alicization-Town。这个名字听起来有点二次元,但别被它迷惑了,这其实是一个相当硬核的、面向开发者和技术爱好者…...
Midjourney V6树胶重铬酸盐输出崩溃?紧急修复指南(含--sref自定义光敏响应曲线参数实测数据)
更多请点击: https://intelliparadigm.com 第一章:Midjourney V6树胶重铬酸盐输出崩溃现象与本质溯源 现象复现与触发条件 Midjourney V6 在启用 --style raw 且 prompt 中包含化学术语(如“重铬酸盐”、“树胶”、“potassium dichromate”…...
