如何打造一個小而精的電商網站架構?
本文大綱:
1. 小型電商網站的架構
2. 日誌與監控係統的解決方案
3. 構建數據庫的主從架構
4. 基於共享存儲的圖片服務器架構
5. 移動M站建設
6. 係統容量預估
7. 緩存係統
一、小型電商網站的架構
剛從傳統軟件行業進入到電商企業時,覺得電商網站沒有什麼技術含量,也沒有什麼門檻,都是一些現有的東西堆積木似的堆出來罷了。然而,真正進入到這個行業之後,才發現並非如此。有人說過,好的架構,是演化出來的,電商網站的架構也是如此。現在好的電商網站,看似很複雜,很牛逼,其實也是從很小的架構,也是從沒什麼技術含量開始的。所以,架構的演化過程,就是在技術團隊不斷追求極致的過程。
今天就來總結小型電商網站的架構演進。一套電商係統最初期的架構,往往會采用一個比較典型的LAMP架構,前端加上Apache/PHP,後端是MySQL。這個算是比較流行的。不過,目前還有一套.net的技術架構,可能大家很少提到。很不幸,我就是在一個.net平台為基礎的電商公司。所以,今天也是要總結.net 平台的電商架構。
1技術架構
一般初期的電商網站,基本就幾個業務子係統:網站前台、商家前台、係統管理後台、App、M站等。業務量也不是很大。所以,MVC + 緩存 + 數據庫基本就搞定了。
單就開發效率而言,.net MVC 的技術架構不會比LAMP開發速度慢。所以,一些企業,為了快速推出自己的電商平台,也會采用.net 架構。
2基礎架構
上圖為基礎架構層麵。這是一個很簡單的基礎架構。
-
前端網站和M站,考慮到訪問量和係統的可用性,基本會采用分布式部署。通過代理服務器進行請求分發。
-
其它的業務子係統,像商家前台和管理係統,基本上都是單機或是主從部署。
-
各個DB ,Redis 服務和文件和圖片服務,搜索引擎Solr服務等,采用主從部署。
3詳細架構
整個係統架構裏麵,還有一個比較重要的組成部分,那就是監控係統。例如:流量監控、硬件監控、係統性能監控等, 還有就是對某個頁麵進行監控,設置頁麵的其中一塊進行監控等。它是提高整個平台可用性的一個重要手段。多平台、多個維度的監控,能夠確保係統的可用性。一旦出現異常,特別在硬件或者性能方麵出現異常,監控係統也能立刻發出警告,這樣也好防範於未然。
總而言之,一個好的係統架構應該從擴展性、安全性、性能和可靠性來考慮。羅馬不是一天建成的,架構適合就行,可以先行之而後優。通過漸進演化的過程,逐步讓係統越來越完善。
二、日誌與監控係統的解決方案
監控係統主要用於服務器集群的資源和性能監控,以及應用異常、性能監控、日誌管理等多維度的性能監控分析。一個完善的監控係統和日誌係統對於一個係統的重要性不必多說。總之,隻有實時了解各係統的狀態,才能保證各係統的穩定。
如上圖所示,監控平台監控的範圍很廣,從服務器性能及資源,到應用係統的監控。每個公司都有特定的平台統一監控的需求及解決方案,但監控平台的任務和作用基本是一致的。
1日誌
日誌是監視程序運行的一種重要的方式,主要有兩個目的:1.bug的及時發現和定位;2.顯示程序運行狀態。
正確詳細的日誌記錄能夠快速的定位問題。同樣,通過查看日誌,可以看出程序正在做什麼,是不是按預期的設計在執行,所以記錄下程序的運行狀態是必要的。這裏將日誌分為兩種:1.異常日誌;2.運行日誌。
我們主要是使用log4net,將各個係統的日誌,持久化記錄到數據庫或者文件中,以方便後續的係統異常監控和性能分析。如何集成log4net,這裏不多說。
日誌記錄的幾個原則:
-
日誌級別一定要區分清楚,哪些屬於error、warning、info等。
-
記錄錯誤的位置。如果是分層係統,一定要在某個層統一處理,例如我們的MVC架構,都是在各個Action中Catch異常並處理,而業務層和數據庫層這些地方的異常,都是Catch到異常後,往上一層拋。
-
日誌信息清晰準確有意義,日誌盡量詳細點,以方便處理。應該記錄相關係統、模塊、時間、操作人、堆棧信息等。方便後續處理。
2監控
監控係統是一個複雜的係統平台,目前有很多的開源產品和平台。不過我們平台小,監控任務和需求少,所以基本都是自己開發。主要有這五個方麵:1.係統資源;2.服務器;3.服務;4.應用異常;5.應用性能。
具體的架構圖如下:
1)係統資源監控
監控各種網絡參數和各服務器相關資源(CPU、內存、磁盤讀寫、網絡、訪問請求等),保證服務器係統的安全運營,並提供異常通知機製以讓係統管理員快速定位/解決存在的各種問題。目前比較流行的應該是Zabbix。
2)服務器監控
服務器的監控,主要是監控各個服務器、網絡節點、網關等網絡設備的請求響應是否正常。通過定時服務,定時去Ping各個網絡節點設備,以確認各網絡設備是否正常。如果哪個網絡設備出現異常,則發出消息提醒。
3)服務監控
服務監控,指的是各個Web服務、圖片服務、搜索引擎服務、緩存服務等平台係統的各項服務是否正常運行。可以通過定時服務,每隔一段時間,就去請求相關的服務,以確保平台的各項服務正常運行。
4)應用異常監控
目前我們平台所有係統的異常記錄,都記錄在數據庫中。通過定時服務,統計分析一段時間之內的異常記錄。如果發現有相關重要的模塊的係統異常,比如支付、下單模塊頻繁發生異常,則立即通知相關人員處理,確保服務正常運行。
5)應用性能監控
在API接口和各應用的相關位置進行攔截和記錄下程序性能(SQL性能,或是 程序執行效率)。相關重要模塊提供性能預警,提前發現問題。 同時統計相關監控信息並顯示給開發的人員,以方便後續的性能分析。
三、構建數據庫的主從架構
發展到大型成熟的公司之後,主從架構可能就有點落伍了,取而代之的是更加複雜的數據庫集群。但作為一個小型電商公司,數據庫的主從架構應該是最基礎的。任何大型的係統架構,都是不斷演進的。主從架構便是數據庫架構中最基礎的架構。所以研究完主從架構,也就能看懂更加複雜的架構了。
首先為什麼要讀寫分離?
對於一個小型網站,可能單台數據庫服務器就能滿足需求。但在一些大型的網站或者應用中,單台的數據庫服務器可能難以支撐大的訪問壓力,升級服務器性能成本又太高,所以必須要橫向擴展。還有就是,單庫的話,讀、寫都是操作一個數據庫。數據多了之後,對數據庫的讀、寫性能就會有很大影響。同時對於數據安全性和係統的穩定性也是挑戰。
數據庫的讀寫分離的好處?
-
將讀操作和寫操作分離到不同的數據庫上,避免主服務器出現性能瓶頸;
-
主服務器進行寫操作時,不影響查詢應用服務器的查詢性能,降低阻塞,提高並發;
-
數據擁有多個容災副本,提高數據安全性,同時當主服務器故障時,可立即切換到其他服務器,提高係統可用性。
讀寫分離的基本原理就是讓主數據庫處理事務性增、改、刪操作(Insert、Update、Delete)操作,而從數據庫處理Select查詢操作。數據庫複製被用來把事務性操作導致的變更同步到其它從數據庫。
以SQL為例,主庫負責寫數據、讀數據。讀庫僅負責讀數據。每次有寫庫操作,同步更新到讀庫。寫庫就一個,讀庫可以有多個,采用日誌同步的方式實現主庫和多個讀庫的數據同步。
1SQL Server 讀寫分離的配置
SQL Server提供了三種技術,可以用於主從架構之間的數據同步的實現:日誌傳送、事務複製和SQL 2012 中新增的功能Always On 技術。各自優劣,具體的大家自己去百度吧,這裏提供網上的朋友的配置方式,僅供參考。
-
日誌傳送:SQL Server 2008 R2 主從數據庫同步
-
事務複製:SQL Server 複製:事務發布
(圖源:網絡)
2C# 數據庫讀寫操作
C#的請求數據庫操作,單數據庫和主從架構的數據庫還是不一樣的。主從架構的數據庫,為了保證數據一致性,一般主庫可讀可寫,從庫隻負責讀,不負責寫入。所以,實際C#在請求數據庫時,要進行區別對待。
最簡單的就是:配置兩個數據庫連接,然後在各個數據庫調用的位置,區分讀寫請求相應的數據庫服務器,如下圖:
第二種解決方案就是判斷SQL語句是寫語句(Insert 、Update、Create、 Alter)還是讀語句(Select)。
Demo下載:https://files.cnblogs.com/files/zhangweizhong/Weiz.DB.rar
(PS:此Demo為本人總結,跟實際生產中的DLL 不太相同,但原理是一樣的,大家總結封裝吧)
同時,增加相關的數據庫配置
四、基於共享存儲的圖片服務器架構
在當前這個互聯網的時代,不管何種網站,對圖片的需求量越來越大。尤其是電商網站,幾乎都會麵臨到海量圖片資源的存儲、訪問等相關技術問題。在對圖片服務器的架構、擴展、升級的過程中,肯定也會碰到各種各樣的問題與需求。當然這並不代表,你就必須得弄一個特別NB的圖片服務架構,隻要簡單、高效、穩定就行。這部分我們來總結一個特別簡單、高效的圖片服務架構:通過共享存儲的方式來實現圖片服務架構。
然而,也有一些人問我,現在大型網站的圖片服務器的架構已經完全不是這樣了,別人家的圖片係統比你這個牛逼多了,為啥不直接寫那個呢?
事實是:第一,大型牛逼的係統我也不會;第二, 再牛逼的係統也是從小的架構演化過去的,沒有一步到位的。這裏介紹圖片服務器架構雖然比較簡單,但也是經過了單機時代的演化了,基本上可以滿足中小型分布式網站的需求。這種架構的搭建和學習成本都極低,符合目前“短平快”的開發模式。
通過共享目錄的方式實現共享存儲 ,在共享目錄文件服務器上配置獨立域名,這樣可以將圖片服務器和應用服務器進行分離,來實現獨立圖片服務器。
優點:
1. 將圖片服務和應用服務分離,緩解應用服務器的I/O負載。
2. 通過共享目錄的方式來進行讀寫操作,可以避免多服務器之間同步相關的問題。
3. 相對來講很靈活,也支持擴容/擴展。支持配置成獨立圖片服務器和域名訪問,方便日後的擴展和優化。
4. 相對於更加複雜的分布式的NFS係統,這種方式是性價比高,符合目前互聯網的“短平快”的開發模式。
缺點 :
1. 共享目錄配置有些繁瑣。
2. 會造成一定的(讀寫和安全)性能損失。
3. 如果圖片服務器出現問題,那所有的應用都會受到影響。同時也對存儲服務器的性能要求特別高。
4. 圖片上傳操作,還是得經過Web服務器,這對Web服務器還是有巨大的壓力。
架構非常簡單,基本架構如下圖所示:
在存儲服務器上建立一個共享目錄(具體方式,我就不去重複了,自己百度吧,注意共享目錄的文件安全)。
各個應用直接通過共享目錄(\\192.168.1.200),將圖片上傳到存儲服務器上。
建立一個Web站點(i1.abc.com)將該共享目錄通過Web站點發布出去。這樣其它的應用就能訪問到相關圖片。
所以,各應用將文件上傳到共享目錄
//保存原圖
//完整的地址:\\192.168.1.200\lib\2016\03\04\10\IMG\4ugvvt6m9gdu.jpg
relativePath = relativeDir + fileName + imageExtension;
var absolutePath = ConfigHelper.SharePath + relativePath;
fileData.SaveAs(absolutePath);
上傳成功後,可直接通過web 的方式訪問:
https://i1.abc.com/lib/2016/03/04/10/IMG/4ugvvt6m9gdu.jpg
五、移動M站建設
最近在一直在搞M站,也就是移動Web站點。由於是第一次,也遇到了很多問題,所以把最近了解到的東西總結一番。聊一聊什麼是移動M站,以及它有什麼作用和優勢。
有人會問,M站和APP有什麼不同?
-
APP直接在用戶的移動設備上,曝光率相對較高。 而M站需打開瀏覽器,輸入地址才能訪問,所以曝光率相對較低。
-
M站的推廣的渠道相比移動APP,渠道較多,方便追蹤用戶來源、流量入口等,方便以後的活動推廣和數據分析。
-
M站用戶無需安裝,輸入URL即可訪問,而APP需要下載安裝。
-
M站能夠快速地通過數據分析,能快速得到用戶的反饋,從而更容易根據統計數據分析和用戶的需求來調整產品。
-
APP對用戶更具粘性及用戶體驗也更好。
-
M站對於營銷推廣活動非常方便,轉發分享方便快捷。
-
M站更新迭代產品速度和響應產品調整非常快,隨時發布,而APP需要審核時間。
-
M站跨平台,無需開發安卓和iOS版,隻需有瀏覽器即可。
所以, 我覺得,M站和客戶端是相輔相成的。M站的及時性和快捷性,是APP無法比擬的。而APP的用戶體驗,則是M站無法做到的。目前來說兩者是不可能被對方完全替代的,在互聯網營銷大行其道的今天,M站也越來越重要。營銷活動大多以H5頁麵的形式展示和傳播。通過M站的營銷和推廣,從而又促進APP的使用和推廣。
目前,移動M站有傾向APP的趨勢。M站會越來越像個APP,使得M站也越來越重要。而且,很多APP的展示效果,在原生代碼無法實現的時候,嵌套移動H5頁麵也是一個很好的選擇。
下麵介紹幾個移動M站建設的要點:
151Degree
51Degrees號稱是目前最快、最準確的設備檢測的解決方案。它是一個免費開源的.NET移動應用開發組件,可以用來檢測移動設備和瀏覽器。甚至可以獲取屏幕尺寸、輸入法、加上製造商和型號信息等。從而可以選擇性地被定向到為移動設備而設計的內容。由於擁有精確的移動設備的數據,所以幾乎支持所有的智能手機,平板電腦等移動設備。
其實說白了,51Degree的作用就是識別客戶端的設備。PC瀏覽器訪問,就跳轉到PC站,手機瀏覽器訪問就跳轉到M站。從而達到更好的用戶體驗。
如何將51Degree加入到現有網站?
2架構
移動Web和傳統的Web其實並沒有本質的區別。說白了還是一個Web站點,使用的技術都是Html+CSS+JS。不同的是,隻不過目前在Html5的大趨勢下,將Html5加入到了移動M站,使得M站更像個輕APP。
3Bootstrap
Bootstrap就不多說了,網上有很多Bootstrap的資料。它最大的優勢應該就是非常流行,非常容易上手。如果缺少專業的設計或美工,那麼Bootstrap是一個比較好的選擇。他的用法極其簡單,幾乎沒什麼學習成本,絕對是快速開發的利器。
官網:https://getbootstrap.com/
Github:https://github.com/twbs/bootstrap/
4幾點建議
-
移動M站的URL要盡量和PC相同,這是可以避免同一URL在PC站可以顯示,但是在手機上打開卻是404;
-
M站寫單獨的TDK。
六、係統容量預估
電商公司的朋友,這樣的場景是否似曾相識:
運營和產品神秘兮兮的跑過來問:我們晚上要做搞個促銷,服務器能抗得住麼?如果扛不住,需要加多少台機器?
於是,技術一臉懵逼。
其實這些都是係統容量預估的問題,容量預估是架構師必備的技能之一。所謂,容量預估其實說白了就是係統在Down掉之前,所能承受的最大流量。這個是技術人員對於係統性能了解的重要指標。常見的容量評估包括流量、並發量、帶寬、CPU、內存 、磁盤等一係列內容。這部分來聊一聊容量預估的問題。
1幾個重要參數
-
QPS:每秒鍾處理的請求數。
-
並發量: 係統同時處理的請求數。
-
響應時間: 一般取平均響應時間。
很多人經常會把並發數和QPS給混淆了。其實隻要理解了上麵三個要素的意義之後,就能推算出它們之間的關係:QPS = 並發量 / 平均響應時間。
2容量評估的步驟與方法
1)預估總訪問量
如何知道總訪問量?對於一個運營活動的訪問量評估,或者一個係統上線後PV的評估,有什麼好方法?
最簡單的辦法就是:詢問業務方,詢問運營同學,詢問產品同學,看產品和運營對此次活動的流量預估。
不過,業務方對於流量的預估,應該就PV和用戶訪問數這兩個指標。技術人員需要根據這兩個數據,計算其他相關指標,比如QPS等。
2)預估平均QPS
-
總請求數=總PV*頁麵衍生連接數
-
平均QPS = 總請求數/總時間
比如:活動落地頁1小時內的總訪問量是30w PV,該落地頁的衍生連接數為30,那麼落地頁的平均QPS=(30w*30)/(60*60)=2500。
3)預估峰值QPS
係統容量規劃時,不能隻考慮平均QPS,還要考慮高峰的QPS,那麼如何評估峰值QPS呢?
這個要根據實際的業務評估,通過以往的一些營銷活動的PV等數據進行預估。一般情況下,峰值QPS大概是均值QPS的3-5倍,如果日均QPS為1000,於是評估出峰值QPS為5000。
不過,有一些業務會比較難評估業務訪問量,例如“秒殺業務”,這類業務的容量評估暫時不在此討論。
4)預估係統、單機極限QPS
如何預估一個業務,一個服務器單機的極限QPS呢?
這個性能指標是服務器最基本的指標之一,所以除了壓力測試沒有其他的辦法。通過壓力測試,算出服務器的單機極限QPS 。
在一個業務上線前,一般都需要進行壓力測試(很多創業型公司,業務迭代很快的係統可能沒有這一步,那就悲劇了),以APP推送某營銷活動為例(預計日均QPS為1000,峰值QPS為5000),業務場景可能是這樣的:
-
通過APP推送一個活動消息;
-
運營活動H5落地頁是一個Web站點;
-
H5落地頁由緩存Cache和數據庫DB中的數據拚裝而成。
通過壓力測試發現,Web服務器單機隻能抗住1200的QPS,Cache和數據庫DB能抗住並發壓力(一般來說,1%的流量到數據庫,數據庫120 QPS還是能輕鬆抗住的,Cache的話QPS能抗住,需要評估Cache的帶寬,這裏假設Cache不是瓶頸),這樣,我們就得到了Web單機極限的QPS是1200。一般來說,生產係統不會跑滿到極限的,這樣容易影響服務器的壽命和性能,單機線上允許跑到QPS1200*0.8=960。
擴展說一句,通過壓力測試,已經知道Web層是瓶頸,則可針對Web相關的方麵做一些調整優化,以提高Web服務器的單機QPS 。
還有壓力測試工作中,一般是以具體業務的角度進行壓力測試,關心的是某個具體業務的並發量和QPS。
5)回答最開始那兩個問題
需要的機器=峰值QPS/單機極限QPS
好了,上述已經得到了峰值QPS是5000,單機極限QPS是1000,線上部署了3台服務器:
-
服務器能抗住麼? -> 峰值5000,單機1000,線上3台,扛不住
-
如果扛不住,需要加多少台機器? -> 需要額外2台,提前預留1台更好,給3台保險
3總結
需要注意的是,以上都是計算單個服務器或是單個集群的容量。實際生產環境是由Web、消息隊列、緩存、數據庫等等一係列組成的複雜集群。在分布式係統中,任何節點出現瓶頸,都有可能導致雪崩效應,最後導致整個集群垮掉 (“雪崩效應”指的是係統中一個小問題會逐漸擴大,最後造成整個集群宕機)。
所以,要了解規劃整個平台的容量,就必須計算出每一個節點的容量。找出任何可能出現的瓶頸所在。
七、緩存係統
對於一個電商係統,緩存是重要組成部分,而提升係統性能的主要方式之一也是緩存。它可以擋掉大部分的數據庫訪問的衝擊,如果沒有它,係統很可能會因為數據庫不可用導致整個係統崩潰。
但緩存帶來了另外一些棘手的問題: 數據的一致性和實時性。例如,數據庫中的數據狀態已經改變,但在頁麵上看到的仍然是緩存的舊值,直到緩衝時間失效之後,才能重新更新緩存。這個問題怎麼解決?
還有就是緩存數據如果沒有失效的話,是會一直保持在內存中的,對服務器的內存也是負擔,那麼,什麼數據可以放緩存,什麼數據不可以,這是係統設計之初必須考慮的問題。
什麼數據可以放緩存?
-
不需要實時更新但是又極其消耗數據庫的數據。比如網站首頁的商品銷售的排行榜,熱搜商品等等,這些數據基本上都是一天統計一次,用戶不會關注其是否是實時的。
-
需要實時更新,但是數據更新的頻率不高的數據。
-
每次獲取這些數據都經過複雜的處理邏輯,比如生成報表。
什麼數據不應該使用緩存?
實際上,在電商係統中,大部分數據都是可以緩存的,不能使用緩存的數據很少。這類數據包括涉及到錢、密鑰、業務關鍵性核心數據等。總之,如果你發現,係統裏麵的大部分數據都不能使用緩存,這說明架構本身出了問題。
如何解決一致性和實時性的問題?
保證一致性和實時性的辦法就是:一旦數據庫更新了,就必須把原來的緩存更新。
說一說我們的緩存方案:我們目前的緩存係統:Redis(主從)+ RabbitMQ + 緩存清理服務組成,具體如下圖:
緩存清理作業訂閱RabbitMQ消息隊列,一有數據更新進入隊列,就將數據重新更新到Redis緩存服務器。
當然,有些朋友的方案,是數據庫更新完成之後,立馬去更新相關緩存數據。這樣就不需要MQ和緩存清理作業。不過,這同時也增加了係統的耦合性。具體得看自己的業務場景和平台大小。
原文發布時間為:2017-04-14
本文來自雲棲社區合作夥伴DBAplus
最後更新:2017-05-17 12:02:06
上一篇:
對MarshalByRefObject的解釋
下一篇:
關於rails和Grails的性能討論
Python-高階函數習題練習
當我跑步時,我在想什麼
新手神器!不用部署深度學習環境、上傳數據集!(附代碼&視頻教程)
JavaScript數據安全實戰!攻擊與防範
6月16日雲棲精選夜讀:數據庫分布式架構巧設計,水平拆分不再難
Joomla行業解決方案
PostgreSQL Oracle 兼容性係列之 - WITH 遞歸 ( connect by )
VM中裝Linux換ISO文件報錯"該光盤無法被掛載"
Windows上使用Cygwin和Gitolite搭建Git服務器
《Spring MVC學習指南(第2版)》——第1章 Spring框架 1.1XML配置文件