寫到這,越寫越拖抬了... 這次沒有加上任何 "新功能",有的只是修正使用上的一些問題而以...
首先,還是要感謝愛用者 小熊子 的回報,照片初次被下載時會觸發上傳到 Flickr 的動作,上傳完成才重新引導 Request 到 Flickr 存取照片。如果在這一連串動作尚未完成前,就有第二個 Request 跑來的話,那這張照片就會被傳到 Flickr 兩次...。Orz,枉費我還投搞這些並行處理的文章,怎麼可以犯這種錯...
就跟很多 BUG 一樣,難在沒想到,難在沒發現,難在不知道原因...,不然修正 BUG 倒是很簡單的事,感謝回報這個 BUG 的恩公... 找到問題後剩下的 ISSUE 就迎刃而解了,要做的就是把關鍵的程式碼包裝在臨界區 (CRITICAL SECTION) 內,以防這段 CODE 同時間執行多次。這段 CODE 不能太大,鎖定範圍太大會影響效能 (好不容易換了四核CPU,鎖太大就糟踏這顆 CPU 了...),最後找出關鍵應該是 [判定是否需要上傳到 FLICKR] 及 [建立 FLICKR 副本檔] 這兩個動作,一定要包括在內,拆開的話就不能保證結果正確了。
1: string flickrURL = null;
2: lock (this.GetType())
3: {
4: if (File.Exists(this.CacheInfoFile) == false)
5: {
6: //
7: // CACHE INFO 不存在,重新建立
8: //
9: this.BuildCacheInfoFile(context);
10: context.Response.AddHeader("X-FlickrProxy", "Upload");
11: }
12: }
寫好後,這段 CODE 越看越不順眼,雖然我的網站流量沒那麼大啦 [H],不過怎麼可以這麼短視... 這段 CODE 的問題還是一樣,鎖定的範圍 "太大了" !! 會嚴重影響效能.. (如果流量真的很大的話)
怎麼說? 不過才兩行,那到底是要縮到多小? 不不,問題其實不在於 LOCK 的區段到底有多少 CODE,而是該 LOCK 的只有對同一張照片的 Http Request 才該被阻檔下來,同時間有多個 Http Request 來下載不同張照片,以現在的點閱率來說我應該要高興吧... 幹嘛還去 LOCK 它? 不過上面的 CODE 就是在做這件事,不分青紅皂白只要是有上傳到 FLICKR 的動作就一率 LOCK。更糟的是如果有一張照片正在上傳中,其它照片的 Http Request 也都會被迫停下來等它傳完...
該要有個改進的版本了。LOCK過度也是初次碰到 Multi-threading Programming 的人很容易犯的錯誤,接下來看看第二個版本:
1: lock (this.LockHandle)
2: {
3: if (File.Exists(this.CacheInfoFile) == false)
4: {
5: //
6: // CACHE INFO 不存在,重新建立
7: //
8: this.BuildCacheInfoFile(context);
9: context.Response.AddHeader("X-FlickrProxy", "Upload");
10: }
11: }
看起來只有第一行 LOCK STATEMENT 裡指定的物件不一樣而以。沒錯,這裡跟第一段 CODE 的差別只在於 LOCK 的標的物不一樣。同一個物件只能被 LOCK 一次,當物件被 LOCK 還沒放開時,第二個人想要 LOCK 同一個物件,很抱歉... 得先等第一個人願意放掉它才可以。LOCK不同物件就各不相干了。沒錯,這就是我要的邏輯。所以這個問題的關鍵在於,我如何讓每張照片有專屬的 "物件" 來 LOCK ?
檔名的字串物件? 不適合... 可能有多個字串值相同,但是是不同物件... FileInfo? 也不行,因為找不到文件會保證同一個檔案拿到的 FileInfo 物件會是同一個... 沒辦法,只好自己弄一個。來看一下 LockHandle 的實作:
1: private object LockHandle
2: {
3: get
4: {
5: string hash = this.GetFileHash();
6: lock (_locks)
7: {
8: if (_locks.ContainsKey(hash) == false)
9: {
10: _locks.Add(hash, new object());
11: }
12: }
13: return _locks[hash];
14: }
15: }
16: private static Dictionary<string, object> _locks = new Dictionary<string, object>();
其實以值來說,拿檔名就足夠拿來示別了,只不過有大小寫的問題要處理。拿檔案的內容做 MD5 實在有點殺雞用牛刀,不過因為處理照片本來就需要算檔案的 MD5 了,現成的就拿來用一下...。這裡我簡單的做了個 Dictionary,就放沒什麼用的 OBJECT,我只要這個 PROCESS 在有生之年,同一個檔案都會拿到同一個 OBJECT 就足夠了...
都寫到這還有什麼不滿意的? 還是有... 哈哈。因為我在測試時有過一個頁面,同一頁會放一堆圖檔...。試想一下當我瀏覽這頁面會發生什麼事?
"同時間 IE 發出了數個 HttpRequest 來跟我的程式要圖檔,如果正巧都是第一次,嗯,有限的頻寬要一次上傳多張圖檔到 Flickr,不就更慢了?"
就算我的頻寬沒問題,同一瞬間這麼多 UPLOAD 的動作,引起 Flickr 的 "關切" 就不好了... 我是不是應該要限制一下同時上傳的數量才對? 就像 FlashGet 可以限制同時下載的數量一樣...
哈,不就是之前寫過的文章,用 SEMAPHORE ? 沒錯... 怎麼老覺的這篇像在替我其它文章打廣告用的... 事實上不見得要動用到 SEMAPHORE,如果你要限制的是一次只能一個 UPLOAD 動作,直接用各種的 LOCK 機制就夠了。如果你要限制並行的 UPLOAD 動作是兩個以上,甚至更動態隨著 LOADING 變化等等,才需要動用到 SEMAPHORE ...
既然要 DEMO,就 DEMO 實際一點的 CODE 吧。假設我要限制並行 UPLOAD 的數量不超過 2 個,則需要把 CODE 改成這樣。首先要先準備好 SEMAPHORE 物件:
1: public static Semaphore FlickrUploaderSemaphore = new Semaphore(2, 2);
真正執行上傳動作的部份要加上 SEMAPHORE 的管控:
1: FlickrUploaderSemaphore.WaitOne();
2: photoID = flickr.UploadPicture(this.FileLocation);
3: FlickrUploaderSemaphore.Release();
嗯,真是小題大作,不過這種機會不拿來練習練習,真正碰到怎麼寫的出來? 如果各位對於在 ASP.NET 上怎麼使用 LOCK 及 SEMAPHORE 不大熟的,可以參考一下我投稿的文章... 萬分感謝 [:D]
由於在使用 Flickr API 時, 老是碰到上傳成功後, 結果拿到的照片 URL 不能看的問題... 被它整了好久, 不過總算解決了 @_@... 原來 API 拿到的資料是錯的, 嘖...
說來話長, 不過既然花時間解決了就要記錄一下... 問題大概是這樣. 上傳照片完成之後可以拿到 photoId, 代表某一張放在 Flickr 上的照片. 之後透過 PhotosGetInfo(photoId) 這個 API 可以取得這張照片的相關資訊, 當然也有 MediumUrl, LargeUrl... 等等 properties 可以用.
很直覺嘛, 要秀大圖我就直接拿 LargeUrl 就好, 偏偏有時是好的, 有時是壞的... API 傳回來的東西應該不會錯吧? 我心裡是這樣想的. 不過跟 Flickr 網站的 url 對照一下才發現, 竟然有時是不同的... 一路追下去, google 跟作者在 codeplex 網站上的 forums 都找了, 才發現...
PhotosGetInfo( ) 抓到的只是一堆 ID, 然後用 Flickr 公布的網址格式 "湊" 出各種 URL. 然而過去 Flickr 層經有一次改變部份網址的格式, 當你的圖檔不是很大時, Flickr 判定沒有另外存一張大圖的需要了, 就直接跳到原圖 (original size). 而原圖的網址格式又不一樣, 因此當圖檔太小時, API 抓到的 LargeUrl 就會是錯的...
My God,.... 為了這種鳥問題害我多白了好幾根頭髮... 找到原因後找 solution 就簡單了. 因應這個問題, 也多了一組 API: PhotosGetSizes( ), 直接連回 Flickr 明確的查詢可用的 size 有幾種, 連同它的網址及一堆相關資訊一起傳回來... 改用這個 API 傳回的資訊, 結果就正確了, 沒有圖掛掉的問題... Orz
不能怪人家 API 寫的不好, 只能怪自己功課沒作足... 不看文件直接拿 API 就用, 看名字猜用法才會這樣.. code 改一改就 ok 了, 少了這個不確定性, 原本畫蛇添足加上去的確認圖檔的動作也不用了.. 貼一下修改前跟修改後的 code:
1: PhotoInfo pi = flickr.PhotosGetInfo(photoID);
2: string flickrURL = null;
3: string size = null;
4: try
5: {
6: flickrURL = this.CheckFlickrUrlAvailability(pi.MediumUrl);
7: size = "medium";
8: flickrURL = this.CheckFlickrUrlAvailability(pi.LargeUrl);
9: size = "large";
10: flickrURL = this.CheckFlickrUrlAvailability(pi.OriginalUrl);
11: size = "original";
12: }
13: catch { }
1: foreach (Size s in flickr.PhotosGetSizes(photoID).SizeCollection)
2: {
3: XmlElement elem = null;
4: elem = cacheInfoDoc.CreateElement("size");
5: elem.SetAttribute("label", s.Label);
6: elem.SetAttribute("source", s.Source);
7: elem.SetAttribute("url", s.Url);
8: elem.SetAttribute("width", s.Width.ToString());
9: elem.SetAttribute("height", s.Height.ToString());
10: cacheInfoDoc.DocumentElement.AppendChild(elem);
11: }
嗯, 終於搞定. FlickrProxy 正式邁入實用的階段... 收工!
整個進度算是很順利,初版已經可以運作了,而且也成功的套用在小熊子的 BLOG 上... 因為過去已經有幾個類似的 HttpHandler 的 code 可以直接拿來改了,反而真正的瓶頸是在瞭解如何操控 FlickrNet 這個 .NET 版的 Flickr API 身上 Orz。FlickrNet 碰到的問題後面再說明,先來看一下整個 Project 的源頭: system design。
這個程式的目標很明確,就是我不想改變任何的使用習慣,我要讓 blogger (比如我家大人) 完全不用理會 flickr 這東西的存在,也不需要在寫文章時去傷腦筋該把照片先放到 Flickr 然後再放到網頁上這類瑣事.. 因此我需要的是在 blog server 上有某些自動的機制,能夠自動把照片丟到 flickr 上,也能夠自動的把網頁上要顯示的照片轉到 flickr 那邊。而必要時,這些機制都能夠取消或調整,不會影響到 blog 的資料等等問題。
初步的想法就是從接手這些圖檔的 HttpHandler 著手。如果前端 (BROWSER) 到 BLOG SERVER 上要求下載照片的要求都能經過我的控制,理論上我就能達成這個目的。因為前端的 Http Request 不需要修改,因此我這次的任務不需要像黑暗大哥那樣辛苦的去調整每一頁的 HTML code (雖然我的方法也沒多輕鬆.. Orz),這是我決定採用這個方式的主要優點。HTML不用改,我也不用改變原本上傳圖檔的方式,因此所有的調整都不會影響到最重要的 DATA,所有改變都是可以還原的。
負責處理照片的 Http Handler 只要能依照這流程作事就夠了,因此等等會看到的程式碼也是很簡單:
這樣就完成了。我把它畫成 UML Sequency Diagram:
接下來就是看 Code 了,寫這樣的程式,關鍵有幾個,大部份都是 IIS / ASP.NET 的設定要正確,讓 IIS 能把 REQUEST 轉到你的程式,剩下的就沒什麼特別的了。對 HttpHandler 不熟的人可以先參考一下這幾篇 ( From MSDN ):
How to: Configure an HTTP Handler Extension in IIS
How to: Register HTTP Handlers
HTTP Handlers and HTTP Modules Overview
Walkthrough: Creating a Synchronous HTTP Handler
在 IIS 上寫這些東西,比較麻煩的是 configuration,反而不是程式... 初學者常會卡在這裡,而這部份的行為正好又跟 Visual Studio 內建的 DevWeb 差很多 (真的差很多... 有時連抓到的 Path Info 都會不一樣 @_@),強烈建議開發階段就直接在 IIS 上面開發...
要克服的第一個設定,就是 IIS。預設情況下,IIS 看到圖檔的 request,毫不考慮就會把內容丟回去了,你程式怎麼寫都沒機會攔到,所以要在應用程式對應這邊,先把 *.JPG 的控制權交給 .NET Framework 的 ISAPI filter ..
有兩個選擇,你心藏夠力的話可以把所有的 Request 都指到 .NET Framework,或是只指定 .JPG 就好。我這邊是以 .JPG 為例:
仔細看一下可以發現,其實所有 ASP.NET 的附檔名,通通都是指向同一個 ISAPI Filter: aspnet_isapi.dll。至於每一種附擋名會有什麼不同的行為,那是 .NET 自己關起門來解決的事,這邊不用傷腦筋... 直接 COPY 別的設定過來最快..
IIS 的部份搞定了,如果現在就透過 IIS 去看網站上的 .JPG,全部都會破圖... 因為所有的 Request 全都被 .NET 接管了。除非你整個 WEB APP 的 .JPG 都要透過你的 HTTP HANDLER,否則請先在 WEB.CONFIG 裡加上這段:
加在 /configuration/system.web/httpHandlers 下 (這是 XPath):
1: <httpHandlers>
2: <add path="*.jpg" verb="*" type="System.Web.StaticFileHandler" />
3: </httpHandlers>
System.Web.StaticFileHandler 是 ASP.NET 內建的,是跟 IIS 預設一樣的行為,就是原封不動的把檔案的 BINARY DATA 照傳回去而以。預設的還有其它幾個,Forbidden 等等的都可以用同樣的方式指定。
這一段加上去等於繞了一圈,IIS把 .JPG 交給 ASP.NET,而 ASP.NET 又原封不動的傳了回去。沒錯,一切都是為了後面作準備... 接下來要把未來會放照片的目錄,重新指定 HttpHandler。我的例子是 ~/storage 下的 *.JPG 通通都要轉到 Flickr,因此我在 Web.config 加上這段 (當然,你直接放在 ~/storage/web.config 也是可以):
1: <location path="storage">
2: <system.web>
3: <httpHandlers>
4: <add path="*.jpg" verb="*" type="ChickenHouse.Web.HttpHandlers.FlickrProxyHttpHandler,App_Code" />
5: </httpHandlers>
6: </system.web>
7: </location>
設定的部份大功告成,剩下的就是程式碼了。看一下主要的部份:
1: //
2: // 確認 CACHE 目錄已存在
3: //
4: if (Directory.Exists(this.CacheFolder) == false)
5: {
6: Directory.CreateDirectory(this.CacheFolder);
7: }
8: XmlDocument cacheInfoDoc = new XmlDocument();
9: string flickrURL = null;
10: if (File.Exists(this.CacheInfoFile) == false)
11: {
12: //
13: // CACHE INFO 不存在,重新建立
14: //
15: flickrURL = this.BuildCacheInfoFile(context);
16: }
17: else
18: {
19: //
20: // CACHE INFO 已經存在。確認 CACHE 的正確性後就可以直接導到 FLICKR URL
21: //
22: string cacheKey = "flickr.proxy." + this.GetFileHash();
23: flickrURL = context.Cache[cacheKey] as string;
24: if (flickrURL == null)
25: {
26: cacheInfoDoc.Load(this.CacheInfoFile);
27: flickrURL = cacheInfoDoc.DocumentElement.GetAttribute("url");
28: context.Cache.Insert(
29: cacheKey,
30: flickrURL,
31: new CacheDependency(this.CacheInfoFile));
32: }
33: }
34: context.Response.Redirect(flickrURL);
刪掉了一些無關緊要的 CODE。主程式很簡單,就上面提到了邏輯而以。想辦法取得照片在 Flickr 那邊的正確網址,Redirect回去就好。如何得知網址? 第一次如何把照片傳上去? 這次來看看主角: BuildCacheInfoFile。
1: private string BuildCacheInfoFile(HttpContext context)
2: {
3: Flickr flickr = new Flickr(
4: ConfigurationManager.AppSettings["flickrProxy.API.key"],
5: ConfigurationManager.AppSettings["flickrProxy.API.security"]);
6: flickr.AuthToken = ConfigurationManager.AppSettings["flickrProxy.API.token"];
7: string photoID = flickr.UploadPicture(this.FileLocation);
8: PhotoInfo pi = flickr.PhotosGetInfo(photoID);
9: string flickrURL = null;
10: try
11: {
12: flickrURL = this.CheckFlickrUrlAvailability(pi.MediumUrl);
13: flickrURL = this.CheckFlickrUrlAvailability(pi.LargeUrl);
14: flickrURL = this.CheckFlickrUrlAvailability(pi.OriginalUrl);
15: }
16: catch { }
17: XmlDocument cacheInfoDoc = new XmlDocument();
18: cacheInfoDoc.LoadXml("<proxy />");
19: cacheInfoDoc.DocumentElement.SetAttribute(
20: "src",
21: this.FileLocation);
22: cacheInfoDoc.DocumentElement.SetAttribute(
23: "url",
24: flickrURL);
25: cacheInfoDoc.DocumentElement.SetAttribute(
26: "photoID",
27: photoID);
28: cacheInfoDoc.Save(this.CacheInfoFile);
29: return flickrURL;
30: }
寫這段,其實時間都花在怎麼用 Flickr API。Flickr API 很重視使用者的安全。認證部份一定要使用者親自到 Flickr 網站登入,同時按下授權後,API才能正常使用。經過這一連串動作,可以拿到三組序號:
其中 (1) 及 (2) 是使用者要自己到 Flickr 網站申請的 (http://www.flickr.com/services/api/keys),第三個 TOKEN 就是要程式呼叫過程中會要求使用者連上網啟用後才能得到的。這邊我沒另外寫程式,我是直接用 FlickrNet 的作者提供的 SAMPLE CODE,照著操作就可以拿到 TOKEN 了。
有了這三段序號 API 才能正常運作。之後只要上傳 (第七行) 取得 photoID 回來就算完成。接下來第 12 行取得網址就 OK 了。
不過這邊也是卡最久的地方... 有人說 flickr server 忙的時後連到照片網址,有時會出現 "photo not available" 的訊習,有時又正常。有人則說某些照片只會有特定 SIZE,像是 original / large size 的有時也會發生 "photo not available" 的狀況...
試了幾次,實在是抓不出它的規則,也找不出避開的辦法... 只好硬著頭皮,每個取得的網址就都用 HTTP 硬給它試看看... 因為 Flickr API 取得網址的 property 在失敗時會丟出 EXCEPTION,因此這段 code 寫成這樣:
1: try
2: {
3: flickrURL = this.CheckFlickrUrlAvailability(pi.MediumUrl);
4: flickrURL = this.CheckFlickrUrlAvailability(pi.LargeUrl);
5: flickrURL = this.CheckFlickrUrlAvailability(pi.OriginalUrl);
6: }
7: catch { }
CheckFlickrUrlAvailability() 是我自己寫的,就是真正連到 Flickr 判定到底照片能不能從這網址下載... 任一行只要發生 EXCEPTION 就會跳出,flickrURL 變數就可以保留最後一個 (最大) 可用的網址...。
好,程式碼看完了... 最後來看看測試網站。我放了一個很簡單的網頁,簡單的幾行 HTML,加上一張圖。
1: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2:
3: <html xmlns="http://www.w3.org/1999/xhtml">
4: <head>
5: <title>Untitled Page</title>
6: </head>
7: <body>
8:
9: <hr />
10:
11: <img src="smile_sunkist.jpg" alt="test image" />
12:
13: <hr />
14:
15:
16: </body>
17: </html>
網頁上看到的結果:
這有啥好看的? 只是證明 USER 看起來完全正常而以... 哈哈,拿出 Fiddler 看一下:
#0 及 01 都是正常情況下就會有的 HTTP REQUEST,代表 IE 要下載 HTML 跟 JPG。不過在下載 JPG 檔,卻收到了 302 (OBJECT MOVE) 的重新導向的結果,因此 IE 就接著再到 Flickr 去下載照片,最後秀在網頁上。不過照片真的有出現在 Flickr 上嗎? 用我的帳號登入看看...
哈哈,果然出現了。看來這沒幾行的 CODE 真正發恢它的作用了。網站什麼都不用改,只要加上這 HttpHandler,配合調一些設定,馬上下載圖片的頻寬就省下來了。不過最少還是得花一次頻寬啦。BLOGGER把圖檔傳上來就不說了,圖檔第一次有人來看的時後,程式還是需要把檔案傳出去,放到 Flickr 上。不過一旦放成功了,以後第二次第三次.... 的頻寬就都省下來了。要花的只有 Fiddler 抓到的 #1 那少少的 302 REDIR 回應而以。
這個 Project 告一段落,後續還是會繼續改進,不過就都是小地方的調整,一些重構及把舊的 code 整理在一起的動作而以。對程式碼有興趣的人可以再跟我聯絡。
久久沒動手寫 code,手又開始癢了... 前陣子跟小熊子聊的時後想到一個新的 IDEA,就順手記下來。像我們這種自己用ADSL架的小型網站,瓶頸都是卡在頻寬。愛拍照的小熊子最在意的當然就是網站擺照片所需要的頻寬... 解決方式其實有一堆,像是 Live Writer 就有個很有名的 PLUGIN,可以直接插入你放在 Flickr 的照片...
其實這類的 solution 很多,但是用起來就覺的不大喜歡,怎麼說? 倒不是說軟體不好用,而是它的作法。這類 plug-ins 都是幫你一次把事情作好,幫你上傳到 flickr,幫你查出 link,幫你產生HTML片段,貼到 WLW... 這種作法的問題在於你張貼文章時,這些資訊就得確定下來。你沒辦法裝了這個外掛,就把你八百年前貼的照片一起轉到 flickr,你也被這個外掛還有你的 flickr 帳號綁死了,未來換帳號的話,或是你沒有 WLW 可以用時,這些功能都沒有了。
我比較喜歡的是 server side 的 solution,如果是透明的 (像 PROXY) 更好,如果隨時可以不要或是改設定最好,這樣我不但不用綁死在我的某個 flickr 帳號上,甚至不用綁在 flickr 這樣的服務...
過去 (沒想到已經快四年了 -_- ) 其實我作過幾個類似的 HttpHandler,都是用一樣的理念去開發的。這次想的是利用 Flickr 提供的 API,來做一樣的事。
簡單的說,如果我能夠寫個程式,能夠在 Run Time 動態去檢查網站上某張圖檔有沒有傳到 flickr 上? 如果沒有且判定不需要,則像一般網站一樣直接在 Http Response 傳回圖檔的內容。如果需要則自動上傳到 flickr,最後把這個 Http Request 重新導向到 flickr 上的照片網址。
這樣作法最後的結果跟 WLW 搭配 flickr plugins 差不多,差別在一個是靠 client 端,在你張貼文章時幫你處理掉一連串的動作,我的作法是統一在 server 端,在觀看文章內容時才做這件事。效能一定不如 WLW + Flickr plugin 好,不過就是多了彈性。我可以隨時關掉這個功能,隨時換相片服務,另一個更重要的是我自己保有一份完整的網站跟檔案資料。如果我的 BLOG 資料散在各地各個服務,我要備份或是還原等等也都很辛苦...
講了一堆都是廢話,其實這篇主題只有一個,就是想到好點子又要開始動手寫 code 了 [:D] ,有點成果之後會陸續在貼幾篇相關的文章。在之前作了 POC ( Prove Of Concept ),證明這個技巧是可行的,剩下的就是真正動手寫了。另外也有一個目的,就是想把之前寫的另外兩個 HttpHandler 整合起來,弄成統一的 provider 架構來實作。
想的很美,照片就轉到 Flickr,影片就轉到 YouTube ... 不過影片那邊的難度就高的多了,現在的實作只是從 HTTP 自動轉到 RTSP 而以.. ZIP 檔現在是虛擬化成一個資料夾,未來看看能不能自動轉到 Microsoft SkyDrive 之類的服務....
好,先寫到這裡,敬請期待下集 [:D]
經過一個禮拜的準備,總算在這週末完成移機的動作了... 為什麼標題叫 "Next Ten Years" ? 因為換下來的 server 已經陪我十年了,不知道這次換的新 SERVER 能不能陪我再撐十年?
沒想到當年的 ASUS P2B-DS 這麼耐用,中間換了 CPU,換了 RAM,機殼,顯示卡,連硬碟光碟都換過好幾次了,唯獨主機板跟 Power 都沒換過...
其實舊 server 能撐這麼久也不是沒有原因的,除了硬體都沒壞之外,老實說跑跑簡單的 NAT / DHCP / DNS 也都夠用,跑現在這個網站 (BLOG + SQL) 也都撐的住。不過規格時在是不饒人啊,現在已經買不大到 IDE 的硬碟了,就算買的到也很不划算。前陣子弄了張 PCI 的 4 ports SATA card,結果也因為BIOS實在太古董了,裝上硬碟就停在那邊不開機 @_@,舊硬碟只要 COPY 大檔,SQL 2005 Express 就給我罷工... 最後跟同事借了台量耗電的機器,舊SERVER一開機就要 150W... 以它的處理能力來說實在不划算,所以才會忍不住去敗了零件來換...
本來換機的 roadmap 規劃的很漂亮,想說等到 2009 Q1 ~ Q2,INTEL換了新的架構後,現在的桌機 (P5B-E Plus + E6300) 拿來當SERVER,桌機就換新的... 不過實在是受不了硬碟一直維持不到 5% 剩餘空間,加上每次一挪空間網站就給我掛掉,就改變策略直接買來換掉現在的SERVER,桌機就將就點用吧...
這次換的配備,都是以省電為主要訴求,規格就挑同級裡最低階的:
CPU | Intel Core2 Quad Q9300 |
RAM | A牌 DDR2-800 2GB x 4 |
主機板 | Intel Q35 (ASUS P5E-VM DO) |
硬碟 | WD7500AACS (750GB) x 3 |
Power | S牌 330W |
一直覺的SERVER還要找張VGA卡裝上去實在是很雞肋,跟本用不到幾次,不過不裝又很麻煩... 雖然2003號稱可以支援,不過我想還是別自找麻煩好了 [H],主機板就鎖定 Q35 的,因為它定位在商用機種,內建 VGA,同時又保有基本的效能... 不會像其它內建顯示晶片的板子,要嘛RAM只能插兩條,不然就是SATA只有四個...
CPU挑了四核最入門的 Q9300,為什麼不挑 Q6600 ? 差一千五左右,不過耗電量跟溫度都有差,因為我堆SERVER的房間通風很差,太熱實在很麻煩,就挑了Q9300. 硬碟挑的是WD GP系列,閒的時後轉速可以自動從7200降到5400,正好符合我的需求。我一向不大在意硬碟有多快... 反正快慢頂多差個10%,實在沒差多少,容量多一點,溫度低一點比較實在..
裝好的新 SERVER
舊 SERVER 把機殼塞的滿滿的,相對之下新SERVER就顯的小多了,多插張網路卡就一切搞定了,之前插的滿滿的 (網卡 x 2 + USB + VGA ...) 耗電量也省的多,之前只接一顆硬碟,只要 70W... 四顆硬碟都加上去應該也不到 100W... 早知道買 330W 的 POWER 幹嘛...
移機的過程就不提了,原本還很謹慎的弄台IP分享器,想說換機過程中至少讓家裡對外網路是通的,事實證明這完全是多此一舉... 家裡會上網的人全都睡覺去了 [H]... 不過還是要感謝一下提供IP分享器的米國人 [:D] (沒錯,Honga 就是你..),貼張照片感謝一下:
換完後又設定東設定西,檔案這裡搬過來那裡搬過去,總算弄完了。最後除了舊的 Modem 找不到 windows 2003 x64 driver 之外,其它一切正常。因為系統都重灌了,有缺啥設定漏掉的,或是發現網站那裡不正常的再通知我吧!
--------
趁機借問一下,有沒有推薦的 USB Modem (我只要拿來收發傳真而以),有 2003 x64 驅動程式的? 網站是找到幾款,不過都是天價,不然就是市面上買不到...