1. 程式人生 > 其它 >網站靜態內容出版解決方案

網站靜態內容出版解決方案

目錄

  • 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請求也要考慮快取問題

首次訪問伺服器

  1. 訪問www伺服器
  2. nginx 判斷檔案是否存在,如果存在將檔案顯示出來
  3. 如果檔案不存在,去cms伺服器上查詢, 如果存在便返回給www伺服器,並顯示出來
  4. 如果cms上檔案不存在,cms伺服器便使用rewrite生成該檔案, 同時將內容返回給www伺服器,www將內容快取在自己的伺服器上,並將內容顯示出來

第二次訪問

  1. 訪問www伺服器
  2. nginx 判斷檔案是否存在,如果存在將檔案顯示出來
  3. 如果檔案不存在,去cms伺服器上查詢, 如果存在便返回給www伺服器,並顯示出來
  4. 如果cms上檔案不存在,cms伺服器便使用rewrite生成該檔案, 同時將內容返回給www伺服器,www將內容快取在自己的伺服器上,並將內容顯示出來

2. cdn

如何使用 cdn 來快取你的網站內容

讓你的網頁快取在 cdn 節點上的方式有下面幾種

  1. 讓cdn的客服幫你配置快取的規則, 他們很喜歡一刀切, 例如所有html都快取2小時
  2. 在他們管理後臺自行使用正則配置快取的時間, 這個他們一般不會提供, 某些公司的CDN會提供這個功能. 非常方便.
  3. 通過HTTP頭自行控制快取時間, 一般是使用 max-age / s-maxage / Last-Modified 判斷快取時間

我比較喜歡最後一種, 通常我們使用max-age 與 s-maxage 同時使用, 這樣我可以按照我的意向來決定檔案的快取時.

3. www 伺服器

下面給出一個精簡後的配置例子

如果檔案不存在就會連線後端cms伺服器生成檔案,並且顯示出來,同時加上快取. 生成的檔案會從cms中同步到www伺服器上.

你可以採用

  1. rsync同步方案
  2. nfs/samba/gluster 共享方案
  3. iscsi 共享儲存方案
  4. 分散式檔案系統方案

參考閱讀: 分散式檔案系統, 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 內容管理系統的主要功能

  1. 內容分類管理
  2. 內容模板管理
  3. 內容編輯與釋出
  4. 內容生成

服務應該實現

  1. 當發現目錄中檔案不存, 通過rewrite生成html, 這樣可能根據需要生成html頁面
  2. 當頁面更新的時候,應該通過api 重新整理cdn的快取, 圖片的版本好應該加一
  3. 將頁面分成多個模組, 通過SSI拼裝頁面, 避免有重大改版時, 整站生成HTML.
  4. 避免使用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