幾個關於網站架構和性能的問題(我在知乎上的問答)

1 併發
1.1 這個併發是怎麼界定的?
由於我的以爲按照計算機的邏輯,應該是不會有「同一刻」進來的請求,多多少少都會有前後的吧?
若是按照秒來計算,不一樣的請求可能都在30秒過來,可是他們的毫秒數但是不同的,算是併發麼?
因此這個併發是怎麼計算?

說到併發,必定要說起並行了。
「並行」是指不管從微觀仍是宏觀,兩者都是一塊兒執行的,就好像兩我的各拿一把鐵杴在挖坑,一小時後,每人一個大坑。 
而「併發」在微觀上不是同時執行的,只是把時間分紅若干段,使多個進程快速交替的執行,從宏觀外來看,好像是這些進程都在執行,這就好像兩我的用同一把鐵杴,輪流挖坑,一小時後,兩我的各挖一個小一點的坑,要想挖兩個大一點得坑,必定會用兩個小時。 
從以上本質不難看出,「併發」執行,在多個進程存在資源衝突時,並無從根本提升執行效率
真正的同時處理請求,必須在多核服務器或者分佈式系統上。英特爾的超線程技術也只是作到在納秒級的線程切換,也沒法達到同時處理。

同時必須說起的就是——Amahl定律
Amahl定律是計算機科學中很是重要的定律,它定義了串行系統並行優化後加速比的計算公式和理論上限。
加速比定義:加速比=優化前系統耗時/優化後系統耗時
所謂加速比,就是優化前的耗時與優化後耗時的比值。加速比越高,代表優化效果越明顯。
Amahl定律給出了加速比與系統並行度和處理器數量的關係。設加速比爲Speedup,系統內必須串行化的程序比重爲F,CPU處理器數量爲N,則有:

根據此公式,若是CPU處理器數量趨近於無窮,那麼加速比與系統的串行化率成反比,若是系統中必須有50%的代碼串行執行,那麼系統的最大加速比爲2。

1.2 併發測試
一般對一個應用咱們會提出這麼一個問題(也許表達不嚴謹,望更正):
1秒內可以響應的最大請求數是多少?
單個請求響應的最長時間是多少?
上面兩個問題若是要測出結果的話通常怎麼作,好比要求哪些前提條件,網絡、帶寬什麼的?

這兩個問題,其實分別表明了性能測試中兩大基礎概念了。分別爲吞吐量響應時間。這兩個東西不能分開獨立考慮的。當吞吐量爬高時,響應時間必然增加,固然與此同此還有可能服務器端內存泄漏直接崩潰。

測試實施環境的話,環境風險因素儘可能要避免,好比用無線網絡、負載發生器環境純淨不能有360、防火牆、其餘高消耗資源應用。在較爲純淨的環境下,利用 控制變量法_百度百科 減小環境干擾。
至於性能分析:

2 隊列
其實這個跟併發應該是有關係的,常常聽到這麼一句:流量太大,響應不過來,只好對用戶請求進行排隊處理,問題來了:

2.1 什麼狀況下須要排隊? 
按照個人理解,web server如IIS tomcat他們應該有本身的隊列吧?也就是說他們應該可以負載起必定數量的請求,是否是超出這個數量就會掛起,致使超時,因此才須要開發者本身對請求進行排隊?
若是是這樣的話,怎麼才能知道你的web server所能負載的最大請求數?
BTW,這個同1,所能負載的最大請求數是個什麼概念,1s內? 仍是某個瞬間?

這要根據大家的服務器設備、網絡帶寬、負載均衡部署等實際狀況來看的。同時還要看大家的開發人員代碼質量。在考慮這些之後,你能夠嘗試着花三小時時間,不斷的多進程的朝服務器發送請求,同時統計成功響應請求數目。
每秒響應次數=成功響應請求數目/累計負載時間
每次請求服務器時,不斷遞增客戶端進程數,直至達到每秒響應次數沒法遞增或者增速放緩。
經過這種方式,不斷的提升多進程發送請求的能力,就能發現你的web server所能負載的最大請求數。

吞吐量是指對網絡、設備、端口、虛電路或其餘設施,單位時間內成功地傳送數據的數量(以比特、字節、分組等測量)。注:每一個請求包含的字節數是不盡相同的。併發一千萬個十字節的請求,跟併發一百萬個百字節的請求,是極大不一樣的。
因此在考慮吞吐量的同時,還要引入一個概念每秒處理事務數(TPS)
每秒處理事務數是評價系統性能均以每秒鐘完成的技術交易的數量來衡量。 系統總體處理能力取決於處理能力最低模塊的TPS 值(木桶原理)。

2.2 若是須要排隊,在哪一個層排隊?
假設我是J2EE應用,servlet接受請求的,那麼我是在servlet的入口處就作排隊仍是其餘地方?
public void doGet(HttpRequest req,HttpResponse res){
	//這裏對req排隊?
}

系統配置不合理,線程數、鏈接端口數、內存大小、緩存大小等;
數據庫查詢效率低下致使了排隊,一條查詢耗時都是30餘秒堵在這很常見吧,還有諸如數據庫Index設計不合理,表空間配置不合理,SGA&PGA配置不合理;
編碼處理業務邏輯不合理致使了排隊,明明能並行處理的業務使用了串行處理,在循環中使用了字符串的+=操做,固然嚴重點的還有疫苗:Java HashMap的死循環

2.3 有沒有取代排隊的辦法

除了添加服務器進行負載均衡,有沒有別的辦法? 

我在想若是某個業務方法是同步的,好比
public void synchronized operation(){}
這種狀況下操做系統會不會自動排隊?

出現性能瓶頸緣由不只僅是排隊,經常同步的操做是爲了必要的數據原子性而設計。除了添加服務器進行負載均衡,還有如下方法:
業務:更改業務邏輯,將原有的串行處理改成並行處理;
代碼:多線程代碼段,作好變量同步,推薦看Java併發編程實戰 (豆瓣)
數據庫:作好sql優化;
部署:增長應用節點,以提高應用吞吐量;
有時只是緩存過小稍微調整下就行了;
有時jvm設置不合理修改下相應的配置就行了;
解決性能問題
品味性能之道<三>:方法論


3 負載均衡
3.1 負載均衡的適用場景是什麼
我的理解,若是單個服務器可以知足需求的話,無端增長了n臺服務器來負載是否是反而會下降響應時間?

的確負載均衡器自己的性能也要考慮地;
同時作負載均衡不斷的橫向擴展服務器架構,

3.2 負載均衡環境下的應用部署
對於我來講,感受多臺服務器下面的應用部署就是個噩夢,由於咱們的應用隨時均可能更改,並且改動的地方也不集中,每次逐個操做真的很崩潰。

大家須要一個集羣運維管理平臺,通常大公司會本身開發,最近我也在本身寫個簡略的版本將就用,不過我只設計了應用的部署,數據庫那塊的部署管理沒打算弄。這東西還在作的過程當中。(我能說我上班太閒了,本身個弄着玩的麼?)
最終這玩意夭折了,我太懶了...

3.3 負載均衡下的session共享如何處理,是否是採用單點登陸解決?

nginx負載均衡器處理session共享的幾種方法
1) 不使用session,換做cookie
2) 應用服務器自行實現共享
3) ip_hash
4) upstream_hash
5) redis存放seesionid信息

web應用有session的概念,同時數據庫也有session的概念,其實負載均衡不止應用負載均衡的。
  • HTTP重定向負載均衡
  • DNS域名解析負載均衡
  • 反向代理負載均衡
  • IP負載均衡
  • 數據鏈路層負載均衡
ASP.NET性能優化之分佈式Session
Session服務器配置指南與使用經驗
 


4 數據庫讀寫操做

單個請求讀寫都沒有問題,可是假設某個瞬間有n個請求過來,而且「同時」要寫操做,那麼需不須要開發人員在這個邏輯裏面作一些額外的工做?好比再排個隊之類?仍是啥都不關,交給數據庫處理?

我也不是專攻數據庫的,給點我知道的。讀寫分離,index調優,sql調優,清理數據庫磁盤碎片,作memcached數據庫緩存;
(ps:請留意接下來的博客發佈,我已經計劃好了關於mysql數據庫的東西)


5 其餘

5.1 多語言組合
常聽到某某網站採用了前端php+後端java的方式,一直很奇怪,怎麼融合的?(但願這個詳細點)

通訊拆包封包嘛!
SOA面向服務,Restful資源服務,
Message Queue等等。

5.2 還沒想好

 
處理性能瓶頸須要必定的功力的,推薦看看葛一鳴《Java程序性能優化 (豆瓣)》、羅敏《品悟性能優化 (豆瓣)》、《Effective Java 第二版 中文版/Sun公司核心技術叢書 (豆瓣)》、《Web性能優化 (豆瓣)》、《Java性能優化權威指南 (豆瓣)


引自 @張易
若是你所在的網站屬於小型網站(PV百萬)如下,建議進行數據庫調優,提升代碼質量並適當引入緩存。
若是你所在網站屬中小型網站(PV百萬至千萬),建議在以上操做的前提下,分離服務器職責,但服務器總數量應控制在3-5臺(我經歷過的生產環境,PV300w加大量數據庫讀寫應用,兩臺服務器綽綽有餘),適當引入熱備冷備和負載均衡。
若是你所在網站屬大型網站(PV千萬級以上),建議在以上操做的前提下,聘用專業系統運維及應用運維維護服務器。固然,那個時候,你就不須要來知乎上提問了,問專業人士吧。
網站的性能,和代碼質量,服務配置,服務器數量都有着密不可分的關係,具體如何取捨,還應根據我的狀況自行斟酌。



相關文章
相關標籤/搜索