原創(chuàng)丨如何大幅提高 Django 網(wǎng)站加載速度
閱讀本文大概需要 1 分鐘。
之前做了個(gè)爬蟲案例平臺(tái),https://scrape.center/,具體文章在?原創(chuàng)丨發(fā)布一個(gè)爬蟲案例平臺(tái),幫助爬蟲初學(xué)者進(jìn)行練手。
平臺(tái)內(nèi)我設(shè)計(jì)了非常多的網(wǎng)站,有服務(wù)端渲染、客戶端渲染等,其中服務(wù)端渲染的頁(yè)面大家可能爬取的頻率比較高,時(shí)不時(shí)就會(huì)遇到被爬掛的情況。
比如這個(gè)網(wǎng)站:https://ssr1.scrape.center/,當(dāng)訪問(wèn)頻率高的時(shí)候,甚至我后端開了 20 個(gè) Pod 也承受不來(lái),大家并發(fā)量有點(diǎn)猛啊。
這個(gè)后端是用 Django 寫的,而且這個(gè)網(wǎng)站的數(shù)據(jù)不怎么更新,索性再加個(gè) Cache 吧,在 Django 中最高效的 Cache 當(dāng)屬 Memcached 了,本篇文章就來(lái)簡(jiǎn)單記錄下 Django 對(duì)接 Memcached 的過(guò)程。
官方資料
千說(shuō)萬(wàn)說(shuō)都不如官方文檔來(lái)的直接,首推官方文檔:https://docs.djangoproject.com/en/3.1/topics/cache/。
然后后面就是我簡(jiǎn)單的筆記了。
依賴庫(kù)
首先需要安裝個(gè)依賴庫(kù),這里用的是 python-memcached,可以使用 pip 來(lái)安裝:
pip3?install?python-memcached
由于我使用的是 Docker,所以就把它寫到 requirements.txt 里面了。
配置
另外還需要在 settings.py 里面配置一下,內(nèi)容如下:
CACHES?=?{
????'default':?{
????????'BACKEND':?'django.core.cache.backends.memcached.MemcachedCache',
????????'LOCATION':?'cache:11211',
????}
}
這里 LOCATION 是需要一個(gè) Memcached 服務(wù),運(yùn)行在 11211 上面。
另外還需要開啟兩個(gè)中間件:
MIDDLEWARE?=?[
????'django.middleware.cache.UpdateCacheMiddleware',
????...
????'django.middleware.cache.FetchFromCacheMiddleware',
]
這里要加兩個(gè)中間件,一個(gè)在最前面,一個(gè)在最后面,順序不能換,中間的是之前配置的其他中間件。
Docker-Compose
OK,接下來(lái)就是使用 Docker 啟動(dòng)了,這里 Docker-Compose 里面就需要增加一個(gè) Memcache 服務(wù),配置如下:
version:?'3'
services:
??ssr1-backend:
????container_name:?'scrape-ssr1-backend'
????restart:?always
????build:?./backend
????image:?'scrape-ssr1-backend'
????ports:
??????-?'8000:8000'
????environment:
??????...
??cache:
????image:?memcached
????ports:
??????-?'11211:11211'
????entrypoint:
??????-?memcached
??????-?-m?64
這里主要是 cache 的配置,需要加上端口映射和入口參數(shù),這里內(nèi)存大小設(shè)置為 64M。
Kubernetes
我的部署使用的是 Kubernetes,所以對(duì)應(yīng)的 yaml 文件也需要更改了,配置更改如下:
apiVersion:?v1
items:
??-?apiVersion:?v1
????kind:?Service
????metadata:
??????annotations:
????????kompose.cmd:?kompose?-f?docker-compose.yml?-o?kubernetes.yml?convert
????????kompose.version:?1.20.0?()
??????creationTimestamp:?null
??????labels:
????????io.kompose.service:?ssr1-backend
??????name:?ssr1-backend
??????namespace:?scrape
????spec:
??????ports:
????????-?name:?"8000"
??????????port:?8000
??????????targetPort:?8000
??????selector:
????????io.kompose.service:?ssr1-backend
????status:
??????loadBalancer:?{?}
??-?apiVersion:?apps/v1
????kind:?Deployment
????metadata:
??????annotations:
????????kompose.cmd:?kompose?-f?docker-compose.yml?-o?kubernetes.yml?convert
????????kompose.version:?1.20.0?()
??????creationTimestamp:?null
??????labels:
????????io.kompose.service:?ssr1-backend
??????name:?ssr1-backend
??????namespace:?scrape
????spec:
??????replicas:?20
??????revisionHistoryLimit:?1
??????strategy:?{?}
??????selector:
????????matchLabels:
??????????io.kompose.service:?ssr1-backend
??????template:
????????metadata:
??????????annotations:
????????????kompose.cmd:?kompose?-f?docker-compose.yml?-o?kubernetes.yml?convert
????????????kompose.version:?1.20.0?()
??????????creationTimestamp:?null
??????????labels:
????????????io.kompose.service:?ssr1-backend
????????spec:
??????????containers:
????????????-?env:
????????????????-?name:?APP_ENV
??????????????????value:?production
????????????????-?name:?MEMCACHED_HOST
??????????????????value:?ssr1-cache
??????????????image:?germey/scrape-ssr1-backend:${TAG}
??????????????name:?scrape-ssr1-backend
??????????????ports:
????????????????-?containerPort:?8000
??????????????resources:?{?}
??????????restartPolicy:?Always
????status:?{?}
??-?apiVersion:?v1
????kind:?Service
????metadata:
??????annotations:
????????kompose.cmd:?kompose?-f?docker-compose.yml?-o?kubernetes.yml?convert
????????kompose.version:?1.20.0?()
??????creationTimestamp:?null
??????labels:
????????io.kompose.service:?ssr1-cache
??????name:?ssr1-cache
??????namespace:?scrape
????spec:
??????ports:
????????-?name:?"11211"
??????????port:?11211
??????????targetPort:?11211
??????selector:
????????io.kompose.service:?ssr1-cache
????status:
??????loadBalancer:?{?}
??-?apiVersion:?apps/v1
????kind:?Deployment
????metadata:
??????annotations:
????????kompose.cmd:?kompose?-f?docker-compose.yml?-o?kubernetes.yml?convert
????????kompose.version:?1.20.0?()
??????creationTimestamp:?null
??????labels:
????????io.kompose.service:?ssr1-cache
??????name:?ssr1-cache
??????namespace:?scrape
????spec:
??????replicas:?1
??????revisionHistoryLimit:?1
??????strategy:?{?}
??????selector:
????????matchLabels:
??????????io.kompose.service:?ssr1-cache
??????template:
????????metadata:
??????????annotations:
????????????kompose.cmd:?kompose?-f?docker-compose.yml?-o?kubernetes.yml?convert
????????????kompose.version:?1.20.0?()
??????????creationTimestamp:?null
??????????labels:
????????????io.kompose.service:?ssr1-cache
????????spec:
??????????containers:
????????????-?image:?memcached
??????????????name:?scrape-ssr1-cache
??????????????ports:
????????????????-?containerPort:?11211
??????????????resources:?{?}
??????????restartPolicy:?Always
????status:?{?}
kind:?List
metadata:?{?}
---
apiVersion:?networking.k8s.io/v1beta1
kind:?Ingress
metadata:
??name:?ingress-ssr1
??namespace:?scrape
??annotations:
????nginx.ingress.kubernetes.io/ssl-redirect:?"true"
????nginx.ingress.kubernetes.io/rewrite-target:?/
spec:
??tls:
????-?hosts:
????????-?ssr1.scrape.center
??????secretName:?tls-wildcard-scrape-center
??rules:
????-?host:?ssr1.scrape.center
??????http:
????????paths:
??????????-?backend:
??????????????serviceName:?ssr1-backend
??????????????servicePort:?8000
????????????path:?/
注意這里我給 Django 后端增加了一個(gè)環(huán)境變量,叫做 MEMCACHED_HOST,所以在 Django 中,我們可以通過(guò)環(huán)境變量來(lái)讀取 Memcached 的 Host,當(dāng)然端口也可以類似設(shè)置,不過(guò)端口我就直接寫死了,配置更改如下:
CACHES?=?{
????'default':?{
????????'BACKEND':?'django.core.cache.backends.memcached.MemcachedCache',
????????'LOCATION':?os.getenv('MEMCACHED_HOST')?+?':11211',
????}
}
OK,這樣改完之后重新部署就好了。
部署之后我直接將 Pod 降到了 2 個(gè),第一次訪問(wèn)速度可能稍慢,但是一旦加載出來(lái)之后,該頁(yè)面就會(huì)被緩存下來(lái),后續(xù)訪問(wèn)速度就只有兩三百毫秒了,測(cè)速如下:
網(wǎng)址在這:https://ssr1.scrape.center/,大家可以來(lái)爬爬試試吧。
崔慶才丨靜覓
隱形字
同名公眾號(hào)「崔慶才丨靜覓」
在這里分享自己的一些經(jīng)驗(yàn)、想法和見(jiàn)解。
長(zhǎng)按識(shí)別二維碼關(guān)注



