1. 微服務架構介紹
1.1 什么是微服務架構?
形像一點來說,微服務架構就像搭積木,每個微服務都是一個零件,并使用這些零件組裝出不同的形狀。通俗來說,微服務架構就是把一個大系統按業務功能分解成多個職責單一的小系統,并利用簡單的方法使多個小系統相互協作,組合成一個大系統。
如果學科派一點,微服務架構就是把因相同原因而變化的功能聚合到一起,而把因不同原因而變化的功能分離開,并利用輕量化機制(通常為HTTP RESTful API)實現通信。
追本溯源,Martin Folwer對微服務架構的定義是:
微服務架構是一種架構模式,它提倡將單一應用程序劃分成一組小的服務,服務之間互相協調、互相配合,為用戶提供最終價值。每個服務運行在其獨立的進程中,服務與服務間采用輕量級的通信機制互相協作(通常是基于HTTP協議的RESTful API)。每個服務都圍繞著具體業務進行構建,并且能夠被獨立的部署到生產環境、類生產環境等。另外,對具體的服務而言,應根據業務上下文,選擇合適的語言、工具對其進行構建。
對于我個人,我更喜歡一種延續性的解釋,微服務架構≈ 模塊化開發+分布式計算。不管微服務架構的定義怎么樣,都是在描述一個核心思想:把大系統拆分成小型系統,把大事化小,以降低系統的復雜性,從而大幅降低系統建設、升級、運維的風險和成本。
順帶提一下,亞馬遜創始人Jeff Bezos在2002年就說過:所有團隊的模塊都要以Service Interface的方式將數據和功能開放出來。不這樣做的人會被炒魷魚。這才是思路超前的大牛。
需要注意的是“微服務”與“微服務架構”是有本質區別的。“微服務”強調的是服務的大小,它關注的是某一個點。而“微服務架構”則是一種架構思想,需要從整體上對軟件系統進行通盤的考慮。
Chris Richardson說:“微服務”是一個很糟糕的名字,它導致開發人員創建了許多粒度很小的服務,每個服務擁有一個單獨的REST端點。不僅如此,這個名字還暗示了微服務在開發者心目中的重要位置。例如,人們會說“我們可以用微服務來解決這個問題”;我也看到了越來越多的“某某微服務框架”,而實際上,這些框架跟微服務架構不一定有太多聯系,它們只是簡單的Web框架(如:spring-boot)。使用“微服務架構”這個名字會更恰當些。它是一種架構風格,它把一系列協作的服務組織成一個系統來支撐業務。
1.2常見的微服務組件
1.服務注冊:服務提供方將自己調用地址注冊到服務注冊中心,讓服務調用方能夠方便地找到自己。
2.服務發現:服務調用方從服務注冊中心找到自己需要調用的服務的地址。
3.負載均衡:服務提供方一般以多實例的形式提供服務,負載均衡功能能夠讓服務調用方連接到合適的服務節點。并且,節點選擇的工作對服務調用方來說是透明的。
4.服務網關:服務網關是服務調用的唯一入口,可以在這個組件是實現用戶鑒權、動態路由、灰度發布、A/B測試、負載限流等功能。
5.配置中心:將本地化的配置信息(properties,
xml, yaml等)注冊到配置中心,實現程序包在開發、測試、生產環境的無差別性,方便程序包的遷移。
6.API管理:以方便的形式編寫及更新API文檔,并以方便的形式供調用者查看和測試。
7.集成框架:微服務組件都以職責單一的程序包對外提供服務,集成框架以配置的形式將所有微服務組件(特別是管理端組件)集成到統一的界面框架下,讓用戶能夠在統一的界面中使用系統。
8.分布式事務:對于重要的業務,需要通過分布式事務技術(TCC、高可用消息服務、最大努力通知)保證數據的一致性。具有代表性的有spring transaction
9.調用鏈:記錄完成一個業務邏輯時調用到的微服務,并將這種串行或并行的調用關系展示出來。在系統出錯時,可以方便地找到出錯點。具有代表性的有pinpoint.
10.支撐平臺:系統微服務化后,系統變得更加碎片化,系統的部署、運維、監控等都比單體架構更加復雜,那么,就需要將大部分的工作自動化。現在,可以通過Docker等工具來中和這些微服務架構帶來的弊端。 例如:持續集成、藍綠發布、健康檢查、性能健康等等。嚴重點,以我們兩年的實踐經驗,可以這么說,如果沒有合適的支撐平臺或工具,就不要使用微服務架構。
一般情況下,如果希望快速地體會微服務架構帶來的好處,使用Spring Cloud提供的服務注冊(Eureka)、服務發現(Ribbon)、服務網關(Zuul) 三個組件即可以快速入門。其它組件則需要根據自身的業務選擇性使用。
1.3微服務架構有哪些優勢劣勢?
要談優勢,就一定要有對比,我們可以嘗試著從兩個維度來對比:
1.3.1單體架構和微服務架構的對比
【結論】:
n對于簡單項目來說,單體架構5勝8敗。
(優勢項:開發效率、上手難度、運維效率、硬件需求、項目成本;劣勢項:系統設計(高內聚低耦合)、系統設計(擴展性)、需求變更響應速度、系統升級效率、知識積累、非功能需求、職責、成就感、風險)
n對于復雜項目來說,單體架構2勝11敗。
(優勢項:上手難度、運維效率;劣勢項:硬件需求、項目成本、開發效率、系統設計(高內聚低耦合)、系統設計(擴展性)、需求變更響應速度、系統升級效率、知識積累、非功能需求、職責、成就感、風險;)
1.3.2微服務與共享庫的對比.,
1.3.3什么場景需要用微服務架構?
看了上面的比較,微服務架構可以說是以壓倒性的優勢勝過單體架構和共享庫,會讓人產生一種錯覺,微服務架構就是軟件開發中的銀彈。
但是,正如大家所了解的,軟件研發是一個系統工程,它沒有銀彈,不能夠一招鮮吃遍天。正如當年的CMMI和敏捷方法一樣,敏捷雖好,但它不一定能適用于所有的場景,它對組織環境、團隊氛圍、溝通方式、技術能力這些都是有一些要求的,如果用不好,反而會帶來一些負面影響。
那么,我們什么時候需要采用微服務呢?從我個人的經驗來看,我認為有三種場景可以考慮使用微服務。
1.規模大(團隊超過10人)
2.業務復雜度高(系統超過5個子模塊)
3.需要長期演進(項目開發和維護周期超過半年)
2.微服務架構身份認證
2
2.1背景介紹
從單體應用架構到分布式應用架構再到微服務架構,應用的安全訪問在不斷的經受考驗。為了適應架構的變化、需求的變化,身份認證與鑒權方案也在不斷的變革。面對數十個甚至上百個微服務之間的調用,如何保證高效安全的身份認證?面對外部的服務訪問,該如何提供細粒度的鑒權方案?本文將會為大家闡述微服務架構下的安全認證與鑒權方案。
【單體應用VS微服務】
隨著微服務架構的興起,傳統的單體應用場景下的身份認證和鑒權面臨的挑戰越來越大。單體應用體系下,應用是一個整體,一般針對所有的請求都會進行權限校驗。請求一般會通過一個權限的攔截器進行權限的校驗,在登錄時將用戶信息緩存到session中,后續訪問則從緩存中獲取用戶信息。
而微服務架構下,一個應用會被拆分成若干個微應用,每個微應用都需要對訪問進行鑒權,每個微應用都需要明確當前訪問用戶以及其權限。尤其當訪問來源不只是瀏覽器,還包括其他服務的調用時,單體應用架構下的鑒權方式就不是特別合適了。在為服務架構下,要考慮外部應用接入的場景、用戶-服務的鑒權、服務-服務的鑒權等多種鑒權場景。
David
Borsos在倫敦的微服務大會上提出了四種方案:
2.2常見的四種解決方案
2.2.1單點登錄(SSO)
這種方案意味著每個面向用戶的服務都必須與認證服務交互,這會產生大量非常瑣碎的網絡流量和重復的工作,當動輒數十個微應用時,這種方案的弊端會更加明顯。
2.2.2分布式Session
分布式會話方案原理主要是將關于用戶認證的信息存儲在共享存儲中,且通常由用戶會話作為key來實現的簡單分布式哈希映射。當用戶訪問微服務時,用戶數據可以從共享存儲中獲取。在某些場景下,這種方案很不錯,用戶登錄狀態是不透明的。同時也是一個高可用且可擴展的解決方案。這種方案的缺點在于共享存儲需要一定保護機制,因此需要通過安全鏈接來訪問,這時解決方案的實現就通常具有相當高的復雜性了。
2.2.3客戶端Token
令牌在客戶端生成,由身份驗證服務進行簽名,并且必須包含足夠的信息,以便可以在所有微服務中建立用戶身份。令牌會附加到每個請求上,為微服務提供用戶身份驗證,這種解決方案的安全性相對較好,但身份驗證注銷是一個大問題,緩解這種情況的方法可以使用短期令牌和頻繁檢查認證服務等。對于客戶端令牌的編碼方案,Borsos更喜歡使用JSON Web Tokens(JWT),它足夠簡單且庫支持程度也比較好。
2.2.4客戶端Token與API網關結合
這個方案意味著所有請求都通過網關,從而有效地隱藏了微服務。在請求時,網關將原始用戶令牌轉換為內部會話ID令牌。在這種情況下,注銷就不是問題,因為網關可以在注銷時撤銷用戶的令牌。
2.3微服務常見安全認證方案HTTP基本認證
HTTP Basic Authentication(HTTP基本認證)是HTTP 1.0提出的一種認證機制,HTTP基本認證的過程如下:
1.客戶端發送HTTP Request給服務器。
2.因為Request中沒有包含Authorization header,服務器會返回一個401 Unauthozied給客戶端,并且在Response的Header "WWW-Authenticate"中添加信息。
3.客戶端把用戶名和密碼用BASE64加密后,放在Authorization Header中發送給服務器,認證成功。
4.服務器將Authorization Header中的用戶名密碼取出,進行驗證, 如果驗證通過,將根據請求,發送資源給客戶端。
2.3.1Session的認證
基于Session的認證應該是最常用的一種認證機制了。用戶登錄認證成功后,將用戶相關數據存儲到Session中,單體應用架構中,默認Session會存儲在應用服務器中,并且將Session ID返回到客戶端,存儲在瀏覽器的Cookie中。
但是在分布式架構下,Session存放于某個具體的應用服務器中自然就無法滿足使用了,簡單的可以通過Session復制或者Session粘制的方案來解決。
Session復制依賴于應用服務器,需要應用服務器有Session復制能力,不過現在大部分應用服務器如Tomcat、JBoss、WebSphere等都已經提供了這個能力。
除此之外,Session復制的一大缺陷在于當節點數比較多時,大量的Session數據復制會占用較多網絡資源。Session粘滯是通過負載均衡器,將統一用戶的請求都分發到固定的服務器節點上,這樣就保證了對某一用戶而言,Session數據始終是正確的。不過這種方案依賴于負載均衡器,并且只能滿足水平擴展的集群場景,無法滿足應用分割后的分布式場景。
在微服務架構下,每個微服務拆分的粒度會很細,并且不只有用戶和微服務打交道,更多還有微服務間的調用。這個時候上述兩個方案都無法滿足,就要求必須要將Session從應用服務器中剝離出來,存放在外部進行集中管理。可以是數據庫,也可以是分布式緩存,如Memchached、Redis等。這正是David Borsos建議的第二種方案,分布式Session方案。
2.3.2基于Token的認證
隨著Restful API、微服務的興起,基于Token的認證現在已經越來越普遍。Token和Session ID不同,并非只是一個key。Token一般會包含用戶的相關信息,通過驗證Token就可以完成身份校驗。像Twitter、微信、QQ、GitHub等公有服務的API都是基于這種方式進行認證的,一些開發框架如OpenStack、Kubernetes內部API調用也是基于Token的認證。基于Token認證的一個典型流程如下:
1.用戶輸入登錄信息(或者調用Token接口,傳入用戶信息),發送到身份認證服務進行認證(身份認證服務可以和服務端在一起,也可以分離,看微服務拆分情況了)。
2.身份驗證服務驗證登錄信息是否正確,返回接口(一般接口中會包含用戶基礎信息、權限范圍、有效時間等信息),客戶端存儲接口,可以存儲在Session或者數據庫中。
3.用戶將Token放在HTTP請求頭中,發起相關API調用。
4.被調用的微服務,驗證Token權限。
5.服務端返回相關資源和數據。
基于Token認證的好處如下:
1.服務端無狀態:Token機制在服務端不需要存儲session信息,因為Token自身包含了所有用戶的相關信息。
2.性能較好,因為在驗證Token時不用再去訪問數據庫或者遠程服務進行權限校驗,自然可以提升不少性能。
3.支持移動設備。
4.支持跨程序調用,Cookie是不允許垮域訪問的,而Token則不存在這個問題。
5.下面會重點介紹兩種基于Token的認證方案JWT/Oauth2.0。
2.3.2.1JWT介紹
JSON Web Token(JWT)是為了在網絡應用環境間傳遞聲明而執行的一種基于JSON的開放標準(RFC 7519)。來自JWT RFC 7519標準化的摘要說明:JSON Web Token是一種緊湊的,URL安全的方式,表示要在雙方之間傳輸的聲明。JWT一般被用來在身份提供者和服務提供者間傳遞被認證的用戶身份信息,以便于從資源服務器獲取資源,也可以增加一些額外的其它業務邏輯所必須的聲明信息,該Token也可直接被用于認證,也可被加密。
2.3.2.2JWT認證流程
1.客戶端調用登錄接口(或者獲取token接口),傳入用戶名密碼。
2.服務端請求身份認證中心,確認用戶名密碼正確。
3.服務端創建JWT,返回給客戶端。
4.客戶端拿到JWT,進行存儲(可以存儲在緩存中,也可以存儲在數據庫中,如果是瀏覽器,可以存儲在Cookie中)在后續請求中,在HTTP請求頭中加上JWT。
5.服務端校驗JWT,校驗通過后,返回相關資源和數據。
2.3.2.3JWT結構
JWT是由三段信息構成的,第一段為頭部(Header),第二段為載荷(Payload),第三段為簽名(Signature)。每一段內容都是一個JSON對象,將每一段JSON對象采用BASE64編碼,將編碼后的內容用.鏈接一起就構成了JWT字符串。如下:
header.payload.signature
1.頭部(Header)
頭部用于描述關于該JWT的最基本的信息,例如其類型以及簽名所用的算法等。這也可以被表示成一個JSON對象。
{
"typ":"JWT",
"alg":"HS256"
}
在頭部指明了簽名算法是HS256算法。
2.載荷(payload)
載荷就是存放有效信息的地方。有效信息包含三個部分:
l標準中注冊的聲明
l公共的聲明
l私有的聲明
標準中注冊的聲明(建議但不強制使用):
liss:JWT簽發者
lsub:JWT所面向的用戶
laud:接收JWT的一方
lexp:JWT的過期時間,這個過期時間必須要大于簽發時間
lnbf:定義在什么時間之前,該JWT都是不可用的
liat:JWT的簽發時間
ljti:JWT的唯一身份標識,主要用來作為一次性token,從而回避重放攻擊。
公共的聲明 :
公共的聲明可以添加任何的信息,一般添加用戶的相關信息或其他業務需要的必要信息.但不建議添加敏感信息,因為該部分在客戶端可解密。
私有的聲明 :
私有聲明是提供者和消費者所共同定義的聲明,一般不建議存放敏感信息,因為base64是對稱解密的,意味著該部分信息可以歸類為明文信息。
示例如下:
{"iss": "Online JWT Builder",
"iat": 1416797419,
"exp": 1448333419,
"aud": "www.primeton.com",
"sub":"devops@primeton.com",
"GivenName": "dragon",
"Surname": "wang",
"admin": true
}
3.簽名(signature)
創建簽名需要使用Base64編碼后的header和payload以及一個秘鑰。將base64加密后的header和base64加密后的payload使用.連接組成的字符串,通過header中聲明的加密方式進行加鹽secret組合加密,然后就構成了jwt的第三部分。
比如:HMACSHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload), secret)
2.3.2.4JWT的優點
1.跨語言,JSON的格式保證了跨語言的支撐
2.基于Token,無狀態
3.占用字節小,便于傳輸
2.3.2.5Token注銷
Token的注銷,由于Token不存儲在服務端,由客戶端存儲,當用戶注銷時,Token的有效時間還沒有到,還是有效的。所以如何在用戶注銷登錄時讓Token注銷是一個要關注的點。一般有如下幾種方式:
1.Token存儲在Cookie中,這樣客戶端注銷時,自然可以清空掉
2.注銷時,將Token存放到分布式緩存中,每次校驗Token時區檢查下該Token是否已注銷。不過這樣也就失去了快速校驗Token的優點。
3.多采用短期令牌,比如令牌有效期是20分鐘,這樣可以一定程度上降低注銷后Token可用性的風險。
2.3.3OAuth 2.0介紹
OAuth的官網介紹:An open protocol to allow secure
API authorization in a simple and standard method from desktop and web
applications。OAuth是一種開放的協議,為桌面程序或者基于BS的web應用提供了一種簡單的,標準的方式去訪問需要用戶授權的API服務。OAUTH認證授權具有以下特點:
1.簡單:不管是OAuth服務提供者還是應用開發者,都很容易于理解與使用;
2.安全:沒有涉及到用戶密鑰等信息,更安全更靈活;
3.開放:任何服務提供商都可以實現OAuth,任何軟件開發商都可以使用OAuth;
OAuth
2.0是OAuth協議的下一版本,但不向后兼容OAuth 1.0,即完全廢止了OAuth 1.0。OAuth 2.0關注客戶端開發者的簡易性。要么通過組織在資源擁有者和HTTP服務商之間的被批準的交互動作代表用戶,要么允許第三方應用代表用戶獲得訪問的權限。同時為Web應用,桌面應用和手機,和起居室設備提供專門的認證流程。2012年10月,OAuth 2.0協議正式發布為RFC 6749。
2.3.3.1授權流程
OAuth
2.0的流程如下:
(A)用戶打開客戶端以后,客戶端要求用戶給予授權。
(B)用戶同意給予客戶端授權。
(C)客戶端使用上一步獲得的授權,向認證服務器申請令牌。
(D)認證服務器對客戶端進行認證以后,確認無誤,同意發放令牌。
(E)客戶端使用令牌,向資源服務器申請獲取資源。
(F)資源服務器確認令牌無誤,同意向客戶端開放資源。
2.3.3.2四大角色
由授權流程圖中可以看到OAuth 2.0有四個角色:客戶端、資源擁有者、資源服務器、授權服務器。
1.客戶端:客戶端是代表資源所有者對資源服務器發出訪問受保護資源請求的應用程序。
2.資源擁有者:資源擁有者是對資源具有授權能力的人。
3.資源服務器:資源所在的服務器。
4.授權服務器:為客戶端應用程序提供不同的Token,可以和資源服務器在統一服務器上,也可以獨立出去。
2.3.3.3客戶端的授權模式
客戶端必須得到用戶的授權(Authorization Grant),才能獲得令牌(access token)。OAuth 2.0定義了四種授權方式:authorizationcode、implicit、resource owner password credentials、client credentials。
1.授權碼模式(authorization code)
授權碼模式(authorization code)是功能最完整、流程最嚴密的授權模式。它的特點就是通過客戶端的后臺服務器,與"服務提供商"的認證服務器進行互動。流程如下:
1)用戶訪問客戶端,后者將前者導向認證服務器。
2)用戶選擇是否給予客戶端授權。
3)假設用戶給予授權,認證服務器將用戶導向客戶端事先指定的"重定向URI"(redirection
URI),同時附上一個授權碼。
4)客戶端收到授權碼,附上早先的"重定向URI",向認證服務器申請令牌。這一步是在客戶端的后臺的服務器上完成的,對用戶不可見。
5)認證服務器核對了授權碼和重定向URI,確認無誤后,向客戶端發送訪問令牌(access token)和更新令牌(refresh token)。
2.簡化模式(implicit)
簡化模式(Implicit Grant Type)不通過第三方應用程序的服務器,直接在瀏覽器中向認證服務器申請令牌,跳過了"授權碼"這個步驟,因此得名。所有步驟在瀏覽器中完成,令牌對訪問者是可見的,且客戶端不需要認證。流程如下:
1)客戶端將用戶導向認證服務器。
2)用戶決定是否給于客戶端授權。
3)假設用戶給予授權,認證服務器將用戶導向客戶端指定的"重定向URI",并在URI的Hash部分包含了訪問令牌。
4)瀏覽器向資源服務器發出請求,其中不包括上一步收到的Hash值。
5)資源服務器返回一個網頁,其中包含的代碼可以獲取Hash值中的令牌。
6)瀏覽器執行上一步獲得的腳本,提取出令牌。
7)瀏覽器將令牌發給客戶端。
3.密碼模式(Resource Owner Password Credentials)
密碼模式中,用戶向客戶端提供自己的用戶名和密碼。客戶端使用這些信息,向"服務商提供商"索要授權。在這種模式中,用戶必須把自己的密碼給客戶端,但是客戶端不得儲存密碼。這通常用在用戶對客戶端高度信任的情況下,比如客戶端是操作系統的一部分,或者由一個著名公司出品。而認證服務器只有在其他授權模式無法執行的情況下,才能考慮使用這種模式。流程如下:
1)用戶向客戶端提供用戶名和密碼。
2)客戶端將用戶名和密碼發給認證服務器,向后者請求令牌。
3)認證服務器確認無誤后,向客戶端提供訪問令牌。
4.客戶端模式(Client Credentials)
客戶端模式(Client Credentials Grant)指客戶端以自己的名義,而不是以用戶的名義,向"服務提供商"進行認證。嚴格地說,客戶端模式并不屬于OAuth框架所要解決的問題。
在這種模式中,用戶直接向客戶端注冊,客戶端以自己的名義要求"服務提供商"提供服務,其實不存在授權問題。流程如下:
1)客戶端向認證服務器進行身份認證,并要求一個訪問令牌。
2)認證服務器確認無誤后,向客戶端提供訪問令牌。
2.3.4思考總結
正如David Borsos所建議的一種方案,在微服務架構下,我們更傾向于將Oauth和JWT結合使用,Oauth一般用于第三方接入的場景,管理對外的權限,所以比較適合和API網關結合,針對于外部的訪問進行鑒權(當然,底層Token標準采用JWT也是可以的)。JWT更加輕巧,在微服務之間進行訪問鑒權已然足夠,并且可以避免在流轉過程中和身份認證服務打交道。當然,從能力實現角度來說,類似于分布式Session在很多場景下也是完全能滿足需求,具體怎么去選擇鑒權方案,還是要結合實際的需求來。
3.如何進行容量設計
3
3.1需求緣起
互聯網公司,這樣的場景是否似曾相識:
場景一:pm要做一個很大的運營活動,技術老大殺過來,問了兩個問題:
(1)機器能抗住么?
(2)如果扛不住,需要加多少臺機器?
場景二:系統設計階段,技術老大殺過來,又問了兩個問題:
(1)數據庫需要分庫么?
(2)如果需要分庫,需要分幾個庫?
技術上來說,這些都是系統容量預估的問題,容量設計是架構師必備的技能之一。常見的容量評估包括數據量、并發量、帶寬、CPU/MEM/DISK等,今天分享的內容,就以【并發量】為例,看看如何回答好這兩個問題。
3.2容量評估的步驟與方法
【步驟一:評估總訪問量】
如何知道總訪問量?對于一個運營活動的訪問量評估,或者一個系統上線后PV的評估,有什么好的方法?
答案是:詢問業務方,詢問運營同學,詢問產品同學,看對運營活動或者產品上線后的預期是什么。
舉例:58要做一個APP-push的運營活動,計劃在30分鐘內完成5000w用戶的push推送,預計push消息點擊率10%,求push落地頁系統的總訪問量?
回答:5000w*10% = 500w
【步驟二:評估平均訪問量QPS】
如何知道平均訪問量QPS?
答案是:有了總量,除以總時間即可,如果按照天評估,一天按照4w秒計算。
舉例1:push落地頁系統30分鐘的總訪問量是500w,求平均訪問量QPS
回答:500w/(30*60) = 2778,大概3000QPS
舉例2:主站首頁估計日均pv 8000w,求平均訪問QPS
回答:一天按照4w秒算,8000w/4w=2000,大概2000QPS
提問:為什么一天按照4w秒計算?
回答:一天共24小時*60分鐘*60秒=8w秒,一般假設所有請求都發生在白天,所以一般來說一天只按照4w秒評估
【步驟三:評估高峰QPS】
系統容量規劃時,不能只考慮平均QPS,而是要抗住高峰的QPS,如何知道高峰QPS呢?
答案是:根據業務特性,通過業務訪問曲線評估
舉例:日均QPS為2000,業務訪問趨勢圖如下圖,求峰值QPS預估?
回答:從圖中可以看出,峰值QPS大概是均值QPS的2.5倍,日均QPS為2000,于是評估出峰值QPS為5000。
說明:有一些業務例如“秒殺業務”比較難畫出業務訪問趨勢圖,這類業務的容量評估不在此列。
【步驟四:評估系統、單機極限QPS】
如何評估一個業務,一個服務單機能的極限QPS呢?
答案是:壓力測試
在一個服務上線前,一般來說是需要進行壓力測試的(很多創業型公司,業務迭代很快的系統可能沒有這一步,那就悲劇了),以APP-push運營活動落地頁為例(日均QPS2000,峰值QPS5000),這個系統的架構可能是這樣的:
1)訪問端是APP
2)運營活動H5落地頁是一個web站點
3)H5落地頁由緩存cache、數據庫db中的數據拼裝而成
通過壓力測試發現,web層是瓶頸,tomcat壓測單機只能抗住1200的QPS(一般來說,1%的流量到數據庫,數據庫500QPS還是能輕松抗住的,cache的話QPS能抗住,需要評估cache的帶寬,假設不是瓶頸),我們就得到了web單機極限的QPS是1200。一般來說,線上系統是不會跑滿到極限的,打個8折,單機線上允許跑到QPS1000。
【步驟五:根據線上冗余度回答兩個問題】
好了,上述步驟1-4已經得到了峰值QPS是5000,單機QPS是1000,假設線上部署了2臺服務,就能自信自如的回答技術老大提出的問題了:
(1)機器能抗住么?->峰值5000,單機1000,線上2臺,扛不住
(2)如果扛不住,需要加多少臺機器?->需要額外3臺,提前預留1臺更好,給4臺更穩
除了并發量的容量預估,數據量、帶寬、CPU/MEM/DISK等評估亦可遵循類似的步驟。
3.3總結
互聯網架構設計如何進行容量評估:
【步驟一:評估總訪問量】->詢問業務、產品、運營
【步驟二:評估平均訪問量QPS】->除以時間,一天算4w秒
【步驟三:評估高峰QPS】->根據業務曲線圖來
【步驟四:評估系統、單機極限QPS】->壓測很重要
【步驟五:根據線上冗余度回答兩個問題】->估計冗余度與線上冗余度差值