页面静态化
场景:
当某个页面(例如首页)访问频繁,而且查询数据量大,其中还有大量的循环处理,用户访问首页会耗费服务器大量的资源,并且响应数据的效率会大大降低。
解决:
页面静态化
-
页面静态化
-
为什么要做页面静态化
-
减少数据库查询次数。
-
提升页面响应效率(减少页面渲染)
结论:当页面变化不太频繁时可以将页面渲染成一个静态文件,以后用户访问的时候,直接通过nginx去提供静态文件即可,大大的降低了django后台的处理压力。
-
-
什么是页面静态化
- 将动态渲染生成的页面结果保存成html文件,放到静态文件服务器中。
- 用户直接去静态服务器,访问处理好的静态html文件。
-
页面静态化注意点
-
用户相关数据不能静态化:
- 用户名、购物车,浏览记录等不能静态化。
-
动态变化的数据不能静态化:
- 热销排行、新品推荐、分页排序数据等等。
-
不能静态化的数据处理:
-
可以在用户得到页面后,在页面中向后端发送Ajax请求获取相关数据。
-
直接使用模板渲染出来。
-
其他合理的处理方式等等。
-
-
-
-
页面静态化实现
-
首页页面静态化实现步骤
-
查询首页相关数据
-
获取首页模板文件
-
渲染首页html字符串
-
将首页html字符串写入到指定目录,命名’index.html’
# 静态页面和用户无关,是开发者在项目之前生成 import os from collections import OrderedDict from django.conf import settings from django.template import loader from contents.models import ContentCategory from contents.utils import get_categories def generate_static_index_html(): """静态化首页""" # 查询并展示商品分类 # 查询并展示商品分类 categories = get_categories() # 1.查询广告数据 # 查询所有广告的类别 contents = OrderedDict() context_categories = ContentCategory.objects.all() for content_category in context_categories: # 查询出为下架的广告 contents[content_category.key] = content_category.content_set.filter(status=True).order_by('sequence') # 渲染模板的上下文 context = { 'categories': categories, 'contents': contents } # 渲染数据 # 2.先获取模板文件 template = loader.get_template('index.html') # 3.再使用上下文渲染文件 html_text = template.render(context) # 4.准备文件路径,放在静态文件下 file_path = os.path.join(settings.STATICFILES_DIRS[0], 'index.html') # 5.将模板文件写入静态路径 with open(file_path, 'w', encoding='utf-8') as f: f.write(html_text)
-
-
-
定时任务crontab静态化首页
-
场景
问题:对于首页的静态化,考虑到页面的数据可能由多名运营人员维护,并且经常变动,所以将其做成定时任务,即定时执行静态化。
解决:在Django执行定时任务,可以通过
django-crontab
扩展来实现 -
安装 django-crontab(虚拟环境下)
pip install django-crontab
-
注册 django-crontab 应用
INSTALLED_APPS = [ 'django_crontab', # 定时任务 ]
-
配置定时任务,定时任务分为三部分定义:任务时间–任务方法—任务日志
# 定时器配置 CRONJOBS = [ # 每1分钟生成一次首页静态文件 # 任务时间--任务方法---任务日志 ('*/1 * * * *', 'contents.crons.generate_static_index_html', '>> ' + os.path.join(os.path.dirname(BASE_DIR), 'logs/crontab.log')) ] # 指定中文编码格式 CRONTAB_COMMAND_PREFIX = 'LANG_ALL=zh_cn.UTF-8'
定时时间基本格式 : * * * * * 分 时 日 月 周 命令 M: 分钟(0-59)。每分钟用 * 或者 */1 表示 H:小时(0-23)。(0表示0点) D:天(1-31)。 m: 月(1-12)。 d: 一星期内的天(0~6,0为星期天)。
-
管理定时任务
# 添加定时任务到系统中 python manage.py crontab add # 显示已激活的定时任务 python manage.py crontab show # 移除定时任务 python manage.py crontab remove
-
-
定义批量静态化详情页脚本文件
-
场景
- 商品详情页查询数据量大,而且是用户频繁访问的页面。
- 类似首页广告,为了减少数据库查询次数,提升页面响应效率,我们也要对详情页进行静态化处理。
静态化说明:
- 首页广告的数据变化非常的频繁,所以我们最终使用了定时任务进行静态化。
- 详情页的数据变化的频率没有首页广告那么频繁,而且是当SKU信息有改变时才要更新的,所以我们采用新的静态化方案。
- 方案一:通过Python脚本手动一次性批量生成所有商品静态详情页。
- 方案二:后台运营人员修改了SKU信息时,异步的静态化对应的商品详情页面。
- 我们在这里先使用方案一来静态详情页。当有运营人员参与时才会补充方案二。
注意:
- 用户数据和购物车数据不能静态化。
- 热销排行和商品评价不能静态化。
-
定义批量静态化详情页脚本文件
-
准备脚本目录script和Python脚本文件regenerate_detail_html.py(放在项目工程下)
-
指定Python脚本解析器
-
添加Python脚本导包路径
-
设置Python脚本Django环境
-
编写静态化详情页Python脚本代码
#!/home/python/.virtualenvs/meiduo_mall/bin/ python # 1.指定Python脚本解析器 # 2.添加Python脚本导包路径 import sys sys.path.insert(0, '../') # 3.设置Python脚本Django环境 import os if not os.getenv('DJANGO_SETTINGS_MODULE'): os.environ['DJANGO_SETTINGS_MODULE'] = 'meiduo_mall.settings.dev' import django django.setup() from django.template import loader from django.conf import settings from goods import models from contents.utils import get_categories from goods.utils import get_breadcrumb # 4.编写静态化详情页Python脚本代码 def generate_static_sku_detail_html(sku_id): """ 生成静态商品详情页面 :param sku_id: 商品sku id """ pass
-
-
执行批量静态化详情页脚本文件
# 进入静态化详情页Python脚本代码所在目录下 # cd 路径 # 执行脚本文件 python ./regenerate_detail_html.py
-
-
页面静态化测试
-
修改nginx配置文件
server { listen ngnix端口号; server_name locahost; location /group1/M00/ { # Django文件存储地址 alias /var/fdfs/storage/data/; } # 指定访问/时访问的静态文件地址 location = / { # 静态文件路径 root XXXX; index index.html index.htm; } # 指定访问/index.html时访问的静态文件地址 location = /index.html { root XXXX; } # 指定其它页面访问地址 location / { proxy_pass http://ip地址:项目开启端口号; } }
-
关闭nginx
sudo nginx -s stop
-
开启nginx
sudo nginx -c /etc/nginx/nginx.conf
-
启动项目,以nginx端口号访问的页面就是静态化后的页面
-