前面提到多進(jìn)程的并行可以提高并發(fā)度,那么進(jìn)程是越多越好?一般遇到這種問題都回答不是,事實(shí)上,很多大型項(xiàng)目都不會(huì)同時(shí)開太多進(jìn)程。
下面以支持100K并發(fā)量的Nginx服務(wù)器為例。
Nginx是一個(gè)高性能、高并發(fā)的Web服務(wù)器,也就是說它可以同時(shí)處理超過10萬個(gè)HTTP請(qǐng)求,而它建議的啟動(dòng)的進(jìn)程數(shù)不要超過CPU個(gè)數(shù),為什么呢?
我們首先要知道Nginx是Master-worker模型,Master進(jìn)程只負(fù)責(zé)管理Worker進(jìn)程,而Worker進(jìn)程是負(fù)責(zé)處理真實(shí)的請(qǐng)求。每個(gè)Worker進(jìn)程能夠處理的請(qǐng)求數(shù)跟內(nèi)存有關(guān),因?yàn)樵贚inux上Nginx使用了epoll這種多路復(fù)用的IO接口,所以不需要多線程做并行也能實(shí)現(xiàn)并發(fā)。
而多進(jìn)程有一個(gè)壞處就是帶來了CPU上下文切換時(shí)間,所以一味提高進(jìn)程個(gè)數(shù)反而使系統(tǒng)性能下降。當(dāng)然如果當(dāng)前進(jìn)程小于CPU個(gè)數(shù),就沒有充分利用多核的資源,所以Nginx建議Worker數(shù)應(yīng)該等于CPU個(gè)數(shù)。
我們想想進(jìn)程數(shù)應(yīng)該等于CPU數(shù),但是如果進(jìn)程有阻塞呢?這時(shí)是應(yīng)該提高進(jìn)程數(shù)增加并行數(shù)的。
在Nginx的例子中,如果Nginx主要負(fù)責(zé)靜態(tài)內(nèi)容的下載,而服務(wù)器內(nèi)存比較小,大部分文件訪問都需要讀磁盤,這時(shí)候進(jìn)程很容易阻塞,所以建議提高下Worker數(shù)目。
一般情況下除了確保進(jìn)程數(shù)等于CPU數(shù),我們還可以綁定進(jìn)程與CPU,這就保證了最少的CPU上下文切換。
在Nginx中可以這樣配置。
worker_processes 4;
worker_cpu_affinity 1000 0100 0010 0001;
這是通過系統(tǒng)調(diào)用sched_setaffinity()實(shí)現(xiàn)了,感興趣大家可以自行學(xué)習(xí)這方面的知識(shí)。
通過這個(gè)例子大家對(duì)進(jìn)程的并發(fā)與并行應(yīng)該有更深入的理解,接下來了解下進(jìn)程狀態(tài)的概念。