本文介紹一個網站從沒有流量的小型網站到巨型網站的成長過程,並說明每個階段所涉及到的相關技術。 請注意,本文介紹的只是一個可能的範例,並不是說每個網站架構都是按造這個步驟演變。 大部分實務上使用的架構,都是根據網站遇到的問題特別設計,並不能通用全部的網站。 事實上,這些技術您可能整個職業生涯都用不到,在實務上,更多的是利用改變業務流程來解決,而技術面只是輔助。 此外,網站開發涉及技術廣泛,本文不可能一一提及,但我會盡量提供一些常見的面向,讓您在學習過程中,有個方向可以依循。

階段一:靜態網頁

靜態網頁是指網頁資料單純位於 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 等前端框架。
  • 繪圖軟體:只要學會如何看間距、字體大小、顏色、修改圖片尺寸、匯出想要的圖檔格式...等基礎操作即可。

階段二:網頁伺服器

階段一的靜態網頁只能在開發人員的電腦瀏覽,如果要讓其他人也能瀏覽您開發的網頁,那就必需將網頁檔案複製到其他人的電腦才行,但這明顯不利於網頁的發展。 此時更好的做法,就是架設網頁伺服器,讓使用者透過網址就能瀏覽您的網站。 為了達到這個目的,您可能需要完成以下動作:

  1. 找一台電腦安裝作業系統,通常是裝 Linux 作業系統,當然也可以使用 Windows Server。
  2. 安裝網頁伺服器,常見的有 Apache、Nginx 及 IIS 可供選擇。
  3. 設定固定 IP,並在防火牆開啟 80 Port 或 443 Port。
  4. 為了方便使用者記住您的網址,您還需要購買網址,並在 DNS 設定網址對應。
  5. 為了安全性,您還需要購買 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 系統

參考資料