閱讀目錄javascript
一:nginx緩存配置php
在前一篇文章,咱們理解過http緩存相關的知識點, 請看這篇文章. 今天咱們來學習下使用nginx服務來配置緩存的相關的知識。css
nginx配置緩存的優勢:能夠在必定程度上,減小服務器的處理請求壓力。好比對一些圖片,css或js作一些緩存,那麼在每次刷新瀏覽器的時候,就不會從新請求了,而是從緩存裏面讀取。這樣就能夠減輕服務器的壓力。html
nginx可配置的緩存又有2種:
1)客戶端的緩存(通常指瀏覽器的緩存)。
2)服務端的緩存(使用proxy-cache實現的)。前端
客戶端的緩存通常有以下兩種方式實現:java
協商緩存和強緩存。具體理解什麼是協商緩存或強緩存,能夠看我以前的這篇文章.node
在配置以前,咱們來看下咱們的項目基本架構以下:jquery
|----項目demo | |--- .babelrc # 解決es6語法問題 | |--- node_modules # 全部依賴的包 | |--- static | | |--- index.html # html頁面 | | |--- css # 存放css文件夾 | | | |--- base.css # css文件,是從網上隨便複製過來的不少css的 | | |--- js # 存放js的文件夾 | | | |--- jquery-1.11.3.js # jquery 文件 | | |--- images # 存放images文件夾 | | | |-- 1.jpg # 圖片對應的文件 | |--- app.js # 編寫node相關的入口文件 | |--- package.json # 依賴的包文件
package.json 代碼以下:nginx
{ "name": "xxx", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "dev": "nodemon ./index.js" }, "license": "MIT", "devDependencies": {}, "dependencies": { "@babel/core": "^7.2.2", "@babel/preset-env": "^7.2.3", "@babel/register": "^7.0.0", "koa": "^2.7.0", "koa-static": "^5.0.0", "nodemon": "^1.19.0", "path": "^0.12.7" } }
app.js 代碼以下:git
import path from 'path'; import Koa from 'koa'; //靜態資源中間件 import resource from 'koa-static'; const app = new Koa(); const host = 'localhost'; const port = 7878; app.use(resource(path.join(__dirname, './static'))); app.listen(port, () => { console.log(`server is listen in ${host}:${port}`); });
index.js 代碼以下:
require('@babel/register');
require('./app.js');
index.html 代碼以下:
<!DOCTYPE HTML> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>前端緩存</title> <style> .web-cache img { display: block; width: 100%; } </style> <link href="./css/base.css" rel="stylesheet" /> <script type="text/javascript" src="./js/jquery-1.11.3.js"></script> </head> <body> <div class="web-cache"> 1111112224546664456999000 <img src="./images/1.jpg" /> </div> </body> </html>
如上就是一些基本的代碼結構,當咱們在nginx沒有配置任何的時候,咱們直接在命令行中運行 npm run dev 的時候,而後咱們在瀏覽器訪問 http://localhost:7878/ 時候,能夠看到無論我刷新多少次,瀏覽器下圖片,css,js全部的請求都會返回200,不會有任何緩存。以下所示:
如今咱們去我本地安裝的nginx中去配置下哦,打開nginx.conf配置文件。具體本地mac系統下安裝nginx,能夠去我以前的文章查看下如何安裝,mac下安裝nginx.
打開nginx.conf,使用 cat /usr/local/etc/nginx/nginx.conf (或者使用 sudo open /usr/local/etc/nginx/nginx.conf -a 'sublime text' 使用編輯器sublime打開)。
在nginx.conf加入以下規則:
server { location ~* \.(html)$ { access_log off; add_header Cache-Control max-age=no-cache; } location ~* \.(css|js|png|jpg|jpeg|gif|gz|svg|mp4|ogg|ogv|webm|htc|xml|woff)$ { # 同上,通配全部以.css/.js/...結尾的請求 access_log off; add_header Cache-Control max-age=360000; } }
如上配置解析含義以下:
~* 的含義是:通配任意字符(且大小寫不敏感),\轉義字符,所以 ~* \.(html)$的含義是:匹配全部以.html結尾的請求
access_log off; 的含義是 關閉日誌功能。
add_header Cache-Control max-age=no-cache; 的含義:html文件不設置強制緩存時間,協商緩存,使用 Last-Modified。no-cache 會發起往返通訊來驗證緩存的響應,但若是資源未發生變化,則不會下載,返回304。
以下圖所示:
add_header Cache-Control max-age=360000; 的含義給上面匹配後綴的文件設置強制緩存,且緩存的時間是360000秒,第一次訪問的時候,從服務器請求,當除了第一次之外,再次刷新瀏覽器,會從瀏覽器緩存讀取,那麼強制緩存通常是從內存裏面先讀取,若是內存沒有,再從硬盤讀取。
以下圖所示:
注意:如上只是不對反向代理的頁面進行緩存設置的,可是若是是反向代理後的頁面,如上設置是不生效的。好比說我node起了一個服務,而後經過訪問nginx反向代理的方式代理到我node服務來,上面的配置是不生效的。所以咱們須要以下處理配置。
解決nginx反向代理緩存不起做用的問題
好比我上面的node服務端口是7878端口。nginx須要以下配置:
server { listen 8081; server_name xxx.abc.com; location / { proxy_pass http://localhost:7878; add_header Cache-Control max-age=no-cache; } }
1) 若是咱們要添加緩存功能的話,須要建立一個用於存放緩存文件的文件夾。好比咱們這裏使用 /data/nuget-cache。
在/usr/local/etc/nginx目錄下新建。好比使用命令:mkdir /data/nuget-cache. 建立完成後,咱們來查看下:
2)而後咱們須要在nginx.conf的http設置部分添加 proxy_cache_path的設置,以下:
http { // ..... 其餘的配置 proxy_cache_path /data/nuget-cache levels=1:2 keys_zone=nuget-cache:20m max_size=50g inactive=168h; server { listen 8081; server_name xxx.abc.com; location / { proxy_pass http://localhost:7878; add_header Cache-Control max-age=no-cache; } } }
proxy_cache_path 各個配置值的含義解析以下:
proxy_cache_path 指緩存的目錄,目錄爲:/data/nuget-cache。
levels=1:2 表示採用2級目錄結構;
keys_zone 指的是緩存空間名稱,叫nuget-cache。緩存內存的空間爲20M。
max_size 指的是緩存文件能夠佔用的最大空間。爲50G.
inactive=168h; 默認過時時間爲168個小時。爲7天,也能夠寫成:inactive=7d; 這樣的。
3)咱們還須要在server設置部分添加 proxy_cache 與 proxy_cache_valid的設置:以下代碼:
http { // ..... 其餘的配置 proxy_cache_path /data/nuget-cache levels=1:2 keys_zone=nuget-cache:20m max_size=50g inactive=168h; server { listen 8081; server_name xxx.abc.com; location / { proxy_pass http://localhost:7878; add_header Cache-Control max-age=no-cache; proxy_cache nuget-cache; proxy_cache_valid 168h; } } }
proxy_cache 設置的是 proxy_cache_path中的keys_zone的值。
proxy_cache_valid:設置的是緩存過時時間,好比設置168個小時過時。
如上配置完成後,咱們保存nginx.conf配置後,從新啓動下nginx後,發現仍是不能緩存文件了。所以咱們還須要進行以下配置:
須要在server中再加上以下代碼:
proxy_ignore_headers Set-Cookie Cache-Control; proxy_hide_header Cache-Control; proxy_hide_header Set-Cookie;
proxy_ignore_headers的含義是:忽略Cache-Control的請求頭控制,依然進行緩存,好比對請求頭設置cookie後,默認是不緩存的,須要咱們增長忽略配置。
所以全部配置變成以下了:
http { // ..... 其餘的配置 proxy_cache_path /data/nuget-cache levels=1:2 keys_zone=nuget-cache:20m max_size=50g inactive=168h; server { listen 8081; server_name xxx.abc.com; location / { proxy_pass http://localhost:7878; add_header Cache-Control max-age=no-cache; proxy_cache nuget-cache; proxy_cache_valid 168h; proxy_ignore_headers Set-Cookie Cache-Control; proxy_hide_header Cache-Control; proxy_hide_header Set-Cookie; } } }
可是如上寫法看起來很繁瑣,所以咱們可使用include命令把文件包含進來,所以我在 /usr/local/etc/nginx 目錄下新建一個 nginx_proxy.conf 配置文件,把上面的 proxy相關的配置放到該文件裏面,以下所示:
而後咱們的配置就變成以下了:
http { // ..... 其餘的配置 proxy_cache_path /data/nuget-cache levels=1:2 keys_zone=nuget-cache:20m max_size=50g inactive=168h; include nginx_proxy.conf; server { listen 8081; server_name xxx.abc.com; location / { proxy_pass http://localhost:7878; add_header Cache-Control max-age=no-cache; } } }
如上是對頁面使用協商緩存的,可是對於圖片,css, 或js這樣的,我想使用強制緩存,所以對於其餘的類型文件咱們統一以下這樣處理:
server { listen 8081; server_name xxx.abc.com; location / { proxy_pass http://localhost:7878; add_header Cache-Control max-age=no-cache; } location ~* \.(css|js|png|jpg|jpeg|gif|gz|svg|mp4|ogg|ogv|webm|htc|xml|woff)$ { access_log off; add_header Cache-Control "public,max-age=30*24*3600"; proxy_pass http://localhost:7878; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } }
如上css或js文件等緩存的時間是30天。使用的是max-age強制緩存。所以如上,若是是頁面第二次訪問的話,會返回304,以下所示:
若是是css或js這樣的訪問的話,就是強制緩存了,狀態碼仍是200,可是先從內存裏面讀取的。固然若是進程結束了,好比瀏覽器關閉了,再打開,那麼是從硬盤上讀取的了。以下所示:
所以nginx.conf 全部的配置文件代碼以下:
worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; include nginx_proxy.conf; proxy_cache_path /data/nuget-cache levels=1:2 keys_zone=nuget-cache:20m max_size=50g inactive=168h; #gzip on; server { listen 8081; server_name xxx.abc.com; location / { proxy_pass http://localhost:7878; add_header Cache-Control max-age=no-cache; } location ~* \.(css|js|png|jpg|jpeg|gif|gz|svg|mp4|ogg|ogv|webm|htc|xml|woff)$ { access_log off; add_header Cache-Control "public,max-age=30*24*3600"; proxy_pass http://localhost:7878; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }
如上上面的css,js這些我時間設置短一點,好比設置60秒過時的話,那麼過時後,我再刷新瀏覽器,瀏覽器會去詢問服務器端,檢查資源是否被更新了,若是資源沒有被更新的話,那麼服務器端會範湖304.資源依然讀取本地的。以下所示:
而後再繼續刷新的話,它以後又從內存裏面讀取了。依次這樣循環下去。
二:nginx開啓gzip
開啓gzip配置是在http層加的。基本配置代碼以下:
# 開啓gzip gzip on; # 啓用gzip壓縮的最小文件;小於設置值的文件將不會被壓縮 gzip_min_length 1k; # gzip 壓縮級別 1-10 gzip_comp_level 2; # 進行壓縮的文件類型。 gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; # 是否在http header中添加Vary: Accept-Encoding,建議開啓 gzip_vary on;
咱們如上的配置加上去後,如在http下加上上面的gzip代碼:
http { # 開啓gzip gzip on; # 啓用gzip壓縮的最小文件;小於設置值的文件將不會被壓縮 gzip_min_length 1k; # gzip 壓縮級別 1-10 gzip_comp_level 2; # 進行壓縮的文件類型。 gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; # 是否在http header中添加Vary: Accept-Encoding,建議開啓 gzip_vary on; }
咱們能夠先來對比下,若是咱們沒有開啓zip壓縮以前,咱們的對應的文件大小,以下所示:
如今咱們開啓了gzip進行壓縮後的文件的大小,能夠看到以下所示:
而且咱們查看響應頭會看到gzip這樣的壓縮,以下所示