“官宣”下新浪微博崩潰的架構測試

趙小姐姐
如果說昨天什麼最火,估計就是“官宣”了吧,趙麗穎結婚據說某新浪微博甚至還癱瘓了一陣子。
傳說上次有人說微博內部調整,現在已經支援八個明星同時出軌併發,那麼昨天的事情還真是叫人尷尬。

吐槽新浪
併發對於開發初學者可能覺得沒什麼確實感覺,畢竟自己做ORM單應用專案的時候遇到的併發量就是自己,撐死了也就是十幾個人的併發數。所以很多初學者對於併發崩潰並沒有個概念,所以今天我們就來討論一下各個架構可以承受的併發量是多少。
目前比較常用的架構包括但不限於ORM,MVC,RPC,SOA等和架構詳情,如下圖

image.png
單一應用架構:將所有功能都部署在一起減少成本和節點,這樣的框架適合流量較小的網站,只需要一個應用,而簡化資料庫訪問的增刪改查是關鍵。
缺點:不方便維護,程式碼分層不明顯,程式碼越多越難維護,開發的時候我和上帝知道,現在估計只有上帝知道了。
垂直應用架構:將應用拆成互不相干的幾個應用,這樣可以承受的併發有所增加,而加速前端頁面開發的Web框架是關鍵。(這裡涉及到兩個面:一個是將應用按照功能模組拆分並獨立部署,另外一個是程式碼結構上的分層,以SSM為例,分為檢視層、action層、service層、dao層,各層之間通過介面之間耦合起來,jsp呼叫action,action呼叫service,service呼叫dao)
缺點:程式碼難以複用,獨立的模組相當於一個獨立的應用。
分散式服務架構:當垂直應用越來越多,這個時候我們管理起來很麻煩,不僅如此應用間複雜的互動更會讓我們手足無措,這個時候我們可以考慮將核心模組抽取出來作為服務中心,讓前端應用快速響應市場需求,這個時候,用來提高業務複用和整合應用的分散式框架(RPC)是關鍵。
缺點:實際開發中發現有點難,其次網路存在問題的時候遠端呼叫可能較慢,增加伺服器資源當併發量降低之後容易造成資源浪費,但相對於dubbo曾經扛起了阿里巴巴帝國就已經可以看出多強悍了,不過還是上一張圖對比常用的RPC框架

image.png
流動計算架構:當服務越來越多,容量的評估,小服務資源的浪費等問題逐漸顯現,此時需增加一個排程中心基於訪問壓力實時管理叢集容量,提高叢集利用率。此時,用於提高機器利用率的資源排程和治理中心(SOA)是關鍵。
下圖是新浪核心業務圖,我們有理由相信新浪使用的是流動計算架構這個我不太確定,請大神糾正。

image.png
好,羅列清楚,有概念了我們就做簡單的併發測試
貼一下Python的selenium程式碼:
# -*- coding: utf-8 -*- import requests import threading import time class postrequests(): def __init__(self): self.url = '請求的url' def post(self): try: r = requests.post(self.url,files=self.files) print(r.text) except Exception as e: print(e) def login(): login = postrequests() return login.post() # if __name__ == '__main__': #login() try: i = 0 # 這裡是執行緒數 tasks_number = 150 print('測試啟動') time1 = time.clock() while i < tasks_number: t = threading.Thread(target=login) t.start() i +=1 time2 = time.clock() times = time2 - time1 print(times/tasks_number) except Exception as e: print(e)
以下是框架併發測試過程和內容
測試物件:單應用
使用技術:JAVA的TestNg和Python的selenium 測試物件搭建:首先是單應用,簡單的sql查詢,開發一個簡單的API介面,程式碼不貼。 首先使用7個執行緒同時執行7個請求,請求時間超過7秒就算測試失敗,程式碼如下:
@Test(threadPoolSize = 7, invocationCount = 7, timeOut = 7000)
結果:通過沒有報錯沒有超時。
把所有引數翻了一番之後
@Test(threadPoolSize = 14, invocationCount = 14, timeOut = 7000)
結果:開始出現異常,請求時間出現測試失敗的。
測試物件:SSM
使用技術:JAVA的TestNg和Python的selenium
測試物件搭建:MVC,簡單的sql查詢,簡單的API介面,程式碼不貼。
首先使用14個執行緒執行14次,請求時間超過5秒就算測試失敗,程式碼如下:
@Test(threadPoolSize = 14, invocationCount = 14, timeOut = 5000)
結果:通過沒有報錯沒有超時。
把所有引數提升
@Test(threadPoolSize = 180, invocationCount = 1800, timeOut = 5000)
結果:請求明顯變慢,有些測試開始失敗超時,但是並沒出現異常。
繼續增加引數值
@Test(threadPoolSize = 2000, invocationCount = 8000, timeOut = 5000)
結果:請求明顯變慢,開始失敗超時,並出現異常。
注:這裡有人會說可以使用redis快取來提高資料庫速度,我這裡也配置了redis進行測試在@Test(threadPoolSize = 2800, invocationCount = 28000, timeOut = 4000)出現異常和超時請求
測試物件:dubbo
使用技術:JAVA的TestNg和Python的selenium
測試物件搭建:dubbo分散式叢集,使用三臺伺服器做叢集分佈,權重一致,使用redis快取+mysql資料庫技術。
首先使用2000個執行緒執行18000次,請求時間超過4秒就算測試失敗,程式碼如下:
@Test(threadPoolSize = 2000, invocationCount = 18000, timeOut = 4000)
結果:執行了很長時間,但是並沒出現超時和異常。
把所有引數翻了一番之後
@Test(threadPoolSize = 4000, invocationCount = 24000, timeOut = 4000)
結果:還是沒有出現異常,也沒有出現超時
繼續提升引數值
@Test(threadPoolSize = 20000, invocationCount = 200000, timeOut = 4000)
結果還是沒報錯
於是修改策略,併發請求*5臺電腦
@Test(threadPoolSize = 40000, invocationCount = 200000, timeOut = 4000)
結果:終於出現異常和超時請求,當然這還是三臺伺服器,相信更多的資源可以有更好的體驗。
備註:由於測試物件的業務邏輯比較簡單,當然,如果測試對像業務邏輯複雜可能會出現誤差,以大神你們的為準。
第四個臣妾只能說我做不到,首先增加資源吃力,其次我以為測試用例只需要增加計算器執行緒數,同時增加併發請求,但是後來發現這樣的請求並沒辦法模擬出那麼恐怖的併發量。這個希望技術提升後來繼續操作,畢竟對高併發這塊興趣還是蠻大的。今後有可能會繼續模擬環境,當然大神也可以補充改正我。