網站靜態內容出版解決方案
目錄
- 1. 架構總覽
- 2. cdn
- 3. www 伺服器
- 4. cms 伺服器
- 5. img
- 6. Ajax 區域性更新與快取
1. 架構總覽
www 負責靜態檔案瀏覽, 臺數不定, 可以採用零成本的DNS輪詢, 或者4層LVS, 或者7層HAProxy, 還可以用F5, Array 等負載均衡裝置.
cms 負責靜態檔案生成. 生成後的檔案要同步到www中, 或者採用網路共享, 再者使用分散式檔案系統, 總之將生成的檔案交給www伺服器, 根據你壓力橫向擴充套件即可
img 負責圖片檔案瀏覽. 通過給圖片加版本號, 結局圖片更新問題, 這樣更新網站不用頻繁重新整理 CDN
這裡不談論負載均衡, 以及儲存方案, 有情緒可以延伸閱讀: http://netkiller.github.com/architect/index.html
你掌握了這個方案, 你可以很容易實現 向"京東商城", "VANCL凡客誠品", "走秀網" 這樣的網站
這些網站的特點是: 瀏覽量大, 資料儲存主要是圖片, 登入/註冊與購物車,使用者中心 訪問量只佔到 5% 使用負責均衡很容易解決.
靜態化網站可不避免的使用ajax做區域性更新, ajax請求也要考慮快取問題
首次訪問伺服器
- 訪問www伺服器
- nginx 判斷檔案是否存在,如果存在將檔案顯示出來
- 如果檔案不存在,去cms伺服器上查詢, 如果存在便返回給www伺服器,並顯示出來
- 如果cms上檔案不存在,cms伺服器便使用rewrite生成該檔案, 同時將內容返回給www伺服器,www將內容快取在自己的伺服器上,並將內容顯示出來
第二次訪問
- 訪問www伺服器
- nginx 判斷檔案是否存在,如果存在將檔案顯示出來
- 如果檔案不存在,去cms伺服器上查詢, 如果存在便返回給www伺服器,並顯示出來
- 如果cms上檔案不存在,cms伺服器便使用rewrite生成該檔案, 同時將內容返回給www伺服器,www將內容快取在自己的伺服器上,並將內容顯示出來
2. cdn
如何使用 cdn 來快取你的網站內容
讓你的網頁快取在 cdn 節點上的方式有下面幾種
- 讓cdn的客服幫你配置快取的規則, 他們很喜歡一刀切, 例如所有html都快取2小時
- 在他們管理後臺自行使用正則配置快取的時間, 這個他們一般不會提供, 某些公司的CDN會提供這個功能. 非常方便.
- 通過HTTP頭自行控制快取時間, 一般是使用 max-age / s-maxage / Last-Modified 判斷快取時間
我比較喜歡最後一種, 通常我們使用max-age 與 s-maxage 同時使用, 這樣我可以按照我的意向來決定檔案的快取時.
3. www 伺服器
下面給出一個精簡後的配置例子
如果檔案不存在就會連線後端cms伺服器生成檔案,並且顯示出來,同時加上快取. 生成的檔案會從cms中同步到www伺服器上.
你可以採用
- rsync同步方案
- nfs/samba/gluster 共享方案
- iscsi 共享儲存方案
- 分散式檔案系統方案
參考閱讀: 分散式檔案系統, Netkiller Linux Storage 手札
upstream cms.mydomain.com {
server 192.168.2.11 weight=5 max_fails=3 fail_timeout=30s;
server 192.168.2.21 weight=5 max_fails=3 fail_timeout=30s;
server 192.168.2.23 backup;
server 192.168.2.23 down;
}
server {
listen 80;
server_name www.mydomain.com;
charset utf-8;
access_log /var/log/nginx/www.mydomain.com.access.log main;
location / {
root /www/mydomain.com/www.mydomain.com;
index index.html index.htm;
if ($request_uri ~* ".(ico|css|js|gif|jpe?g|png|html)$") {
expires 1d;
}
if ($request_uri ~* ".(xml|json)$") {
expires 1m;
}
valid_referers none blocked *.mydomain.com;
if ($invalid_referer) {
#rewrite ^(.*)$ http://www.mydomain.com/cn/$1;
return 403;
}
proxy_intercept_errors on;
if (!-f $request_filename) {
proxy_pass http://cms.mydomain.com;
break;
}
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /.ht {
# deny all;
#}
}
4. cms 伺服器
CMS 內容管理系統的主要功能
- 內容分類管理
- 內容模板管理
- 內容編輯與釋出
- 內容生成
服務應該實現
- 當發現目錄中檔案不存, 通過rewrite生成html, 這樣可能根據需要生成html頁面
- 當頁面更新的時候,應該通過api 重新整理cdn的快取, 圖片的版本好應該加一
- 將頁面分成多個模組, 通過SSI拼裝頁面, 避免有重大改版時, 整站生成HTML.
- 避免使用seesion技術, 這樣在負載均衡的時候可以使用最小連線數演算法
例如:
rewrite ^/product/(phone|notebook)/(d+).html /product/$1.php?id=$2 last;
URL 唯一, url設計要考慮唯一性, 不要出現同一個url處理兩個任務, 例如下面的例子, 每個使用者的profile一個URL, 當被訪問的時候便可以快取在CDN或者使用者瀏覽器上.
http://www.mydomain.com/profile/neo.html
http://www.mydomain.com/profile/jam.html
server {
listen 80;
server_name www.mydomain.com;
#charset koi8-r;
access_log /var/log/nginx/www.mydomain.com.access.log main;
location / {
root /www/mydomain.com/www.mydomain.com;
index index.html;
}
}
server {
listen 80;
server_name cms.mydomain.com;
charset utf-8;
access_log /var/log/nginx/cms.mydomain.com.access.log main;
location / {
root /www/mydomain.com/cms.mydomain.com;
index index.html index.php;
}
location ~ ^/(cn|tw)/(comment|affiche)/.*.html {
root /www/mydomain.com/www.mydomain.com;
if (!-f $request_filename) {
rewrite ^/(cn|tw)/(comment|affiche)/(d+).html /publish/$2.php?id=$3&lang=$1 last;
}
}
location /xml/ {
root /www/mydomain.com/www.mydomain.com/xml;
}
location ~ ^/(config|include|crontab)/ {
deny all;
break;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ .php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ .php$ {
root /www/mydomain.com/cms.mydomain.com;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /www/mydomain.com/cms.mydomain.com$fastcgi_script_name;
include fastcgi_params;
fastcgi_param DOCUMENT_ROOT /www/mydomain.com/cms.mydomain.com;
fastcgi_param HOSTNAME cms.mydomain.com;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
location ~ /.ht {
deny all;
}
}
5. img
img.mydomain.com
server {
listen 80;
server_name img.mydomain.com;
charset utf-8;
access_log /var/log/nginx/img.mydomain.com.access.log main;
location ~ .*.(gif|jpg|jpeg|png|bmp|swf|ico)$
{
expires 7d;
}
location ~ .*.(js|css)$
{
expires 1d;
}
location ~ .*.(html|htm)$
{
expires 15m;
}
location / {
root /img/mydomain.com/img.mydomain.com;
index index.html;
rewrite "/theme/([0-9] {4})([0-9] {2})([0-9] {2})/(.+).(.+).(.+)" /theme/$1/$2/$3/$4.$6;
rewrite "/news/([0-9] {4})([0-9] {2})([0-9] {2})/(.+).(.+).(.+)" /news/$1/$2/$3/$4.$6;
rewrite "/product/([0-9] {4})([0-9] {2})([0-9] {2})/(.+).(.+).(.+)" /product/$1/$2/$3/$4.$6;
}
}
/theme/2012/08/15/images.1.jpg 實際上就是 /theme/2012/08/15/images.jpg 檔案
/theme/2012/08/15/images.2.jpg 也是 /theme/2012/08/15/images.jpg
/theme/2012/08/15/images.3.jpg 也是 /theme/2012/08/15/images.jpg
但CDN與你的瀏覽器會每次下載新的檔案, 這樣只要更新CDN中的html頁面即可, 不用去理睬圖片, 你的瀏覽器會用新的地址下載圖片. 這樣就解決了煩瑣的重新整理工作.
6. Ajax 區域性更新與快取
例如我的新聞評論頁面,需要使用ajax技術, 將使用者回覆的品論顯示來, ajax 載入json資料然後區域性更新, 我對他做了1分鐘的快取
if ($request_uri ~* ".(xml|json)$") {
expires 1m;
}
如果有新的提交我們可以為json增加版本是控制例如: http://api.mydomain.com/news.json?1.0