最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Django之使用celery和NGINX生成靜態(tài)頁面實(shí)現(xiàn)性能優(yōu)化

 更新時(shí)間:2019年10月08日 08:29:14   作者:YifChan  
這篇文章主要介紹了Django之使用celery和NGINX生成靜態(tài)頁面實(shí)現(xiàn)性能優(yōu)化,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

性能優(yōu)化原理:

當(dāng)我們要給client瀏覽器返回一個(gè)頁面時(shí),我們需要去數(shù)據(jù)庫查詢數(shù)據(jù)并將數(shù)據(jù)和基本頁面模板渲染形成頁面返回給客戶端,但如果每一個(gè)用戶訪問時(shí)都去查詢一次首頁的的數(shù)據(jù)時(shí),當(dāng)日訪問量很大時(shí)那么無疑會(huì)給數(shù)據(jù)庫查詢帶來很大的性能問題。為了解決這個(gè)問題,我們可以給未登錄用戶返回一個(gè)早就渲染好的靜態(tài)首頁(給已登錄的用戶返回一個(gè)調(diào)用緩存數(shù)據(jù)和個(gè)人數(shù)據(jù)渲染的頁面),這樣就可以提高網(wǎng)站的性能了。

使用celery生成靜態(tài)首頁

生成靜態(tài)頁面原理:

在一個(gè)為靜態(tài)首頁準(zhǔn)備的基礎(chǔ)模板之上,獲取數(shù)據(jù),使用django的loader加載基礎(chǔ)模板,使用render渲染頁面即可生成幾臺(tái)頁面。

安裝celery

pip install celery

為redis配置settings文件

# diango的緩存配置
CACHES = {
 "default": {
  "BACKEND": "django_redis.cache.RedisCache",
  "LOCATION": "redis://127.0.0.1:6379/9",
  "OPTIONS": {
   "CLIENT_CLASS": "django_redis.client.DefaultClient",
  }
 }
}

準(zhǔn)備一個(gè)首頁靜態(tài)模板文件static_base.html

{# 首頁 注冊(cè) 登錄 #}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
{% load staticfiles %}
<head>
 <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
 {# 網(wǎng)頁標(biāo)題內(nèi)容塊 #}
 <title>{% block title %}{% endblock title %}</title>
 <link rel="stylesheet" type="text/css" href="{% static 'css/reset.css' %}">
 <link rel="stylesheet" type="text/css" href="{% static 'css/main.css' %}">
 {# 網(wǎng)頁頂部引入文件塊 #}
 {% block topfiles %}{% endblock topfiles %}
</head>
<body>
{# 網(wǎng)頁頂部歡迎信息塊 #}
{% block header_con %}
 <div class="header_con">
  <div class="header">
   <div class="welcome fl">歡迎來到商城!</div>
   <div class="fr">
    <div class="login_btn fl">
     <a href="{% url 'user:login' %}">登錄</a>
     <span>|</span>
     <a href="{% url 'user:register' %}">注冊(cè)</a>
    </div>
    <div class="user_link fl">
     <span>|</span>
     <a href="{% url 'user:user' %}">用戶中心</a>
     <span>|</span>
     <a href="cart.html">我的購物車</a>
     <span>|</span>
     <a href="{% url 'user:order' %}">我的訂單</a>
    </div>
   </div>
  </div>  
 </div>
{% endblock header_con %}

{# 網(wǎng)頁頂部搜索框塊 #}
{% block search_bar %}
 <div class="search_bar clearfix">
  <a href="index.html" class="logo fl"><img src="{% static 'images/logo.png' %}"></a>
  <div class="search_con fl">
   <input type="text" class="input_text fl" name="" placeholder="搜索商品">
   <input type="button" class="input_btn fr" name="" value="搜索">
  </div>
  <div class="guest_cart fr">
   <a href="#" class="cart_name fl">我的購物車</a>
   <div class="goods_count fl" id="show_count">{{ cart_count }}</div>
  </div>
 </div>
{% endblock search_bar %}

{# 網(wǎng)站主體內(nèi)容塊 #}
{% block body %}{% endblock body %}

 <div class="footer">
  <div class="foot_link">
   <a href="#">關(guān)于我們</a>
   <span>|</span>
   <a href="#">聯(lián)系我們</a>
   <span>|</span>
   <a href="#">招聘人才</a>
   <span>|</span>
   <a href="#">友情鏈接</a>  
  </div>
  <p>CopyRight © 2016 北京商城信息技術(shù)有限公司 All Rights Reserved</p>
  <p>電話:010-****888 京ICP備*******8號(hào)</p>
 </div>
 {# 網(wǎng)頁底部html元素塊 #}
 {% block bottom %}{% endblock bottom %}
 {# 網(wǎng)頁底部引入文件塊 #}
 {% block bottomfiles %}{% endblock bottomfiles %}
</body>
</html>

在首頁靜態(tài)模板文件的基礎(chǔ)上繼承生成一個(gè)首頁靜態(tài)文件 static_index.html 方便celery獲取數(shù)據(jù)庫文件并進(jìn)行渲染

{% extends 'static_base.html' %}
{% load staticfiles %}
{% block title %}首頁{% endblock title %}
{% block topfiles %}
 <script type="text/javascript" src="{% static 'js/jquery-1.12.4.min.js' %}"></script>
 <script type="text/javascript" src="{% static 'js/jquery-ui.min.js' %}"></script>
 <script type="text/javascript" src="{% static 'js/slide.js' %}"></script>
{% endblock topfiles %}
{% block body %}
 <div class="navbar_con">
  <div class="navbar">
   <h1 class="fl">全部商品分類</h1>
   <ul class="navlist fl">
    <li><a href="">首頁</a></li>
    <li class="interval">|</li>
    <li><a href="">手機(jī)生鮮</a></li>
    <li class="interval">|</li>
    <li><a href="">抽獎(jiǎng)</a></li>
   </ul>
  </div>
 </div>

 <div class="center_con clearfix">
  <ul class="subnav fl">
   {% for type in types %}
    <li><a href="#model0{{ forloop.counter }}" class="{{ type.logo }}">{{ type.name }}</a></li>
   {% endfor %}
  </ul>
  <div class="slide fl">
   <ul class="slide_pics">
    {% for banner in goods_banners %}
     <li><a href="#"><img src="{{ banner.image.url }}" alt="幻燈片"></a></li>
    {% endfor %}
   </ul>
   <div class="prev"></div>
   <div class="next"></div>
   <ul class="points"></ul>
  </div>
  <div class="adv fl">
   {% for banner in promotion_banners %}
    <a href="{{ banner.url }}"><img src="{{ banner.image.url }}"></a>
   {% endfor %}
  </div>
 </div>

 {% for type in types %}
 <div class="list_model">
  <div class="list_title clearfix">
   <h3 class="fl" id="model0{{ forloop.counter }}">{{ type.name }}</h3>
   <div class="subtitle fl">
    <span>|</span>
    {% for banner in type.title_banners %}
     <a href="#">{{ banner.sku.name }}</a>
    {% endfor %}
   </div>
   <a href="#" class="goods_more fr" id="fruit_more">查看更多 ></a>
  </div>

  <div class="goods_con clearfix">
   <div class="goods_banner fl"><img src="{{ type.image.url }}"></div>
   <ul class="goods_list fl">
    {% for banner in type.image_banners %}
    <li>
     <h4><a href="#">{{ banner.sku.name }}</a></h4>
     <a href="#"><img src="{{ banner.sku.image.url }}"></a>
     <div class="prize">¥ {{ banner.sku.price }}</div>
    </li>
    {% endfor %}
   </ul>
  </div>
 </div>
 {% endfor %}
{% endblock body %}

在項(xiàng)目下新建celery_tasks文件夾,在文件夾中新建tasks.py文件, 編寫tasks文件 ;

from django.conf import settings
from celery import Celery
from django.template import loader

# 在任務(wù)處理者一端加這幾句
import os
# import django
# os.environ.setdefault("DJANGO_SETTINGS_MODULE", "shoppingmall.settings")
# django.setup()

# 這幾個(gè)類要放在django環(huán)境初始化那四句的下面
from goods.models import GoodsType, IndexGoodsBanner, IndexPromotionBanner, IndexTypeGoodsBanner

# 創(chuàng)建一個(gè)Celery類的實(shí)例對(duì)象
app = Celery('celery_tasks.tasks', broker='redis://127.0.0.1:6379/8')


@app.task
def generate_static_index_html():
 '''產(chǎn)生首頁靜態(tài)頁面'''
 # 獲取商品的種類信息
 types = GoodsType.objects.all()
 # 獲取首頁輪播商品信息
 goods_banners = IndexGoodsBanner.objects.all().order_by('index')
 # 獲取首頁促銷活動(dòng)信息
 promotion_banners = IndexPromotionBanner.objects.all().order_by('index')
 # 獲取首頁分類商品展示信息
 for type in types: # GoodsType
  # 獲取type種類首頁分類商品的圖片展示信息
  image_banners = IndexTypeGoodsBanner.objects.filter(type=type, display_type=1).order_by('index')
  # 獲取type種類首頁分類商品的文字展示信息
  title_banners = IndexTypeGoodsBanner.objects.filter(type=type, display_type=0).order_by('index')
  # 動(dòng)態(tài)給type增加屬性,分別保存首頁分類商品的圖片展示信息和文字展示信息
  type.image_banners = image_banners
  type.title_banners = title_banners

 # 組織模板上下文
 context = {
    'types': types,
    'goods_banners': goods_banners,
    'promotion_banners': promotion_banners
   }

 # 使用模板
 # 1.加載模板文件,返回模板對(duì)象
 temp = loader.get_template('static_index.html')
 # 2.模板渲染
 static_index_html = temp.render(context)

 # 生成首頁對(duì)應(yīng)靜態(tài)文件
 save_path = os.path.join(settings.BASE_DIR, 'static/index.html')
 with open(save_path, 'w', encoding='utf-8') as f:
  f.write(static_index_html)

開啟redis服務(wù)

E:\>cd E:\YifChanSoft\Database\Redis\RedisSoft\Redis-x64-3.2.100

E:\YifChanSoft\Database\Redis\RedisSoft\Redis-x64-3.2.100>redis-server --service-install redis.windows-service.conf --loglevel verbose

E:\YifChanSoft\Database\Redis\RedisSoft\Redis-x64-3.2.100>redis-cli
127.0.0.1:6379> select 8
OK
127.0.0.1:6379[8]> keys *
1) "_kombu.binding.celery"
2) "_kombu.binding.celery.pidbox"
127.0.0.1:6379[8]>

開啟redis服務(wù)截圖

將項(xiàng)目代碼拷貝一份放在某處,進(jìn)入該處, 啟動(dòng)tasks的worker模式 ,

注意,用作worker的代碼的tasks文件中應(yīng)該有提前啟動(dòng)django的初始化的代碼,不然worker沒法調(diào)用conf信息;

即應(yīng)該有以下內(nèi)容

# 在任務(wù)處理者一端加這幾句
import os
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "shoppingmall.settings")
django.setup()

為了解決celery4.x在win10上運(yùn)行的錯(cuò)誤,安裝eventlet

pip install eventlet

進(jìn)入復(fù)制用來做celery工作者的項(xiàng)目代碼所在處

開啟worker模式

celery -A celery_tasks.tasks worker -l info -P eventlet

開啟worker模式截圖

如果有就刪除celery代碼文件中static中的index.html文件;

主動(dòng)調(diào)用 generate_static_index_html.delay() 即可驗(yàn)證生成index.html;

from celery_tasks.tasks import generate_static_index_html
generate_static_index_html.delay()

驗(yàn)證截圖

可以看到在項(xiàng)目下的static文件夾下生成了index.html;

開啟項(xiàng)目在瀏覽器中輸入 http://127.0.0.1:8888/static/index.html/ 即可看到生成的靜態(tài)首頁;因?yàn)閿?shù)據(jù)庫中還沒有數(shù)據(jù),所以頁面比較空。

NGINX的安裝

參考教程: http://m.fzitv.net/article/171374.htm

1.下載nginx: http://nginx.org/en/download.html

2.解壓縮nginx包

下載好后在放入合適的目錄,解壓縮后如下

3.使用cmd命令,進(jìn)入nginx所在解壓縮目錄,使用如下命令進(jìn)行 安裝nginx ;

start nginx.exe

安裝截圖

安裝完成后,我們可以在 任務(wù)管理器中看到nginx任務(wù),如圖

至此,nginx就算安裝完成了。

nginx命令

start nginx.exe # 開啟nginx
nginx -s reload # 重新啟動(dòng)
nginx -s stop # 停止nginx
nginx -s quit # 退出nginx

使用NGINX提供靜態(tài)首頁

修改nginx配置

找到nginx的配置文件,如下圖所示,為了方便以后其他的項(xiàng)目使用,我們拷貝一份源文件重命名為nginx_origin.conf

用編輯器打開 nginx.conf 文件,修改配置文件中內(nèi)容如下:

location /static {
 alias E:/Pycharm/Pycharm_save/cp15/18Django_fresh2/step206/shoppingmall206/static/;
}

location / {
 # root html;
 root E:/Pycharm/Pycharm_save/cp15/18Django_fresh2/step206/shoppingmall206/static/;
 index index.html index.htm;
}

配置截圖

注意,其中的地址應(yīng)該是你使用celery的項(xiàng)目所在的絕對(duì)路徑地址,并且地址之間應(yīng)該使用斜杠/而不是反斜杠\,否則會(huì)報(bào)錯(cuò)。

修改好配置保存后,我們使用一下命令進(jìn)行nginx的重啟

nginx -s reload

然后,我們打開瀏覽器輸入一下兩個(gè)鏈接之一就可以看到項(xiàng)目主頁面了。

http://127.0.0.1/ # 注意,后面必須有一個(gè)/,否則會(huì)進(jìn)入nginx默認(rèn)界面
http://127.0.0.1/static/index.html

項(xiàng)目主頁面截圖

nginx的cmd命令截圖,其中的報(bào)錯(cuò)都是因?yàn)槭褂玫氖莣in10目錄自帶的反斜杠

在Django網(wǎng)站和celery可以理解是并列的關(guān)系,在他們之前,其實(shí)還有一個(gè)nginx服務(wù)器負(fù)責(zé)調(diào)度;

一般是當(dāng)用戶直接訪問127.0.0.1時(shí),我們通過nginx調(diào)度去celery的nginx中返回靜態(tài)頁面;

而當(dāng)用戶訪問127.0.0.1/index時(shí),我們返回調(diào)用Django網(wǎng)站的IndexView;

在網(wǎng)站上線時(shí)我們會(huì)使用nginx對(duì)它們進(jìn)行配置。

后臺(tái)數(shù)據(jù)修改時(shí)重新生成靜態(tài)頁面

原理

在數(shù)據(jù)庫的數(shù)據(jù)改變時(shí),會(huì)調(diào)用admin.ModelAdmin下的sava_model和delete_model方法用來更新數(shù)據(jù),而我們需要當(dāng)數(shù)據(jù)改變后重新生成靜態(tài)頁面;

因此,我們可以自定義一個(gè)類繼承admin.ModelAdmin,重寫更新和刪除數(shù)據(jù)的方法,調(diào)用父類的更新刪除方法后,調(diào)用celery中的方法重新生成靜態(tài)首頁;

實(shí)現(xiàn)

我們要配置當(dāng)某個(gè)表的數(shù)據(jù)改變時(shí)重新生成靜態(tài)頁面,就要給該表定義一個(gè) xxxModelAdmin 類,繼承自admin.ModelAdmin并重寫其中的方法,并且在admin中注冊(cè)時(shí)該表應(yīng)該同時(shí)繼承xxxModelAdmin 類;

因?yàn)橛泻芏啾矶夹枰绱伺渲?,且類中的代碼都相同,所以我們可以抽出一個(gè) BaseModelAdmin 類,編寫更新后重新調(diào)用生成靜態(tài)頁面的代碼,然后讓各個(gè)需要修改的表繼承該類即可。

在首頁對(duì)應(yīng)的應(yīng)用中的admin.py文件中編寫如下代碼

from django.contrib import admin
# from django.core.cache import cache
from goods.models import GoodsType, GoodsSKU, Goods, GoodsImage, IndexGoodsBanner, IndexTypeGoodsBanner, IndexPromotionBanner
from celery_tasks.tasks import generate_static_index_html


class BaseModelAdmin(admin.ModelAdmin):
 """當(dāng)后臺(tái)數(shù)據(jù)庫數(shù)據(jù)改動(dòng)時(shí)使celery重新生成靜態(tài)首頁頁面"""
 def save_model(self, request, obj, form, change):
  """當(dāng)更新或者新增數(shù)據(jù)時(shí)調(diào)用"""
  super().save_model(request, obj, form, change)
  # 發(fā)出任務(wù),讓celery worker重新生成靜態(tài)首頁
  generate_static_index_html.delay()

  # 清除首頁的緩存數(shù)據(jù)
  # cache.delete("index_page_data")

 def delete_model(self, request, obj):
  """當(dāng)刪除數(shù)據(jù)時(shí)調(diào)用"""
  super().delete_model(request, obj)
  generate_static_index_html.delay()

  # 清除首頁的緩存數(shù)據(jù)
  # cache.delete("index_page_data")


class GoodsTypeAdmin(BaseModelAdmin):
 pass


class IndexGoodsBannerAdmin(BaseModelAdmin):
 pass


class IndexTypeGoodsBannerAdmin(BaseModelAdmin):
 pass


class IndexPromotionBannerAdmin(BaseModelAdmin):
 pass


admin.site.register(GoodsType, GoodsTypeAdmin)
admin.site.register(GoodsSKU)
admin.site.register(Goods)
admin.site.register(GoodsImage)
admin.site.register(IndexGoodsBanner, IndexGoodsBannerAdmin)
admin.site.register(IndexTypeGoodsBanner, IndexTypeGoodsBannerAdmin)
admin.site.register(IndexPromotionBanner, IndexPromotionBannerAdmin)

至此,當(dāng)我們?cè)赼dmin后臺(tái)更新數(shù)據(jù)時(shí)就會(huì)重新生成靜態(tài)首頁了,大家可以自行嘗試一下~

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python eval函數(shù)介紹及用法

    Python eval函數(shù)介紹及用法

    在本篇文章里小編給大家整理的是一篇關(guān)于Python eval函數(shù)介紹及用法,有興趣的朋友們可以參考下。
    2020-11-11
  • 用Python代碼來解圖片迷宮的方法整理

    用Python代碼來解圖片迷宮的方法整理

    這篇文章主要介紹了用Python代碼來解圖片迷宮的方法整理,本文精選了StackOverflow相關(guān)人氣問題上的幾個(gè)回答,需要的朋友可以參考下
    2015-04-04
  • python reduce 函數(shù)使用詳解

    python reduce 函數(shù)使用詳解

    reduce()函數(shù)也是Python內(nèi)置的一個(gè)高階函數(shù)。reduce()函數(shù)接收的參數(shù)和 map()類似,一個(gè)函數(shù) f,一個(gè)list,但行為和 map()不同,今天我們就來詳細(xì)探討下
    2017-12-12
  • django從請(qǐng)求到響應(yīng)的過程深入講解

    django從請(qǐng)求到響應(yīng)的過程深入講解

    這篇文章主要給大家介紹了關(guān)于django從請(qǐng)求到響應(yīng)的過程的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用django具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-08-08
  • Python利用Turtle庫繪制一顆櫻花樹

    Python利用Turtle庫繪制一顆櫻花樹

    后唐李煜曾說道,櫻花落盡春將困,秋千架下歸時(shí)。漏暗斜月遲遲,花在枝。櫻花落盡的時(shí)候春天也將過去了,秋千架下歸去時(shí)。天上的斜月姍姍來遲,花還在枝頭。本文將用Python+Turtle繪制一顆櫻花樹,感興趣的可以嘗試一下
    2022-04-04
  • 利用python實(shí)現(xiàn)后端寫網(wǎng)頁(flask框架)

    利用python實(shí)現(xiàn)后端寫網(wǎng)頁(flask框架)

    這篇文章主要給大家介紹了關(guān)于如何利用python實(shí)現(xiàn)后端寫網(wǎng)頁(flask框架)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • Python報(bào)錯(cuò)KeyError: ‘missing_key‘的有效解決方法

    Python報(bào)錯(cuò)KeyError: ‘missing_key‘的有效解決方法

    在 Python 編程中,報(bào)錯(cuò)信息常常讓開發(fā)者感到困擾,其中,“KeyError: ‘missing_key’”是一個(gè)較為常見的報(bào)錯(cuò),它可能在各種數(shù)據(jù)處理和字典操作的場景中出現(xiàn),本文將深入探討這個(gè)報(bào)錯(cuò)的原因,并提供多種有效的解決方法,幫助開發(fā)者快速解決此類問題
    2024-10-10
  • Python的Flask框架中使用Flask-SQLAlchemy管理數(shù)據(jù)庫的教程

    Python的Flask框架中使用Flask-SQLAlchemy管理數(shù)據(jù)庫的教程

    在Python中我們可以使用SQLAlchemy框架進(jìn)行數(shù)據(jù)庫操作,那么對(duì)應(yīng)的在Flask框架中我們可以使用SQLAlchemy,下面我們就來看一下Python的Flask框架中使用Flask-SQLAlchemy管理數(shù)據(jù)庫的教程
    2016-06-06
  • python從gbff文件中直接提取cds序列

    python從gbff文件中直接提取cds序列

    這篇文章主要為大家介紹了python從gbff文件中直接提取cds序列示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • Python&Matlab實(shí)現(xiàn)螞蟻群算法求解最短路徑問題的示例

    Python&Matlab實(shí)現(xiàn)螞蟻群算法求解最短路徑問題的示例

    本文主要介紹了Python&Matlab實(shí)現(xiàn)螞蟻群算法求解最短路徑問題的示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03

最新評(píng)論

临夏市| 老河口市| 陵川县| 芜湖市| 秦安县| 凤庆县| 惠东县| 偏关县| 林芝县| 英山县| 海南省| 盈江县| 哈尔滨市| 曲沃县| 临颍县| 浮梁县| 通山县| 斗六市| 云梦县| 游戏| 崇仁县| 石河子市| 秦安县| 长宁区| 文成县| 沙坪坝区| 凤山县| 临湘市| 怀柔区| 平乐县| 名山县| 辽宁省| 太康县| 容城县| 成武县| 新绛县| 福安市| 横山县| 临江市| 大庆市| 肥乡县|