如何實現Django規模化 高階教程

2021-07-29 21:40:14 字數 4856 閱讀 6488

提供:zstack雲計算

本教程為django規模化系列三篇中的第三篇。

導言在之前的教程中,我們已經將django部署在droplet當中。當站點流量提公升時,我們則可通過尋找瓶頸以確定問題並加以修復。然而,如果流量持續增長,我們該如何進一步解決問題?

如果大家使用apache,則推薦各位參閱webserver優化一文。如果大家使用nginx,這些提示也同樣適用。

如果大家建立了cms以管理站點,那麼應該能夠實現比較積極的快取策略。我個人傾向使用varnish,這套前端快取方案適用於apache或nginx。如果符合這一情況,推薦大家參閱apache教程以及nginx教程(是的,nginx教程中**的是php,但也適用於django)。

除非精心配置,否則varnish的缺點在於其會將整套站點全部納入快取。舉例來說,如果大家的站點中存在大量動態內容,那麼varnish的這種快取策略可能引發錯誤。這意味著當a使用者將某項貨品加入購物車,b使用者檢視到的仍是快取中的結果,意味著其能夠將已經被a購買的貨品同樣加入購物車——這樣顯然會帶來問題。

另一項弊端在於,django在預設情況下會強制從快取內容中讀取上游快取,這可能導致衝突並引發反常行為。

但好訊息是,如今django也擁有了自己的快取框架,其擁有以下兩項突出優勢:

其能夠提公升應用程式的快取友好度,從而更好地同varnish相配合(如果大家選擇使用varnish)。

允許使用者控制對哪些站點組成部分進行快取處理。

如果大家使用的droplet配置較低,則建議各位使用資料庫快取機制。其更易啟用且不會帶來額外的伺服器程序。如果大家的記憶體量比較充裕,則可選擇memcached以實現理想的快取後端。今天的教程將著重介紹資料庫快取。

首先為快取建立一套資料庫表。在本示例中,我們的表名為「cache_table」:

python manage.py createcachetable cache_table
caches = 

}

現在大家需要決定將哪些內容納入快取。如果各位只希望確保站點與varnish順利協作,則請參閱per-site快取配置一文。不過這部分內容沒什麼新鮮,所以下面一起聊聊per-view快取。

假設我們擁有一套購物車產品頁面,其變更極少且動態程度不高。另外,假定我們計畫對product_detail(請求product_id)進行快取處理。

from django.views.decorators.cache import cache_page

@cache_page(60 * 60)

def product_detail(request, product_id):

...

其負責對60分鐘內的檢視進行快取(60秒 x 60分鐘)。

另外,我推薦大家參閱幾項重要提示一文。其中一項重要功能在於根據標題頭進行分類。如果大家的站點需要被翻譯成多種語言,或者打算根據不同瀏覽器版本提供不同內容,這篇說明將很有幫助。

如何處理頻繁變更的內容?

首先確定是否全部檢視都能夠進行主動快取,而後再著手進行快取。

大家可能想象不到——事實上僅僅10秒的快取週期也能夠起到良好的作用。在多數情況下,繁忙的站點往往會由於特定頁面的訪問量激增而面臨過載。

如果有10000名使用者在一分鐘內訪問站點中的某一頁面,則意味著伺服器需要將全部查詢同時傳送至資料庫。這時,如果我們將快取時長設定為10秒,則意味著該頁面的每分鐘查詢次數僅為6次——無論併發訪問強度有多大。如此一來,任何伺服器都能輕鬆應對這樣的流量。

電子商務站點往往需要謹慎地處理會話資料。這時大家應當考慮標題頭分類選項是否適用,畢竟創新才是實現成功的最佳途徑!

站點往往會利用ajax支援全部html頁面中的靜態內容並載入per-user會話資訊。立足於電商站點,使用者通常不會注意到其購物車需要5秒鐘才能載入完成——畢竟當前頁面還有很多其它內容供他們瀏覽。

django的內建開發伺服器擁有出色的靜態內容提供能力。大多數django站點都會利用其提供靜態內容。

但事實上,除非需要控制對內容的訪問,否則大家應該盡可能嘗試其它方式。

這裡推薦大家參閱靜態檔案說明文件。如果大家懶得檢視,我將其中的要點總結如下:

在本地開發裝置上,向「settings.py」檔案新增以下行:

static_root = os.path.join(base_dir, "static")
而後執行manage.py命令:

python manage.py collectstatic
staticfiles_dirs = (

os.path.join(base_dir, "static"),

)

現在如果大家執行開發者伺服器並檢視admin區域內的任意頁面源,則會看到來自/static/admin/css/的css檔案。

現在,在部署應用程式時,我們可以通過將apache或nginx直接指向這些檔案來確保其交付以/static/開頭的各檔案。

apache:

nginx:

server

}

在這兩種情況下,大家可以將/static/ url指向磁碟驅動器上應對的檔案位置。這樣,apache與nginx就能夠以等同於django的速度提供這些內容。

如果希望快速發布一套站點或者實現最佳效能,我會使用apache的mod_wsgi。

sudo apt-get install uwsgi uwsgi-plugin-python uwsgi-plugin-cgi
sudo apt-get install libapache2-mod-uwsgi
假設大家建立了乙個名為newproject的新專案,並將其儲存在/srv/newproject位置處。由於其屬於典型的django專案,/srv/newproject/newproject/下將生成乙個settings.py檔案。

[uwsgi]

touch-reload = /tmp/newproject

socket = 127.0.0.1:3031

workers = 2

chdir = /srv/newproject

env = django_settings_module=newproject.settings

module = django.core.handlers.wsgi:wsgihander()

現在建立乙個名為/tmp/newproject的空檔案:

touch /tmp/newproject

而後重啟uwsgi:

sudo service uwsgi restart
請注意,如果大家在同一伺服器上執行多款應用,則需要確保每款應用接入不同的埠。

另外,在對應用進行更新時,確保同時對/tmp/newproject檔案與uwsgi進行過載。

如果大家正在使用mod_wsgi,到這裡請將其禁用並啟用mod_uwsgi。這項操作可能造成錯誤,因此確保首先在測試伺服器上嘗試,直到找到正確的配置方式。

sudo a2dismod wsgi

sudo a2enmod uwsgi

現在對應用進行配置更新。在apache config中應該存在以下行:

wsgiscriptalias / /srv/newproject/newproject.wsgi
將其更新為:

sethandler uwsgi-handler

uwsgisocket 127.0.0.1:3031

現在過載apache配置:

sudo service apache2 reload
在伺服器配置檔案中,我們需要利用以下內容替換現有wsgi指令:

uwsgi_pass      127.0.0.1:3031;

include uwsgi_params;

uwsgi_param uwsgi_scheme $scheme;

就是這麼簡單!

uwsgi的重要優勢之一就是允許我們限定應用程式在記憶體中的執行次數。如果大家前面提到的配置,則記憶體中通常存在1個父程序與2個worker。如果大家需要更多worker,則可在.ini檔案中進行編輯以增加「workers」的數量。而後使用「sudo service uwsgi reload」命令以過載uwsgi。

在應用程式執行一段時間之後,檢查伺服器的記憶體使用量。

使用free -m命令以檢視緩衝區/快取與應用所使用的實際記憶體量。其中的關鍵值在於「free」列頂端的數字。在理想情況下,高強度伺服器幾乎會用掉全部記憶體。

如果大家發現仍有記憶體餘量但站點速度開始變慢,則應深入檢查是否存在其它問題。

另外,也有可能是分配給磁碟快取的記憶體容量太低。是否存在不必要的程序在占用記憶體?在預設情況下,linux會盡可能為磁碟快取分配更多記憶體,並在應用需要記憶體時及時將其釋放。

在理想狀態下,vps環境應該永遠不會出現記憶體限制,所有唯讀資產全部存在於快取當中。因此,請盡量去掉不必要的後台程序。

另外,也需要確保靜態檔案由web伺服器提供——而非django。

大家也掌握了如何利用uwsgi將djngo應用執行在web伺服器程序之外,從而實現效能提公升。(在這裡,推薦大家參閱如何實現卓越apache/uwsgi一文。)

最後,我們**了如何將盡可能多的記憶體分配給伺服器應用以提高資源利用率。

本文**自digitalocean community。英文原文:how to scale django: beyond the basics by matthew nuzum

翻譯:diradw

井通鏈有望實現規模化商用

井通公鏈因其智慧型合約的非同步呼叫和分層分片技術,效能似乎比以太坊更優,同時因為更多節點的rbft共識演算法,可接入的智慧型資產可以比ripple的範圍更廣。規模化商用是目前平台型公鏈的一致追求。從以太坊剛開始的pow機制到目前的pos機制,以及eos所採取的dpos機制,都是志在提高商用效能。井通...

mysql 規模化部署 sql mysql部署

配置檔案 設定mysql客戶端預設字符集 default character set utf8mb4 mysqld 設定3306埠 port 3306 設定mysql的安裝目錄 basedir d dev mysql 5.7.30 winx64 設定mysql資料庫的資料的存放目錄 datadir ...

Vue 30 規模化 狀態管理

由於多個狀態分散在不同的元件和元件直接的互動中,大型應用常常變得複雜。為了解決這個問題,vue提供了vuex 我們有受到elm啟發的狀態管理庫。它甚至整合進了vue devtools,無需配置即可進行時光旅行除錯。如果你來自react開發者,你可能想知道vuex和redux的差異,redux是flu...