專利名稱:一種實(shí)現(xiàn)單機(jī)支持高并發(fā)處理方法及系統(tǒng)的制作方法
技術(shù)領(lǐng)域:
本發(fā)明涉及一種網(wǎng)絡(luò)數(shù)據(jù)傳輸,尤其涉及單機(jī)支持高并發(fā)訪問的處理方法及系統(tǒng)。
背景技術(shù):
并發(fā)是指網(wǎng)站在同一時(shí)間訪問的人數(shù),人數(shù)越多,瞬間帶寬要求更高,也就是要求服務(wù)器瞬間處理的流量越大,當(dāng)并發(fā)數(shù)超過一定量(例如百萬級(jí))后稱為高并發(fā),網(wǎng)站如果要在短時(shí)間內(nèi)響應(yīng)高并發(fā)的請(qǐng)求,需要對(duì)服務(wù)器的處理能力提出更高要求。目前已有的高并發(fā)解決方案,多采用分布式的集群部署方式。這種方式要求前端布置一個(gè)服務(wù)器,后端布置多臺(tái)服務(wù)器,前端的一個(gè)服務(wù)器用于負(fù)載均衡,將并發(fā)轉(zhuǎn)發(fā)給后端的服務(wù)器,后端的服務(wù)器進(jìn)行業(yè)務(wù)處理。這種分布式的系統(tǒng)架構(gòu)雖然對(duì)高并發(fā)處理具有一定的效果,但其系統(tǒng)設(shè)計(jì)及部署都比較復(fù)雜,并且整體成本較高。而單機(jī)(即單服務(wù)器)環(huán)境下支持的并發(fā)數(shù)小,當(dāng)單機(jī)系統(tǒng)需要支持更多用戶時(shí),只能通過部署更多軟硬件來擴(kuò)容,造成資源浪費(fèi),成本增加。
發(fā)明內(nèi)容
本發(fā)明要解決的主要技術(shù)問題是,提供一種實(shí)現(xiàn)單機(jī)支持高并發(fā)處理方法及系統(tǒng),不需要分布式的集群部署,而是采用單機(jī)系統(tǒng)來支持多用戶的高并發(fā)處理,使單機(jī)系統(tǒng)實(shí)現(xiàn)支持更多用戶。根據(jù)本發(fā)明的第一方面,提供一種實(shí)現(xiàn)單機(jī)支持高并發(fā)處理方法,包括由同一服務(wù)器執(zhí)行的主線程工作步驟和工作線程工作步驟,所述主線程工作步驟包括:主線程監(jiān)聽事件;當(dāng)主線程監(jiān)聽到事件后,判斷事件類型;按照事件類型對(duì)該事件進(jìn)行響應(yīng)和處理,當(dāng)事件類型為客戶端新連接事件時(shí),接收新的套接字并對(duì)新的套接字進(jìn)行處理;當(dāng)事件類型為傳輸請(qǐng)求事件時(shí),接收傳輸請(qǐng)求指令,根據(jù)傳輸請(qǐng)求指令生成請(qǐng)求消息添加到接收消息隊(duì)列等待工作線程的讀?。划?dāng)事件類型為輸出事件時(shí),將處于發(fā)送狀態(tài)的數(shù)據(jù)進(jìn)行發(fā)送處理;所述工作線程工作步驟包括:讀取接收消息隊(duì)列中的請(qǐng)求消息;獲取請(qǐng)求消息的響應(yīng)數(shù)據(jù)并將響應(yīng)數(shù)據(jù)處置為發(fā)送狀態(tài),以供主線程進(jìn)行發(fā)送處理。根據(jù)本發(fā)明的第二方面,提供一種實(shí)現(xiàn)單機(jī)支持高并發(fā)處理系統(tǒng),包括:接收消息隊(duì)列,其用于接收消息;主線程,其用于監(jiān)聽事件,當(dāng)監(jiān)聽到事件后,判斷事件類型,按照事件類型對(duì)該事件進(jìn)行響應(yīng)和處理,當(dāng)事件類型為客戶端新連接事件時(shí),接收新的套接字并對(duì)新的套接字進(jìn)行處理;當(dāng)事件類型為傳輸請(qǐng)求事件時(shí),接收傳輸請(qǐng)求指令,并根據(jù)指令生成請(qǐng)求消息添加到接收消息隊(duì)列;當(dāng)事件類型為輸出事件時(shí),將處于發(fā)送狀態(tài)的數(shù)據(jù)進(jìn)行發(fā)送處理;工作線程,其用于讀取接收消息隊(duì)列中的請(qǐng)求消息,獲取請(qǐng)求消息的響應(yīng)數(shù)據(jù)并將響應(yīng)數(shù)據(jù)處置為發(fā)送狀態(tài),以供主線程進(jìn)行發(fā)送處理;所述接收消息隊(duì)列、主線程和工作線程位于同一服務(wù)器上。根據(jù)本發(fā)明的第三方面,提供一種實(shí)現(xiàn)單機(jī)支持高并發(fā)狀態(tài)下對(duì)傳輸請(qǐng)求事件的處理方法,包括:主線程檢測(cè)到一個(gè)傳輸請(qǐng)求事件時(shí),讀取指令頭及指令體數(shù)據(jù),根據(jù)請(qǐng)求的指令頭及指令體生成一個(gè)請(qǐng)求消息,將請(qǐng)求消息添加到接收消息隊(duì)列;工作線程從接收消息隊(duì)列中取出一條請(qǐng)求消息,根據(jù)請(qǐng)求消息創(chuàng)建響應(yīng)消息頭,然后調(diào)用業(yè)務(wù)處理函數(shù)對(duì)請(qǐng)求消息進(jìn)行處理,生成響應(yīng)數(shù)據(jù),將響應(yīng)數(shù)據(jù)關(guān)聯(lián)到數(shù)據(jù)發(fā)送指針上,并觸發(fā)輸出事件;主線程檢測(cè)到輸出事件后,從數(shù)據(jù)發(fā)送指針上取出關(guān)聯(lián)的響應(yīng)數(shù)據(jù),并將響應(yīng)數(shù)據(jù)發(fā)送出去。本發(fā)明通過主要包括主線程、接收消息隊(duì)列和工作線程的高并發(fā)處理系統(tǒng)架構(gòu),對(duì)不同類型事件進(jìn)行不同處理,使單機(jī)系統(tǒng)實(shí)現(xiàn)了支持更多用戶的并發(fā)訪問,不需要分布式的集群部署,架構(gòu)簡單,整體成本較低。
圖1為本發(fā)明一種實(shí)施例中高并發(fā)處理系統(tǒng)的架構(gòu)圖;圖2為本發(fā)明一種實(shí)施例中主線程工作流程圖;圖3為本發(fā)明一種實(shí)施例中工作線程工作流程圖;圖4為本發(fā)明一種實(shí)施例中對(duì)傳輸請(qǐng)求事件的處理流程圖;圖5為本發(fā)明一種實(shí)施例中實(shí)現(xiàn)單機(jī)支持高并發(fā)處理的主流程圖;圖6為本發(fā)明一種具體實(shí)例中主線程工作流程圖;圖7為本發(fā)明一種具體實(shí)例中工作線程工作流程圖。
具體實(shí)施例方式下面通過具體實(shí)施方式
結(jié)合附圖對(duì)本發(fā)明作進(jìn)一步詳細(xì)說明。本申請(qǐng)通過在單機(jī)(即同一臺(tái)服務(wù)器)系統(tǒng)上設(shè)計(jì)高并發(fā)處理系統(tǒng),通過對(duì)不同類型事件的不同處理,對(duì)多用戶(例如百萬級(jí)用戶)的并發(fā)請(qǐng)求做出響應(yīng)和處理。請(qǐng)參考圖1,實(shí)現(xiàn)單機(jī)支持高并發(fā)處理系統(tǒng)的架構(gòu)如圖1所示,包括位于同一服務(wù)器I上主線程10、接收消息隊(duì)列20和工作線程30,其中主線程10用于創(chuàng)建工作線程30、監(jiān)聽事件,當(dāng)監(jiān)聽到事件后,判斷事件類型,按照事件類型對(duì)該事件進(jìn)行響應(yīng)和處理,當(dāng)事件類型為客戶端新連接事件時(shí),接收新的套接字并對(duì)新的套接字進(jìn)行處理;當(dāng)事件類型為傳輸請(qǐng)求事件時(shí),接收傳輸請(qǐng)求指令,根據(jù)傳輸請(qǐng)求指令生成請(qǐng)求消息添加到接收消息隊(duì)列;當(dāng)事件類型為輸出事件時(shí),將處于發(fā)送狀態(tài)的數(shù)據(jù)進(jìn)行發(fā)送處理。接收消息隊(duì)列20用于接收主線程10發(fā)送來的消息,將消息進(jìn)行先入先出處理或按照預(yù)先設(shè)定的優(yōu)先級(jí)緩存和輸出。工作線程30用于讀取接收消息隊(duì)列中的請(qǐng)求消息,調(diào)用函數(shù)處理后得到請(qǐng)求消息的響應(yīng)數(shù)據(jù)并將響應(yīng)數(shù)據(jù)處置為發(fā)送狀態(tài),以供主線程10進(jìn)行發(fā)送處理。
在一具體實(shí)例中,主線程10包括監(jiān)聽模塊11、輸入處理模塊12和輸出處理模塊
13。監(jiān)聽模塊11用于監(jiān)聽服務(wù)器系統(tǒng)底層觸發(fā)的事件,讀取底層在事件中設(shè)置的標(biāo)識(shí),根據(jù)標(biāo)識(shí)判斷事件類型,當(dāng)事件類型為客戶端新連接事件或已連接客戶的傳輸請(qǐng)求事件時(shí),作為輸入事件發(fā)信息給輸入處理模塊12,并通知輸入處理模塊12事件的類型。輸入處理模塊12根據(jù)事件類型進(jìn)行接收和處理。當(dāng)事件類型為客戶端新連接事件時(shí),輸入處理模塊12循環(huán)接收新的套接字,如果接收失敗,則結(jié)束內(nèi)部循環(huán),如果接收成功,將新的套接字加入服務(wù)器系統(tǒng)的I/O模型隊(duì)列中,當(dāng)接收到數(shù)據(jù)讀取完畢標(biāo)識(shí)時(shí),則結(jié)束事件處理。當(dāng)事件類型為傳輸請(qǐng)求事件時(shí),輸入處理模塊12接收傳輸請(qǐng)求指令的指令頭及指令體,驗(yàn)證合法后,組成一個(gè)請(qǐng)求消息,添加到接收消息隊(duì)列中。在接收指令時(shí),輸入處理模塊12根據(jù)指令頭中描述的長度信息動(dòng)態(tài)分配指令體緩存空間,接收指令體數(shù)據(jù),并將接收到的指令體數(shù)據(jù)放入指令體緩存空間,判斷指令的接收狀態(tài),如果整個(gè)指令接收成功,則將指令體緩存空間中的指令體數(shù)據(jù)放入消息隊(duì)列;如果接收到數(shù)據(jù)讀取完畢標(biāo)識(shí),則結(jié)束事件處理;如果接收失敗則結(jié)束事件的處理。當(dāng)事件類型為輸出事件時(shí),監(jiān)聽模塊11發(fā)信息給輸出處理模塊13,輸出處理模塊13從數(shù)據(jù)發(fā)送指針上讀取處于發(fā)送狀態(tài)的數(shù)據(jù),將該數(shù)據(jù)打包發(fā)送,在發(fā)送數(shù)據(jù)后判斷數(shù)據(jù)發(fā)送狀態(tài),當(dāng)判斷數(shù)據(jù)發(fā)送成功后,將I/O模型隊(duì)列中與接收該數(shù)據(jù)的客戶端的套接字中的輸出事件修改為傳輸請(qǐng)求事件,以便接收來自于該客戶端的下一傳輸請(qǐng)求事件,提高響應(yīng)速度。當(dāng)輸出處理模塊13判斷數(shù)據(jù)發(fā)送失敗后,結(jié)束事件處理。在另一實(shí)施例中,請(qǐng)參考圖1,實(shí)現(xiàn)單機(jī)支持高并發(fā)處理系統(tǒng)還包括與接收消息隊(duì)列20、主線程10和工作線程30位于同一服務(wù)器I上的會(huì)話管理器40,會(huì)話管理器40用于對(duì)客戶端信息進(jìn)行添加、更新或刪除,所述客戶端信息由主線程寫入或刪除。當(dāng)事件類型為客戶端新連接事件且輸入處理模塊12接收該客戶端的套接字成功后,輸入處理模塊12將客戶端信息寫入會(huì)話管理器40。客戶端信息包括客戶端登錄網(wǎng)站信息、心跳信息和連接時(shí)長中的至少一種。當(dāng)事件類型為來自于已在會(huì)話管理器40中建立客戶端信息的客戶端的傳輸請(qǐng)求事件時(shí),如果輸入處理模塊12接收該客戶端的傳輸請(qǐng)求指令不成功,則將I/O模型隊(duì)列中該客戶端的套接字刪除,并將會(huì)話管理器40中該客戶端的客戶端信息刪除。當(dāng)事件類型為輸出事件時(shí),如果輸出處理模塊13判斷數(shù)據(jù)發(fā)送失敗后,將I/O模型隊(duì)列中與接收該數(shù)據(jù)的客戶端的套接字刪除,并刪除會(huì)話管理器中該客戶端信息。如果輸入處理模塊12接收傳輸請(qǐng)求指令不成功或輸出處理模塊13發(fā)送數(shù)據(jù)不成功,說明套接字有誤,所以將I/o模型隊(duì)列中該客戶端的套接字和會(huì)話管理器40中該客戶端的客戶端信息刪除,以便再次觸發(fā)關(guān)于該客戶端的事件時(shí)作為客戶端新連接事件,在I/O模型隊(duì)列中和會(huì)話管理器40中記錄該客戶端的新的套接字,使服務(wù)器系統(tǒng)應(yīng)用層可以和傳輸層通過新的套接字接口。這樣可避免由于通過舊的、無效的或錯(cuò)誤的套接字接收或發(fā)送數(shù)據(jù)而導(dǎo)致的連接時(shí)間過長的問題,從而可提高對(duì)并發(fā)訪問的響應(yīng)速度。因此,在輸入處理模塊12接收傳輸請(qǐng)求指令不成功或輸出處理模塊13發(fā)送數(shù)據(jù)不成功時(shí),也可以將I/o模型隊(duì)列中該客戶端的套接字和會(huì)話管理器40中該客戶端的客戶端信息中的套接字刪除,而保留會(huì)話管理器40中該客戶端的客戶端信息中的其他信息,例如保留客戶端通信的IP地址、使用的傳輸層協(xié)議(TCP或UDP)、客戶端使用的端口號(hào)和心跳信息。當(dāng)下次該客戶端發(fā)出新連接事件時(shí),根據(jù)客戶端通信的IP地址將該客戶端的新的套接字更新到該客戶端信息中。
在另一具體實(shí)例中,刪除客戶端信息的方式還可以按套接字刪除,也可以按超時(shí)時(shí)間刪除。在會(huì)話管理器40寫入客戶端信息后,在一具體實(shí)例中,工作線程30從接收消息隊(duì)列20中讀取一請(qǐng)求消息,根據(jù)該請(qǐng)求消息動(dòng)態(tài)分配響應(yīng)數(shù)據(jù)緩存空間,讀取會(huì)話管理器40中與傳輸請(qǐng)求事件對(duì)應(yīng)的客戶端信息,將響應(yīng)數(shù)據(jù)存入響應(yīng)數(shù)據(jù)緩存空間,將響應(yīng)數(shù)據(jù)緩存空間關(guān)聯(lián)到數(shù)據(jù)發(fā)送指針上,并觸發(fā)輸出事件??蛻舳诵畔⒖商峁┙o上層應(yīng)用程序(即業(yè)務(wù)處理函數(shù))。建立會(huì)話管理器的另一效果是可將其中記錄有信息的客戶端和服務(wù)器保持長連接,例如在客戶端信息中保存有心跳信息,心跳是維持長連接的基本要素。長連接使客戶端有請(qǐng)求產(chǎn)生時(shí),可隨時(shí)處理,不需重新建立連接,節(jié)省了處理時(shí)間,提高了任務(wù)處理效率?;谏鲜黾軜?gòu),在單機(jī)支持高并發(fā)處理時(shí)包括主線程工作步驟和工作線程工作步驟,其中主線程工作步驟如圖2所示,包括以下步驟:步驟S21,主線程監(jiān)聽事件。在一實(shí)施例中,首先創(chuàng)建監(jiān)聽套接字,將監(jiān)聽套接字綁定所述服務(wù)器的IP地址和端口,在主線程監(jiān)聽事件過程中監(jiān)聽來自于被綁定的服務(wù)器的IP地址和端口的事件。步驟S22,當(dāng)主線程監(jiān)聽到事件后,判斷事件類型??筛鶕?jù)所述服務(wù)器底層對(duì)事件設(shè)置的標(biāo)識(shí)判斷事件類型。步驟S23,按照事件類型對(duì)該事件進(jìn)行響應(yīng)和處理,當(dāng)事件類型為客戶端新連接事件時(shí),則執(zhí)行步驟S24,接收新的套接字并對(duì)新的套接字進(jìn)行處理。當(dāng)事件類型為傳輸請(qǐng)求事件時(shí),執(zhí)行步驟S25,接收傳輸請(qǐng)求指令,根據(jù)傳輸請(qǐng)求指令生成請(qǐng)求消息添加到接收消息隊(duì)列等待工作線程的讀取。當(dāng)事件類型為輸出事件時(shí),執(zhí)行步驟S26,將處于發(fā)送狀態(tài)的數(shù)據(jù)進(jìn)行發(fā)送處理。在步驟S24中,主線程的一種處理方案為:主線程循環(huán)接收新的套接字,如果接收失敗,則結(jié)束內(nèi)部循環(huán),如果接收成功,則記錄客戶端信息,當(dāng)接收到數(shù)據(jù)讀取完畢標(biāo)識(shí)時(shí),則結(jié)束事件處理。將新的套接字加入服務(wù)器系統(tǒng)的I/o模型隊(duì)列中,并將與該新的套接字對(duì)應(yīng)的客戶端信息添加到會(huì)話管理器中。新的套接字接收成功后,將新的套接字設(shè)置為非阻塞狀態(tài),當(dāng)系統(tǒng)從非阻塞的套接字上接收消息時(shí),如果該套接字上沒有消息,會(huì)立即返回,不再長時(shí)間等待,從而提高處理速度。在步驟S25中,主線程的一種處理方案為:主線程接收傳輸請(qǐng)求指令的指令頭,根據(jù)指令頭中描述的長度信息動(dòng)態(tài)分配指令體緩存空間,接收指令體數(shù)據(jù),并將接收到的指令體數(shù)據(jù)放入指令體緩存空間,判斷指令的接收狀態(tài),如果整個(gè)指令接收成功,則根據(jù)指令頭及指令體緩存空間中的指令體數(shù)據(jù)生成請(qǐng)求消息,并將請(qǐng)求消息添加到接收消息隊(duì)列,如果接收到數(shù)據(jù)讀取完畢標(biāo)識(shí),則結(jié)束事件處理。在步驟S26中,主線程的一種處理方案為:主線程將處于發(fā)送狀態(tài)的數(shù)據(jù)進(jìn)行打包發(fā)送,在發(fā)送數(shù)據(jù)后判斷數(shù)據(jù)發(fā)送狀態(tài),當(dāng)判斷數(shù)據(jù)發(fā)送成功后,將I/o模型隊(duì)列中與接收該數(shù)據(jù)的客戶端的套接字中的輸出事件修改為傳輸請(qǐng)求事件,當(dāng)輸出處理模塊13判斷數(shù)據(jù)發(fā)送失敗后,結(jié)束事件處理。其中工作線程工作步驟如圖3所示,包括以下步驟:步驟S31,讀取接收消息隊(duì)列中的請(qǐng)求消息。
步驟S32,調(diào)用業(yè)務(wù)處理函數(shù)對(duì)請(qǐng)求消息進(jìn)行處理,生成響應(yīng)數(shù)據(jù)。在一種具體實(shí)例中,根據(jù)請(qǐng)求消息創(chuàng)建響應(yīng)消息頭,響應(yīng)消息頭包含服務(wù)類型,序號(hào),服務(wù)狀態(tài),及響應(yīng)指令體大小等信息,客戶端接收到響應(yīng)頭后,就能知道服務(wù)處理的狀態(tài)。工作線程根據(jù)請(qǐng)求消息動(dòng)態(tài)分配響應(yīng)數(shù)據(jù)緩存空間,調(diào)用上層應(yīng)用設(shè)置的回調(diào)函數(shù)處理業(yè)務(wù)邏輯,生成響應(yīng)數(shù)據(jù),將響應(yīng)數(shù)據(jù)存入響應(yīng)數(shù)據(jù)緩存空間。步驟S33,獲取請(qǐng)求消息的響應(yīng)數(shù)據(jù)并將響應(yīng)數(shù)據(jù)處置為發(fā)送狀態(tài),以供主線程進(jìn)行發(fā)送處理。將響應(yīng)數(shù)據(jù)緩存空間關(guān)聯(lián)到數(shù)據(jù)發(fā)送指針上,并觸發(fā)輸出事件?;谏鲜龈卟l(fā)處理系統(tǒng)的架構(gòu),實(shí)現(xiàn)單機(jī)支持高并發(fā)狀態(tài)下對(duì)傳輸請(qǐng)求事件的處理流程如圖4所示,包括以下步驟:步驟S41,主線程檢測(cè)到一個(gè)傳輸請(qǐng)求事件時(shí),讀取請(qǐng)求的指令頭及指令體數(shù)據(jù),根據(jù)指令頭及指令體數(shù)據(jù)生成一個(gè)請(qǐng)求消息。步驟S42,主線程將請(qǐng)求消息添加到接收消息隊(duì)列。步驟S43,工作線程從接收消息隊(duì)列中取出一條請(qǐng)求消息。步驟S44,工作線程根據(jù)請(qǐng)求消息創(chuàng)建響應(yīng)消息頭,然后調(diào)用業(yè)務(wù)處理函數(shù)處理業(yè)務(wù)邏輯,生成響應(yīng)數(shù)據(jù),將響應(yīng)數(shù)據(jù)關(guān)聯(lián)到數(shù)據(jù)發(fā)送指針上,并觸發(fā)輸出事件。步驟S45,主線程檢測(cè)到輸出事件后,從數(shù)據(jù)發(fā)送指針上取出關(guān)聯(lián)的響應(yīng)數(shù)據(jù),并將響應(yīng)數(shù)據(jù)發(fā)送出去。以系統(tǒng)內(nèi)核為epoll機(jī)制(一種網(wǎng)絡(luò)IO模型,IO事件通知機(jī)制)為例,步驟S41是通過這個(gè)系統(tǒng)內(nèi)核的EPOLL機(jī)制來檢測(cè)的,步驟S44將響應(yīng)數(shù)據(jù)關(guān)聯(lián)到內(nèi)核EPOLL的一個(gè)指針上,并觸發(fā)輸出事件,然后在步驟S45中,主線程通過系統(tǒng)內(nèi)核的EPOLL機(jī)制檢測(cè)到輸出事件,從內(nèi)核的指針上取出該響應(yīng)數(shù)據(jù)。下面以高并發(fā)處理系統(tǒng)基于印oil作為I/O模型為例進(jìn)行進(jìn)一步說明。高并發(fā)服務(wù)器中提升性能的關(guān)鍵是10、CPU和內(nèi)存,所以高并發(fā)的服務(wù)器需要最大限度的利用CPU,減少內(nèi)存申請(qǐng),復(fù)制。其中網(wǎng)絡(luò)IO模型也是影響系統(tǒng)性能的關(guān)鍵因素。本實(shí)施例選擇Iinux平臺(tái)下的epoll作為IO模型,內(nèi)存分配使用tcmalloc (google的一個(gè)開源內(nèi)存管理庫)以提高分配效率及降低頻繁內(nèi)存分配帶來的CPU損耗。服務(wù)器采用多線程的模型,有一個(gè)主線程負(fù)責(zé)網(wǎng)絡(luò)10的輸入及輸出,有多個(gè)工作線程負(fù)責(zé)業(yè)務(wù)邏輯的處理。工作線程之間沒有互相制約的關(guān)系,獨(dú)立執(zhí)行同樣的工作。本實(shí)施例的服務(wù)器是請(qǐng)求響應(yīng)式的,也就是對(duì)應(yīng)每一個(gè)請(qǐng)求都會(huì)產(chǎn)生一個(gè)響應(yīng)消息,無論服務(wù)處理是成功還是失敗。而且請(qǐng)求總是由客戶端發(fā)起的,當(dāng)然一個(gè)服務(wù)器也可以是另外一個(gè)服務(wù)器的客戶端。本實(shí)施例的通訊協(xié)議可以是采用二進(jìn)制格式,以減少內(nèi)存拷貝及提高打包,解包效率。請(qǐng)求及響應(yīng)指令都分為指令頭,及指令體兩部分。指令頭是必須的,并且所有服務(wù)的指令頭都相同,請(qǐng)求及響應(yīng)的指令頭均相同,但具體的參數(shù)會(huì)不一樣,指令體是可選的,指令體一般存儲(chǔ)服務(wù)請(qǐng)求的額外參數(shù)。相比較文本格式,采用二進(jìn)制的指令頭及指令體,指令的解析將十分簡單,從socket句柄(服務(wù)器與客戶端之間的數(shù)據(jù)通道)讀取數(shù)據(jù)時(shí),直接將結(jié)構(gòu)體指令作為參數(shù),讀取指定長度,成功后,就可以直接使用結(jié)構(gòu)體了,這樣就避免了內(nèi)存的二次復(fù)制。系統(tǒng)架構(gòu)包括主線程、接收消息隊(duì)列、工作線程和會(huì)話管理器。
主線程是最核心的模塊之一,其主要功能包括:工作線程的創(chuàng)建,業(yè)務(wù)端口輸入/輸出的監(jiān)聽,接收新的連接,socket (即套接字)數(shù)據(jù)的接收與發(fā)送及客戶信息的管理維護(hù)
坐寸ο主線程通過epoll來管理主監(jiān)聽socket及所有客戶端socket, epoll網(wǎng)絡(luò)IO模型通常有ET/LT兩種觸發(fā)模式,本實(shí)施例采用效率相對(duì)較高的ET模式。當(dāng)監(jiān)聽到EP0LLIN事件(即傳輸請(qǐng)求事件)時(shí)需要循環(huán)讀取緩沖區(qū)的數(shù)據(jù)(或接收所有已準(zhǔn)備好的連接),直到接收到EAGAIN(EAGAIN是一個(gè)信號(hào),表示該套接字上已經(jīng)沒有事件了 )為止,接收到EAGAIN表示本次事件的數(shù)據(jù)已讀取完畢。當(dāng)有新的客戶端連接到服務(wù)端口時(shí),主線程將新的客戶端socket添加到epoll的監(jiān)控列表中,并通過會(huì)話管理器添加客戶端信息到客戶端列表中。而當(dāng)檢測(cè)到客戶端連接失敗時(shí)(如讀取時(shí)返回0,或者心跳失敗),主線程會(huì)從客戶端列表中刪除客戶端信息??蛻舳巳缬行枨笊酝頃?huì)再次發(fā)送請(qǐng)求。當(dāng)有客戶端socket可讀時(shí)(即有傳輸請(qǐng)求產(chǎn)生),主線程會(huì)讀取請(qǐng)求指令頭及指令體,并在做一些合法性驗(yàn)證后將請(qǐng)求消息壓入接收消息隊(duì)列。當(dāng)有客戶端socket可寫時(shí)(即有請(qǐng)求處理結(jié)果產(chǎn)生),主線程會(huì)取出epoll_event中與事件相關(guān)聯(lián)的數(shù)據(jù),并發(fā)送出去。接收消息隊(duì)列是一個(gè)阻塞的同步隊(duì)列,同步指消息隊(duì)列是線程安全的,能夠保證當(dāng)有多個(gè)線程同步訪問隊(duì)列時(shí),不會(huì)導(dǎo)致混亂。阻塞是指,當(dāng)從隊(duì)列中取數(shù)據(jù)時(shí),如果隊(duì)列中此時(shí)沒有數(shù)據(jù),會(huì)一直阻塞,只到有數(shù)據(jù)被添加到隊(duì)列中時(shí),才會(huì)返回。本實(shí)施例設(shè)計(jì)了線程同步,使其可支持多線程并行運(yùn)作并具有阻塞及通知機(jī)制。工作線程負(fù)責(zé)從接收消息隊(duì)列中取出數(shù)據(jù),并調(diào)用用戶設(shè)置的回調(diào)函數(shù)處理業(yè)務(wù)請(qǐng)求。響應(yīng)數(shù)據(jù)直接關(guān)聯(lián)到epoll_event的data, ptr指針上,然后使用epoll_ctl控制信號(hào)觸發(fā)EP0LL_0UT事件(即輸出事件),然后由主線程發(fā)送響應(yīng)數(shù)據(jù)。會(huì)話管理器提供對(duì)客戶信息的添加,更新,刪除等操作??梢园疵枋龇麆h除,也可以按超時(shí)時(shí)間刪除。本實(shí)施例中,一旦建立連接,會(huì)話管理器會(huì)將服務(wù)器與各客戶端之間的連接保持為長連接,這樣在客戶端有請(qǐng)求產(chǎn)生時(shí),可隨時(shí)處理,不需重新建立連接,節(jié)省了處理時(shí)間,提高了任務(wù)處理效率。如圖5所示為一種實(shí)施例中實(shí)現(xiàn)單機(jī)支持高并發(fā)處理的主流程圖,包括以下步驟:步驟S51,啟動(dòng)單機(jī)支持高并發(fā)處理進(jìn)程。步驟S52,初始化會(huì)話管理器。步驟S53,創(chuàng)建監(jiān)聽套接字,并綁定服務(wù)器IP,端口,開始監(jiān)聽事件。步驟S54,創(chuàng)建并啟動(dòng)工作線程。步驟S55,創(chuàng)建印oil套接字,并注冊(cè)監(jiān)聽套接字到EPOLL隊(duì)列中。步驟S56,使用循環(huán)體epoll_wait檢測(cè)epoll事件。當(dāng)檢測(cè)到新事件時(shí),執(zhí)行步驟S57。步驟S57,循環(huán)處理印011事件。一種具體實(shí)例中,epoll事件處理流程如圖6所示,包括以下步驟:步驟S611,判斷是否是監(jiān)聽套接字,如果是監(jiān)聽套接字的事件,表示事件是未曾建立過連接的新客戶端的新連接事件,則執(zhí)行步驟S612,否則執(zhí)行步驟S621。步驟S612,循環(huán)使用系統(tǒng)函數(shù)accept接收該新的客戶端的連接,接收對(duì)應(yīng)于該新客戶端的套接字。步驟S613,判斷接收是否成功,如果接收失敗,即接收到EAGAIN信號(hào),則表示套接字中無數(shù)據(jù)可讀,則結(jié)束內(nèi)部循環(huán),回到步驟S56重新執(zhí)行。如果接收成功,則執(zhí)行步驟S614。步驟S614,設(shè)置對(duì)應(yīng)于該新客戶端的套接字為非阻塞的,并將套接字加入EPOLL隊(duì)列。步驟S615,通過會(huì)話管理器,添加客戶端信息。然后回到步驟S612。步驟S621,判斷是否是EP0LLIN事件,即已知客戶端的輸入事件,即傳輸請(qǐng)求事件,如果是,則執(zhí)行步驟S622,否則執(zhí)行步驟S631。步驟S622,循環(huán)接收傳輸請(qǐng)求事件。首先接收指令頭,并驗(yàn)證指令頭的合法性;根據(jù)指令頭中的length長度,動(dòng)態(tài)分配指令體緩存空間,用于緩存?zhèn)鬏斦?qǐng)求事件的指令體數(shù)據(jù);再接收指令體數(shù)據(jù),將指令體數(shù)據(jù)緩存到指令體緩存空間中。步驟S623,判斷指令體接收狀態(tài)。如果接收成功,則執(zhí)行步驟S624根據(jù)請(qǐng)求的指令頭和指令體生成消息,壓入接收消息隊(duì)列。如果接收失敗,則執(zhí)行步驟S64,從EPOLL隊(duì)列中刪除描述符,然后關(guān)閉描述符,刪除客戶端信息。然后跳到步驟S56處理下一 EPOLL事件。步驟S625,判斷是否接收到EAGAIN信號(hào),如果是,則結(jié)束內(nèi)部循環(huán),回到步驟S56重新處理下一 EPOLL事件。否則轉(zhuǎn)向步驟S622,重新接收下一條請(qǐng)求。步驟S631,判斷是否是EP0LL0UT事件(即輸出事件,服務(wù)器有任務(wù)處理結(jié)果產(chǎn)生),如果是,則執(zhí)行步驟S632。步驟S632,從印oil event中取出暫存在緩存空間中的關(guān)聯(lián)的響應(yīng)數(shù)據(jù)。根據(jù)客戶端信息中記錄的該客戶端的套接字的發(fā)送指令頭,如果發(fā)送成功,接著發(fā)送指令體,并釋放數(shù)據(jù)的緩存空間。步驟S633,判斷發(fā)送狀態(tài)。如果響應(yīng)數(shù)據(jù)發(fā)送成功,則執(zhí)行步驟S634。如果發(fā)送失敗,則執(zhí)行步驟S64,從EPOLL隊(duì)列中刪除該客戶端的套接字,然后關(guān)閉該客戶端的套接字,刪除客戶端信息。步驟S634,將該客戶端套接字的EP0LL0UT事件修改成EP0LLIN事件,結(jié)束事件處理,返回步驟S56重新處理下一 EPOLL事件。當(dāng)然,本領(lǐng)域技術(shù)人員應(yīng)該理解,基于本申請(qǐng)的發(fā)明構(gòu)思,某些步驟執(zhí)行的先后順序可以調(diào)整,例如可先執(zhí)行步驟S631,后執(zhí)行步驟S621。一種具體實(shí)例中,工作線程的處理流程圖如圖7所示,包括以下步驟:步驟S71,從接收消息隊(duì)列中取出一條請(qǐng)求數(shù)據(jù)ReqData。步驟S72,動(dòng)態(tài)分配響應(yīng)數(shù)據(jù)的緩存空間,并根據(jù)緩存空間來進(jìn)行初始化。步驟S73,調(diào)用業(yè)務(wù)處理函數(shù),對(duì)請(qǐng)求數(shù)據(jù)進(jìn)行處理。步驟S74,釋放請(qǐng)求數(shù)據(jù)ReqData的空間。步驟S75,將響應(yīng)數(shù)據(jù)關(guān)聯(lián)到Epoll的event上,并使用epoll_ctl將套接字的事件改為EP0LL0UT,觸發(fā)EP0LL0UT事件,由主線程來發(fā)送數(shù)據(jù)。然后回到步驟S71,繼續(xù)處理下一條消息數(shù)據(jù)。本實(shí)施例采用單進(jìn)程、多線程模型,其中的網(wǎng)絡(luò)接收及發(fā)送都在同一線程中完成,業(yè)務(wù)處理在獨(dú)立的工作線程中完成。同時(shí)工作線程是預(yù)先創(chuàng)建好的,線程數(shù)也是固定的。這種設(shè)計(jì)帶來的好處是避免線程過多導(dǎo)致的上下文切換開銷。并使系統(tǒng)足夠簡潔。請(qǐng)求響應(yīng)式的服務(wù)模式,即請(qǐng)求總是由客戶端發(fā)起的,并且服務(wù)器總是有一個(gè)返回。這種設(shè)計(jì)的好處同樣是使系統(tǒng)處理流程更簡潔,效率更高,以支持更高的并發(fā)量。基于二進(jìn)制的協(xié)議設(shè)計(jì),使數(shù)據(jù)打包與解包的處理效率更高。以上內(nèi)容是結(jié)合具體的實(shí)施方式對(duì)本發(fā)明所作的進(jìn)一步詳細(xì)說明,不能認(rèn)定本發(fā)明的具體實(shí)施只局限于這些說明。對(duì)于本發(fā)明所屬技術(shù)領(lǐng)域的普通技術(shù)人員來說,在不脫離本發(fā)明構(gòu)思的前提下,還可以做出若干簡單推演或替換,都應(yīng)當(dāng)視為屬于本發(fā)明的保護(hù)范圍。
權(quán)利要求
1.一種實(shí)現(xiàn)單機(jī)支持高并發(fā)處理方法,其特征在于包括,由同一服務(wù)器執(zhí)行的主線程工作步驟和工作線程工作步驟,所述主線程工作步驟包括: 主線程監(jiān)聽事件; 當(dāng)主線程監(jiān)聽到事件后,判斷事件類型; 按照事件類型對(duì)該事件進(jìn)行響應(yīng)和處理,當(dāng)事件類型為客戶端新連接事件時(shí),接收新的套接字并對(duì)新的套接字進(jìn)行處理;當(dāng)事件類型為傳輸請(qǐng)求事件時(shí),接收傳輸請(qǐng)求指令,根據(jù)傳輸請(qǐng)求指令生成請(qǐng)求消息添加到接收消息隊(duì)列等待工作線程的讀??;當(dāng)事件類型為輸出事件時(shí),將處于發(fā)送狀態(tài)的數(shù)據(jù)進(jìn)行發(fā)送處理; 所述工作線程工作步驟包括: 讀取接收消息隊(duì)列中的請(qǐng)求消息; 獲取請(qǐng)求消息的響應(yīng)數(shù)據(jù)并將響應(yīng)數(shù)據(jù)處置為發(fā)送狀態(tài),以供主線程進(jìn)行發(fā)送處理。
2.如權(quán)利要求1所述的方法,其特征在于,所述主線程監(jiān)聽事件之前還包括:創(chuàng)建監(jiān)聽套接字,將監(jiān)聽套接字綁定所述服務(wù)器的IP地址和端口,在主線程監(jiān)聽事件過程中監(jiān)聽來自于被綁定的服務(wù)器的IP地址和端口的事件,所述主線程監(jiān)聽到事件后,根據(jù)所述服務(wù)器底層對(duì)事件設(shè)置的標(biāo)識(shí)判斷事件類型。
3.如權(quán)利要求1或2所述的方法,其特征在于,當(dāng)事件類型為客戶端新連接事件時(shí),所述接收新的套接字并對(duì)新的套接字進(jìn)行處理步驟包括: 循環(huán)接收新的套接字,如果接收失敗,則結(jié)束內(nèi)部循環(huán),如果接收成功,則記錄客戶端信息,當(dāng)接收到數(shù)據(jù)讀取完畢標(biāo)識(shí)時(shí),則結(jié)束事件處理。
4.如權(quán)利要求3所述的方法,其特征在于,新的套接字接收成功后,將新的套接字設(shè)置為非阻塞狀態(tài),所述記錄客戶端信息包括:將新的套接字加入服務(wù)器系統(tǒng)的I/O模型隊(duì)列中,并將與該新的套接字對(duì)應(yīng)的客戶端信息添加到會(huì)話管理器中。
5.如權(quán)利要求1或2所述的方法,其特征在于,當(dāng)事件類型為傳輸請(qǐng)求事件時(shí),所述接收傳輸請(qǐng)求指令,并將指令體中的請(qǐng)求消息添加到接收消息隊(duì)列步驟包括: 接收傳輸請(qǐng)求指令的指令頭; 根據(jù)指令頭中描述的長度信息動(dòng)態(tài)分配指令體緩存空間; 接收指令體數(shù)據(jù),并將接收到的指令體數(shù)據(jù)放入指令體緩存空間; 判斷指令的接收狀態(tài),如果整個(gè)指令接收成功,則根據(jù)請(qǐng)求的指令頭及指令體生成一個(gè)請(qǐng)求消息,將請(qǐng)求消息添加到接收消息隊(duì)列;如果接收到數(shù)據(jù)讀取完畢標(biāo)識(shí),則結(jié)束事件處理;如果接收失敗,則刪除I/o模型隊(duì)列中與發(fā)送傳輸請(qǐng)求指令的客戶端對(duì)應(yīng)的套接字,刪除會(huì)話管理器中該客戶端信息。
6.如權(quán)利要求1或2所述的方法,其特征在于,當(dāng)事件類型為輸出事件時(shí),將處于發(fā)送狀態(tài)的數(shù)據(jù)進(jìn)行發(fā)送處理步驟包括: 當(dāng)判斷數(shù)據(jù)發(fā)送成功后,將I/o模型隊(duì)列中與接收該數(shù)據(jù)的客戶端的套接字中的輸出事件修改為傳輸請(qǐng)求事件; 當(dāng)判斷數(shù)據(jù)發(fā)送失敗后,將I/o模型隊(duì)列中與接收該數(shù)據(jù)的客戶端的套接字刪除,并刪除會(huì)話管理器中該客戶端信息。
7.如權(quán)利要求1或2所述的方法,其特征在于,獲取請(qǐng)求消息的響應(yīng)數(shù)據(jù)并將響應(yīng)數(shù)據(jù)處置為發(fā)送狀態(tài)包括:根據(jù)請(qǐng)求消息動(dòng)態(tài)分配響應(yīng)數(shù)據(jù)緩存空間; 調(diào)用業(yè)務(wù)處理函數(shù)對(duì)請(qǐng)求消息進(jìn)行處理; 將響應(yīng)數(shù)據(jù)存入響應(yīng)數(shù)據(jù)緩存空間; 將響應(yīng)數(shù)據(jù)緩存空間關(guān)聯(lián)到數(shù)據(jù)發(fā)送指針上,并觸發(fā)輸出事件。
8.一種實(shí)現(xiàn)單機(jī)支持高并發(fā)處理系統(tǒng),其特征在于包括: 接收消息隊(duì)列,其用于接收消息; 主線程,其用于監(jiān)聽事件,當(dāng)監(jiān)聽到事件后,判斷事件類型,按照事件類型對(duì)該事件進(jìn)行響應(yīng)和處理,當(dāng)事件類型為客戶端新連接事件時(shí),接收新的套接字并對(duì)新的套接字進(jìn)行處理;當(dāng)事件類型為傳輸請(qǐng)求事件時(shí),接收傳輸請(qǐng)求指令,并根據(jù)指令生成請(qǐng)求消息添加到接收消息隊(duì)列;當(dāng)事件類型為輸出事件時(shí),將處于發(fā)送狀態(tài)的數(shù)據(jù)進(jìn)行發(fā)送處理; 工作線程,其用于讀取接收消息隊(duì)列中的請(qǐng)求消息,獲取請(qǐng)求消息的響應(yīng)數(shù)據(jù)并將響應(yīng)數(shù)據(jù)處置為發(fā)送狀態(tài),以供主線程進(jìn)行發(fā)送處理; 所述接收消息隊(duì)列、主線程和工作線程位于同一服務(wù)器上。
9.如權(quán)利要求8所述的高并發(fā)處理系統(tǒng),其特征在于,所述高并發(fā)處理系統(tǒng)基于epoll作為I/O模型創(chuàng)建,所述主線程綁定所述服務(wù)器的IP地址和端口,其監(jiān)聽的事件為該IP地址和端口的事件。
10.如權(quán)利要求8或9所述的高并發(fā)處理系統(tǒng),其特征在于,還包括與接收消息隊(duì)列、主線程和工作線程位于同一服務(wù)器上的會(huì)話管理器,所述會(huì)話管理器用于對(duì)客戶端信息進(jìn)行添加、更新或刪除,所述客戶端信息由主線程寫入或刪除。
11.如權(quán)利要求1 0所述的高并發(fā)處理系統(tǒng),其特征在于,所述客戶端信息包括客戶端登錄網(wǎng)站信息、心跳信息和連接時(shí)長中的至少一種;所述會(huì)話管理器將其中記錄有信息的客戶端和服務(wù)器保持長連接。
12.如權(quán)利要求8或9所述的高并發(fā)處理系統(tǒng),其特征在于,當(dāng)主線程判斷事件類型為客戶端新連接事件時(shí),主線程循環(huán)接收新的套接字,如果接收失敗,則結(jié)束內(nèi)部循環(huán),如果接收成功,將新的套接字加入服務(wù)器系統(tǒng)的I/O模型隊(duì)列中,并將與該新的套接字對(duì)應(yīng)的客戶端信息添加到會(huì)話管理器中,當(dāng)接收到數(shù)據(jù)讀取完畢標(biāo)識(shí)時(shí),則結(jié)束事件處理;當(dāng)主線程判斷事件類型為傳輸請(qǐng)求事件時(shí),主線程接收傳輸請(qǐng)求指令的指令頭,根據(jù)指令頭中描述的長度信息動(dòng)態(tài)分配指令體緩存空間,接收指令體數(shù)據(jù),并將接收到的指令體數(shù)據(jù)放入指令體緩存空間,判斷指令的接收狀態(tài),如果整個(gè)指令接收成功,則根據(jù)指令頭及指令體數(shù)據(jù)生成一個(gè)請(qǐng)求消息并將該請(qǐng)求消息添加到接收消息隊(duì)列;如果接收到數(shù)據(jù)讀取完畢標(biāo)識(shí),則結(jié)束事件處理;如果接收失敗,則刪除I/o模型隊(duì)列中與發(fā)送傳輸請(qǐng)求指令的客戶端對(duì)應(yīng)的套接字,刪除會(huì)話管理器中該客戶端信息;當(dāng)主線程判斷事件類型為輸出事件時(shí),主線程在發(fā)送數(shù)據(jù)后判斷數(shù)據(jù)發(fā)送狀態(tài),當(dāng)判斷數(shù)據(jù)發(fā)送成功后,將I/o模型隊(duì)列中與接收該數(shù)據(jù)的客戶端的套接字中的輸出事件修改為傳輸請(qǐng)求事件,當(dāng)判斷數(shù)據(jù)發(fā)送失敗后,將I/o模型隊(duì)列中與接收該數(shù)據(jù)的客戶端的套接字刪除,并刪除會(huì)話管理器中該客戶端信息。
13.如權(quán)利要求8或9所述的高并發(fā)處理系統(tǒng),其特征在于,所述工作線程從接收消息隊(duì)列中讀取一請(qǐng)求消息,根據(jù)該請(qǐng)求消息動(dòng)態(tài)分配響應(yīng)數(shù)據(jù)緩存空間,調(diào)用業(yè)務(wù)處理函數(shù)對(duì)請(qǐng)求消息進(jìn)行處理生成響應(yīng)數(shù)據(jù),將響應(yīng)數(shù)據(jù)存入響應(yīng)數(shù)據(jù)緩存空間,將響應(yīng)數(shù)據(jù)緩存空間關(guān)聯(lián)到數(shù)據(jù)發(fā)送指針上,并觸發(fā)輸出事件。
14.一種實(shí)現(xiàn)單機(jī)支持高并發(fā)狀態(tài)下對(duì)傳輸請(qǐng)求事件的處理方法,其特征在于包括: 主線程檢測(cè)到一個(gè)傳輸請(qǐng)求事件時(shí),讀取指令頭及指令體數(shù)據(jù),根據(jù)請(qǐng)求的指令頭及指令體生成一個(gè)請(qǐng)求消息,將請(qǐng)求消息添加到接收消息隊(duì)列; 工作線程從接收消息隊(duì)列中取出一條請(qǐng)求消息,根據(jù)請(qǐng)求消息創(chuàng)建響應(yīng)消息頭,然后調(diào)用業(yè)務(wù)處理函數(shù)對(duì)請(qǐng)求消息進(jìn)行處理,生成響應(yīng)數(shù)據(jù),將響應(yīng)數(shù)據(jù)關(guān)聯(lián)到數(shù)據(jù)發(fā)送指針上,并觸發(fā)輸出事件; 主線程檢測(cè)到輸出事件后, 從數(shù)據(jù)發(fā)送指針上取出關(guān)聯(lián)的響應(yīng)數(shù)據(jù),并將響應(yīng)數(shù)據(jù)發(fā)送出去。
全文摘要
本發(fā)明公開了一種實(shí)現(xiàn)單機(jī)支持高并發(fā)處理方法及系統(tǒng),包括位于同一服務(wù)器上的接收消息隊(duì)列、主線程和工作線程,主線程監(jiān)聽到事件后,判斷事件類型,當(dāng)事件類型為客戶端新連接事件時(shí),接收新的套接字并對(duì)新的套接字進(jìn)行處理;當(dāng)事件類型為傳輸請(qǐng)求事件時(shí),接收傳輸請(qǐng)求指令,并根據(jù)指令生成請(qǐng)求消息添加到接收消息隊(duì)列;當(dāng)事件類型為輸出事件時(shí),將處于發(fā)送狀態(tài)的數(shù)據(jù)進(jìn)行發(fā)送處理;工作線程讀取接收消息隊(duì)列中的請(qǐng)求消息,獲取請(qǐng)求消息的響應(yīng)數(shù)據(jù)并將響應(yīng)數(shù)據(jù)處置為發(fā)送狀態(tài)。本發(fā)明使單機(jī)系統(tǒng)實(shí)現(xiàn)了支持更多用戶的并發(fā)訪問,不需要分布式的集群部署,架構(gòu)簡單,整體成本較低。
文檔編號(hào)G06F9/46GK103164256SQ201110405659
公開日2013年6月19日 申請(qǐng)日期2011年12月8日 優(yōu)先權(quán)日2011年12月8日
發(fā)明者劉小杰, 伍正勇 申請(qǐng)人:深圳市快播科技有限公司