網站架構的演化,從小型網站到巨型網站
網頁開發本文介紹一個網站從沒有流量的小型網站到巨型網站的成長過程,並說明每個階段所涉及到的相關技術。 請注意,本文介紹的只是一個可能的範例,並不是說每個網站架構都是按造這個步驟演變。 大部分實務上使用的架構,都是根據網站遇到的問題特別設計,並不能通用全部的網站。 事實上,這些技術您可能整個職業生涯都用不到,在實務上,更多的是利用改變業務流程來解決,而技術面只是輔助。 此外,網站開發涉及技術廣泛,本文不可能一一提及,但我會盡量提供一些常見的面向,讓您在學習過程中,有個方向可以依循。
階段一:靜態網頁
靜態網頁是指網頁資料單純位於 HTML 文本中,而不是連結資料庫取得,瀏覽器單純呈現 HTML 文本中內容,且網頁也無後台可以異動網頁中的資料。 以技術來說,靜態網頁是使用 HTML、CSS 和 JavaScript 進行開發,這是網站前端開發的基礎技術,也可以說只要會這三項技能,就能開發出各式各樣漂亮的網頁。
在開發上,也不需要太專業的軟體,最簡便的可以用 Windows 內建的記事本就能開發。 但實務上會使用更好用的軟體進行開發,常見的有 Visual Studio Code 及 Sublime Text,在後續開發 PHP 後端程式時,也可以使用這兩款軟體撰寫程式碼即可。 當程式碼撰寫完成後,只需要將文件用 .htm 副檔名儲存即可。 執行時,只要點兩下 .htm 檔,用預設的瀏覽器執行就能看到網頁畫面。
由於前端開發較注重畫面美觀及操作流暢性,通常會由美術設計師來設計畫面,再由軟體工程師根據設計稿來開發系統,因此工程師通常也需要學會基礎的繪圖軟體操作。 基本的繪圖軟體有 Photoshop 和 Illustrator,其他專為介面設計的軟體還有 Adobe XD、Figma、Sketch 及 InVision,不過也不用通通都學會,可以根據配合的美術設計師使用哪個軟體,就學那個軟體就好。
關鍵技術學習
- HTML:建議學到精通,HTML 是由一大堆標籤組成的,如果可能最好全部實作過一遍。
- CSS:建議學到精通,初學者建議先學最原始的 CSS,先不要去學 SASS 及 LESS 預處理器,SASS 及 LESS 能做到的效果,CSS 通通都能做。
- JavaScript:非常關鍵,初學者建議先學原生 JavaScript 語法及 jQuery,如果未來想要專攻前端,再去學 Angular、React 及 Vue 等前端框架。
- 繪圖軟體:只要學會如何看間距、字體大小、顏色、修改圖片尺寸、匯出想要的圖檔格式...等基礎操作即可。
階段二:網頁伺服器
階段一的靜態網頁只能在開發人員的電腦瀏覽,如果要讓其他人也能瀏覽您開發的網頁,那就必需將網頁檔案複製到其他人的電腦才行,但這明顯不利於網頁的發展。 此時更好的做法,就是架設網頁伺服器,讓使用者透過網址就能瀏覽您的網站。 為了達到這個目的,您可能需要完成以下動作:
- 找一台電腦安裝作業系統,通常是裝 Linux 作業系統,當然也可以使用 Windows Server。
- 安裝網頁伺服器,常見的有 Apache、Nginx 及 IIS 可供選擇。
- 設定固定 IP,並在防火牆開啟 80 Port 或 443 Port。
- 為了方便使用者記住您的網址,您還需要購買網址,並在 DNS 設定網址對應。
- 為了安全性,您還需要購買 SSL 憑證。
完成這些動作之後,您的網站才是實質意義上公開讓任何人瀏覽的網站。
關鍵技術學習
- 安裝作業系統:多裝個幾次就會了,甚至有經費的話,可以直接購買雲端服務。
- 網頁伺服器:除了基本設定外,建議再學一下安全設定及效能設定。
- 防火牆:學會基本的開 Port 就可以了,太複雜的防火牆規則通常也會有網管人員協助處理。
- 購買網址:可以到 PChome 或 GoDaddy 購買。
- DNS 設定:通常網址購買平台都會提供 DNS 設定介面,不用真的自己架設 DNS Server。學習上著重學習 DNS 資源紀錄類型的功能及使用時機,如:SOA、NS、A、AAAA、CNAME、MX。
- SSL 憑證:需要學會如果在網頁伺服器設定 SSL 憑證。此外,現在也有免費的 SSL 憑證 Let’s Encrypt,也建議學習一下如何設定。
階段三:動態網頁
純靜態頁網站只能用來提供資訊,無法讓使用者傳遞資料,也無法實作複雜的業務邏輯,且純靜態頁也不利於資料更新,因此現在決大部分的網站都是屬於動態網頁。 動態網頁通常包含前台與後台,前台提供一般使用者瀏覽網站內容,後台提供管理員異動網站中的內容。
靜態網頁是將 HTML 儲存在文件檔案中,而動態網頁簡單來說就是透過程式碼生成 HTML,後端使用的程式語言有很多選擇,常見的有 PHP、JavaScript、Python 或 Go。 當前端發送請求後,後端根據收到的資料執行業務邏輯,並透過 SQL 語法從資料庫中取得必要資料,最後生成 HTML 回傳至瀏覽器。
此外,在較具規模的網站中,還會做到前後端分離。 使用前後端分離的開發模式,可以輕鬆的將前端程式與後端程式部署至不同的伺服器中,前端專注於介面設計,後端專注於業務邏輯開發,兩端的溝通則是使用 AJAX 與後端 RESTful API 進行資料傳遞。 如果您的客戶端不只有網頁,而是還有 APP 或其他應用程式時,此時前後端就需要分離得更徹底,後端不能輸出任何 HTML,而是開發各種 API,單純輸出資料而已,資料格式通常使用 JSON 格式或 XML 格式。
關鍵技術學習
- 後端程式:初學者先挑一種程式語言學到精通,除了基本語法外,還需要學習物件導向,更進階的話建議學一下設計模式,本系列文章主要使用 PHP。
- 資料庫:除了要會安裝之外,還要了解資料庫的一些設定及資料備份。
- SQL 語法:建議需要精通,初學者至少先精通 SELECT、INSERT、UPDATE、DELETE 及 JOIN 語法,進階還需學習預存程序。
- AJAX + RESTful API + JSON:絕對需要精通,幾乎是現代網站的基礎。
階段四:快取策略
隨著造訪人數越來越多,當伺服器第一次遇到效能瓶頸時,可以先嘗試進行以下調整:
- CSS Spirte
- 將網頁中分佈在不同地方的小圖片合併成一張大圖片,再利用 CSS 背景偏移技巧來呈現圖片,此方法可以減少網頁的 HTTP 請求。
- 合併多個 JavaScript 檔及 CSS 檔
- 同樣是為了減少 HTTP 請求。
- 壓縮 JavaScript 檔及 CSS 檔
- 壓縮後的檔案依然還是文字檔,只是檔案中的空白及換行通通都刪除了,此壓縮動作可以透過工具完成,壓縮完記得保留原始檔案。
- Brotli 或 GZIP 壓縮
- 經過最小化的文字檔,可以透過 Brotli 或 GZIP 壓縮成更小的檔案,此兩工具擇一使用即可。
- 調整伺服器參數
- 包含作業系統、網頁伺服器及資料庫等各項參數調整,這部分需要相當專業的技能,而且也沒有標準答案,各項參數都是測試出來的。
經過以上努力之後,相信執行速度多少可以獲得改善,再更進階的作法,就是使用各種快取策略。 快取策略非常多樣,後端的快取策略還區分為本地快取及遠端快取,遠端快取較為複雜,此階段應該優先使用各種本地快取策略,如果還是無法改善,再考慮使用遠端快取。 常見的快取策略有瀏覽器快取、網頁伺服器快取、反向代理快取、動態內容快取。
- 瀏覽器快取
- 將靜態資源快取放在客戶端的瀏覽器,避免每次刷新頁面都要重新下載全部靜態資源。
- 網頁伺服器快取
- 與瀏覽器快取類似,只是將靜態資源快取放在伺服器端的網頁伺服器,兩種快取策略可以並存。
- 反向代理快取
- 主要用於當後端為多台伺服器時,可以將伺服器隱藏在反向代理伺服器之後,從而提高安全性,並且也能提供快取,以加速網站反應速度,通常搭配負載平衡一起使用。反向代理亦可在單台伺服器上使用,一樣能帶來效能的提升。
- 動態內容快取
- 主要面向程式的快取策略,有些資料平常不太會異動,但幾乎每次刷新頁面都需要從資料庫取得,這時候就能將這種資料快取,以加速網站反應速度,比較常見的例子就是網站中的選單。
關鍵技術學習
- CSS Spirte:算實用技巧,但如果要換圖也有點麻煩。
- 合併壓縮多個 JavaScript 檔:常用且不會太難。
- 合併壓縮多個 CSS 檔:常用且不會太難。
- Brotli 與 GZIP 壓縮:主要是伺服器的設定,操作過幾次就會了。
- 系統參數優化:較困難,遇到再研究即可。
- 各種快取策略:遇到再研究即可。
階段五:伺服器分離
當流量越來越大,單台伺服器已經扛不住了,此時可以考慮將不同服務分離出來,每個服務使用獨立的伺服器來運行,並且規劃不同的硬體設備。
- 網頁伺服器
- 執行網頁業務邏輯程式,注重 CPU 執行速度。
- 資料庫伺服器
- 注重儲存容量及記憶體容量,並且需要規劃備份機制。
- 快取伺服器
- 常見的有 Memcache 及 Redis,注重記憶體容量。
- 檔案伺服器
- 常見的有 NFS 及 Samba,注重儲存容量,有很多大檔案的話,也需要多增加記憶體,建議使用 RAID 磁碟陣列。
關鍵技術學習
- 網頁伺服器:在階段二就已經在使用了。
- 資料庫伺服器:在階段三就已經在使用了。
- Memcache 及 Redis:遇到再研究即可。
- NFS 及 Samba:遇到再研究即可。
- RAID:建議要學,至少要有概念,小公司也有機會用到。
階段六:資料庫讀寫分離及分庫分表
單台資料庫伺服器在頻繁讀寫時,效率越來越慢,可以將資料庫分離成兩台獨立伺服器,一台負責讀取,一台負責寫入,再將兩台伺服器資料進行同步,目前主流的資料庫軟體都有內建同步功能。當讀寫分離後,勢必會遇到資料在短時間不一致的問題,同步間隔設定得越長,不一致的時間越長。 此時必需檢視業務邏輯中的程式碼,將可容忍資料不一致的功能從讀取資料庫讀取,不能容忍資料不一致的功能從寫入資料庫讀取。
分庫分表區分垂直切割及水平切割兩種方式。 垂直切割比較好實作,根據不同業務性質的資料,拆分不同的資料庫及資料表進行儲存。 水平切割則是使用多台資料庫伺服器,並且使用相同的資料表結構來儲存不同行數的資料,例如全部資料有 10 萬筆,前 5 萬筆在 A 資料庫,後 5 萬筆則儲存在 B 資料庫。
關鍵技術學習
- 讀寫分離:建議要學,小公司也有機會用到。
- 分庫分表:較困難,遇到再研究即可。
階段七:分散式運算
當流量繼續變大,讀寫分離也只是權宜之計,很快就扛不住了,其他伺服器也會出現類似的問題,接下來就要透過分散式運算來處理。 分散式運算是使用多台伺服器一起完成同一個任務,於階段五分離的網頁伺服器、資料庫伺服器、快取伺服器及檔案伺服器,全部都能進行分散式運算。 當進行分散式運算後,將會帶來許多問題,原本程式碼中的作法可能都需要進行調整及重新設計,算是一個大工程。
- 分散式網頁伺服器
- 算是比較簡單的分散式運算,使用多台伺服器安裝相同的程式碼,並透過負載平衡伺服器分配流量導向不同的伺服器。 這個作法還需要處理 SESSION 不一致問題,也就是當您在 A 伺服器登入,當流量導向 B 伺服器後,原本有登入就變成沒有登入。
- 分散式資料庫
- 目前主流的資料庫都提供叢集功能來進行分散式運算, 分散式資料庫遇到的難能有很多,例如資料資料不一致、備援問題、資料管理較複雜。
- 分散式快取
- 階段五使用的 Memcache 及 Redis 都能實作分散式快取,分散式快取也會遇到資料不一致的難題。
- 分散式檔案系統
- 分散式檔案系統並不是嚴格意義上的檔案系統,比較像是建構在軟體層面的檔案系統,透過連結多個伺服器建構出一個大的檔案系統。 在存取時,也是透過網路並使用特殊的通訊協定進行存取控制,通常無法直接透過網址連結到實體檔案。 常見的分散式檔案系統有 Hadoop 及 MogileFS。
叢集也是分散式運算的一種,但叢集是每台伺服器都具備相同的程式或資料內容,使用上就好像一台伺服器一樣。 而分散式中的每台伺服器可以是完全不同的程式或資料內容,連作業系統也都能完全不同。
關鍵技術學習
- 負載平衡:建議要學,小公司也有機會用到。
- 分散式網頁伺服器:建議要學,小公司也有機會用到。
- 分散式資料庫:遇到再研究即可。
- 分散式快取:遇到再研究即可。
- 分散式檔案系統:較困難,遇到再研究即可。
階段八:CDN 與反向代理
當網站擴展到全球服務時,如果您的全部伺服器都架設在同一個國家,這樣國外的使用者在瀏覽網站時,勢必需要等待更長的傳輸時間。 而在傳輸資料內容中,又以靜態資源佔用最多流量,如圖片檔、影片檔、JavaScript 檔及 CSS 檔,此時 CDN (Content Delivery Network) 就能派上用場了。
CDN 是一種靜態資源快取網路,當使用者瀏覽網站時,CDN 會根據使用者的所在地,從最近的伺服器回傳資料。 CDN 節點要分佈得越廣數量越多才會產生效益,因此一般公司幾乎沒有能力架設有效益的 CDN 網路,所以通常都是付費直接使用大公司佈設的 CDN 網路, 如 AWS Cloudfront、GCP CDN、Azure CDN 及 CloudFlare CDN。
反向代理於階段四就已經再使用了,但在階段四是使用於單台伺服器,在這個階段可以將反向代理運用到多台伺服器的場景。 反向代理能增加後端伺服器的安全性,也能提供快取服務,以加速網站反應速度。
關鍵技術學習
- CDN:小公司幾乎沒有機會用到,學會使用現成的 CDN 網路即可,不用學習架設。
- Reverse Proxy:主要是伺服器的設定,建議要學。
階段九:NoSQL 與搜尋引擎
使用資料庫叢集之後,資料庫速度提升了不少。 當資料量越來越多,資料庫叢集又不堪負荷時,此時還是可以繼續分庫分表加入更多的伺服器進入叢集。
但我們可以思考另外一個做法,將許多不需要做交易或關聯的資料,直接脫離關聯式資料庫,改用 NoSQL 資料庫取代。 NoSQL 使用 Key-Value 方式儲存資料,在讀取跟寫入上都比關聯式資料庫資料庫快很多。 但 NoSQL 無法確保資料的關聯性,所以您很難將全部資料庫都改為 NoSQL 儲存,比較常見的是 關聯式資料庫與 NoSQL 資料庫並存。 常見的 NoSQL 資料庫有 MongoDB、HBase、Apache Cassandra。
這邊說的搜尋引擎是指站內搜尋,在小型網站要做站內搜尋,可以簡單粗暴的使用 SQL 的 Like 語法,如果多張表一起查詢也可以搭配 UNION ALL 來查詢。 但在大流量網站絕對不可能這樣做,眾所周知這兩個語法都是相當耗效能。 如果想要自己打造一個搜尋引擎的話,還需要學習爬蟲程式,但即便學會了,打造搜尋引擎也不是一件簡單的事情,但我們可以使用現成的搜尋引擎軟體。 目前比較著名的搜尋引擎軟體有 Elastic Search,不過設定上也不會太容易。
關鍵技術學習
- NoSQL:有時間可以學一下,至少有個概念。
- 搜尋引擎:較困難,遇到再研究即可。
階段十:業務切分與訊息佇列
網站發展得越久,提供的功能也會越來越多,伺服器的負載也會更大。 此時可以將網頁伺服器根據不同的業務進行切分,由不同的伺服器負責不同的功能處理。 由於功能進行切分後,每個功能可能不需要使用到完整的伺服器效能,此時還可以使用虛擬化技術,將一台強大的伺服器虛擬化成多台伺服器,常見的有 VMware 及 Docker。
當流量非常大的時候,可以使用訊息佇列 (Message Queue) 實現非同步資料存取。 常見的訊息佇列軟體有 RabbitMQ、Kafaka 及 Apache ActiveMQ。
關鍵技術學習
- 虛擬化技術 VMware:遇到再研究即可。 平常我們在 Windows 安裝 VMware 軟體,其實就是在做虛擬化。 但在大型伺服器應用上,是直接將整台伺服器虛擬化,而不是在作業系統上,安裝虛擬化軟體,這兩者的難度差異是不同的。
- 虛擬化技術 Docker:遇到再研究即可。 如果是接案公司或傳產資訊室應該是用不到,但在其他軟體開發公司算蠻常見的。
- 業務切分: 遇到再研究即可。困難點不是在技術上,而是要怎麼切才合理。
- 訊息佇列: 遇到再研究即可。
階段十一:業務邏輯整併
當大型網站功能切分久了之後,會發現很多業務邏輯都是共通的,此時又需要將共通的業務邏輯進行整併,以更有效的控管資源的使用。
關鍵技術學習
- 業務邏輯整併: 遇到再研究即可。困難點不是在技術上,而是要怎麼整併才合理。
網站管理
最後來聊聊與網站架構較無關,但在網路管理上也經常用到內容。
版本控制
程式碼版本控制是很常見的,只要公司稍具規模都會使用到版本控制。 版本控制可以追蹤程式碼異動的過程,在多人開發上有時候會同時存在多個版本的程式碼,例如某個功能有 Bug,可以先開新的分支由一名工程師進行處理,待處理完成之後再整併回來。
版本控制是很實用的功能,常見的版本控制軟體有 Git、CVS、Subversion,建議可以挑選一種花時間學一下,概念是差不多的。
流量監控
流量監控也是網站發展到一定階段之後,一定會使用到的軟體。 通常如果是跟主機商承租主機的話,大多也會提供流量監控服務。 如果是自架伺服器的話,才會需要自己架設流量監控軟體
常見的流量監控軟體有 OpenNMS 及 Zabbix。
日誌分析
日誌分析比較接近資安領域,工作內容就是監控各種設備或應用程式產生的日誌,並進行日誌分析,分析結果通常會使用可視化圖表來呈現。 日誌分析能協助故障排除、預測流量趨勢、識別安全漏洞、改善產品...還有很多,有時候為了預警識別,自己動手寫程式進行自動化分析也是常見的事情。
伺服器中的日誌檔案散落在不同的地方,格式也都不相同,並且有些日誌檔案檔案還非常大,使用一般文字編輯軟體開啟就需要花費很多時間,如果還要管理多台伺服器中的日誌檔案,工作量肯定是非常浩大。 因此實務上至少要使用 Log Management 日誌管理工具來協助進行分析,常見的日誌分析軟體有 Graylog 及 Loggly,或使用更強大的 SIEM 系統。
參考資料
- 書籍:從車庫的舊 PC 到百萬台伺服器:巨型網站成長從無到無限大,技術架構大揭祕, ISBN:9789865712334
- 書籍:巨型網站大師親自指導:建立極速 Web 站台的祕密, ISBN:9789865836047
- 書籍:百億造訪還能正常運作: 全球最大購物網站技術公開, ISBN:9789863797609
- 書籍:淘寶網的原理架構解密: Java 中介軟體 in 巨型網站, ISBN:9789863791768
0 則留言