1. 常用服務(wù)器模型
a.迭代服務(wù)器:只有一個(gè)進(jìn)程/線程處理請(qǐng)求。一般為單進(jìn)程,加上select多路復(fù)用,非阻塞socket。
b.迭代/并發(fā)混合型服務(wù)器:平時(shí)迭代處理,對(duì)消耗大的請(qǐng)求并發(fā)處理。處理請(qǐng)求時(shí)設(shè)置一個(gè)超時(shí),當(dāng)請(qǐng)求的處理時(shí)間超時(shí)時(shí),創(chuàng)建一個(gè)進(jìn)程/線程,把處理轉(zhuǎn)給新的進(jìn)程/線程處理,主進(jìn)程/線程繼續(xù)處理其他請(qǐng)求。
c.并發(fā)服務(wù)器:多個(gè)進(jìn)程/線程并發(fā)處理請(qǐng)求。
2. 以上三類的服務(wù)器比較
迭代服務(wù)器:最簡(jiǎn)單,性能不高。
并發(fā)服務(wù)器:性能較高,但結(jié)構(gòu)相對(duì)比較復(fù)雜,開(kāi)發(fā)難度中等。
迭代/并發(fā)混合型服務(wù)器:性能不錯(cuò),但結(jié)構(gòu)通常比單純的并發(fā)服務(wù)器更復(fù)雜。
3. 多進(jìn)程的并發(fā)服務(wù)器
a. 每個(gè)連接fork一個(gè)進(jìn)程:主進(jìn)程accpet連接,有新連接到來(lái)時(shí)fork一個(gè)進(jìn)程,然后繼續(xù)accept,等待新的連接。數(shù)據(jù)傳輸由子進(jìn)程處理,處理完后子進(jìn)程exit。每個(gè)子進(jìn)程只處理一個(gè)連接。
b. Prefork進(jìn)程:主進(jìn)程預(yù)先f(wàn)ork一些進(jìn)程,各個(gè)子進(jìn)程競(jìng)爭(zhēng)accept,然后處理數(shù)據(jù)傳輸。一個(gè)子進(jìn)程可以處理一個(gè)連接,也可以同時(shí)處理多個(gè)連接(通過(guò)select等)。
c. Prefork進(jìn)程:由父進(jìn)程accept請(qǐng)求,通過(guò)流管道轉(zhuǎn)發(fā)fd到子進(jìn)程,子進(jìn)程收到fd后,處理數(shù)據(jù)傳輸,處理結(jié)束后通知父進(jìn)程。父進(jìn)程處理的事情比較簡(jiǎn)單,容易監(jiān)控子進(jìn)程。
以上3種方式性能比較:
a.每個(gè)連接fork一個(gè)進(jìn)程:處理smtp等狀態(tài)較多,數(shù)據(jù)量比較大時(shí)比較簡(jiǎn)單實(shí)用,總體性能不大好。
b.Prefork進(jìn)程,各個(gè)子進(jìn)程競(jìng)爭(zhēng)accept:比較簡(jiǎn)單,性能不錯(cuò)。
c.Prefork進(jìn)程,由父進(jìn)程accept請(qǐng)求,通過(guò)流管道轉(zhuǎn)發(fā)fd到子進(jìn)程:代碼復(fù)雜,性能一般不如上一種。
4. 多線程的并發(fā)服務(wù)器
a.每個(gè)連接一個(gè)線程
b.Prethread多個(gè)線程,各個(gè)線程互斥accept
c.Prethread多個(gè)線程,主線程accept并分發(fā)連接給子線程
5. 多進(jìn)程與多線程的比較
使用線程的模型:性能比使用進(jìn)程要高,但代碼比較復(fù)雜,對(duì)代碼質(zhì)量要求更高,線程出錯(cuò)后可能會(huì)影響到所有線程,多進(jìn)程的模式一個(gè)進(jìn)程出錯(cuò)一般不會(huì)影響其他進(jìn)程。
多線程模型共享數(shù)據(jù)比較簡(jiǎn)單有效,多進(jìn)程模型共享數(shù)據(jù)比較麻煩,效率也不如線程。
6. 一些流行的網(wǎng)絡(luò)服務(wù)器采用的模型
Sendmail: 采用多進(jìn)程,每個(gè)連接fork一個(gè)進(jìn)程.
每個(gè)連接fork一個(gè)子進(jìn)程
子進(jìn)程只處理一個(gè)連接
子進(jìn)程fork一個(gè)localmail進(jìn)程(可以由用戶自己編寫(xiě)),通過(guò)管道把數(shù)據(jù)轉(zhuǎn)給localmail處理,把郵件處理業(yè)務(wù)邏輯獨(dú)立出來(lái)
優(yōu)點(diǎn):結(jié)構(gòu)簡(jiǎn)單,不用維護(hù)復(fù)雜的狀態(tài)機(jī)
Apache1.3:采用多進(jìn)程, prefork進(jìn)程
子進(jìn)程競(jìng)爭(zhēng)accept,每次只處理一個(gè)連接
主進(jìn)程不accept,根據(jù)負(fù)載情況調(diào)整子進(jìn)程數(shù)量
子進(jìn)程運(yùn)行一段時(shí)間后,主進(jìn)程會(huì)讓它退出,然后創(chuàng)建一個(gè)新的進(jìn)程,防止內(nèi)存泄漏等
主進(jìn)程通過(guò)shared memory監(jiān)控子進(jìn)程
移動(dòng)QQ: Prefork多個(gè)進(jìn)程,競(jìng)爭(zhēng)accept,
典型的一問(wèn)一答TCP服務(wù)器,結(jié)構(gòu)簡(jiǎn)單
每個(gè)進(jìn)程通過(guò)select可以同時(shí)處理多個(gè)連接
采用這種結(jié)構(gòu)的原因有:
每秒請(qǐng)求<1000,可以滿足要求
結(jié)構(gòu)簡(jiǎn)單,容易開(kāi)發(fā)、維護(hù)