李 鵬
(1.英業(yè)達(dá)集團(tuán)(天津)電子有限公司 天津 300193;2.天津科技大學(xué)電子信息與自動(dòng)化學(xué)院 天津 300457)
目前,國(guó)內(nèi)外市場(chǎng)上的客戶關(guān)系管理系統(tǒng)(CRM)多采用Java作為基礎(chǔ)語(yǔ)言進(jìn)行設(shè)計(jì)開發(fā),其安全性、穩(wěn)定性、系統(tǒng)完善度、架構(gòu)安全性等得到了很好的保證。但是其開發(fā)周期相對(duì)較長(zhǎng),人力需求較多,最重要的是Java在高并發(fā)的處理上存在一些弊端,很容易造成Server端阻塞 。而Node.js高效的異步事件調(diào)度機(jī)制和基于javascript的閉包模式較好地解決了這些弊端。
Node.js是由 Ryan Dahl編寫的服務(wù)器端 javascript,其初衷是為了編寫更為高效的 Web服務(wù)器,它使用當(dāng)前最快的谷歌V8 javascript引擎和單線程的模式。因?yàn)椴恍枰紤]并發(fā),因此也就不涉及鎖和阻塞的問(wèn)題,大大簡(jiǎn)化了編程。 它的事件回調(diào)模型均采用異步操作,如數(shù)據(jù)庫(kù)訪問(wèn)都是通過(guò)事件來(lái)觸發(fā)的。
Node.js完全發(fā)揮了 javascript作為動(dòng)態(tài)解釋語(yǔ)言的強(qiáng)大威力,開發(fā)人員可以自由使用 javascript的一切特性,如閉包(closure),并且不需要擔(dān)心跨瀏覽器支持(因?yàn)槭欠?wù)端)。那么單線程如何處理多用戶請(qǐng)求呢?事實(shí)上,Ryan觀察到 Web訪問(wèn)的一個(gè)事實(shí):每次 Web請(qǐng)求服務(wù)周期最耗費(fèi)時(shí)間的往往是 I/O 操作,包括讀寫文件、數(shù)據(jù)庫(kù)操作、開啟網(wǎng)絡(luò)等。真正Web 服務(wù)內(nèi)部的運(yùn)算只占很小的比例。例如瀏覽器訪問(wèn)一個(gè)頁(yè)面,幾乎大部分時(shí)間都花在 I/O的讀寫上,從讀文件一直到向接口(socket)寫數(shù)據(jù),花在頁(yè)面后端代碼的計(jì)算量則微乎其微。舉例來(lái)說(shuō),假設(shè) Web Server是一個(gè)銀行,每個(gè)瀏覽器的訪問(wèn)相當(dāng)于客戶去窗口取一筆錢,客戶在某個(gè)窗口辦理業(yè)務(wù)相當(dāng)于服務(wù)器從本地硬盤讀寫文件,這個(gè)操作會(huì)花很長(zhǎng)時(shí)間,由于窗口數(shù)有限,所以需要一個(gè)排隊(duì)叫號(hào)系統(tǒng),即Node.js線程。當(dāng)窗口有空時(shí),營(yíng)業(yè)員就通知排號(hào)系統(tǒng)叫下一位,但是喇叭一次只播放一個(gè)叫號(hào)的聲音,所以所有通知都存放在了一個(gè)事件隊(duì)列中,排號(hào)系統(tǒng)報(bào)完一個(gè)號(hào)再處理下一個(gè),直到隊(duì)列空為止,然后就處于空閑狀態(tài)。如果把叫號(hào)類比后端代碼執(zhí)行,它的速度就會(huì)比處理銀行業(yè)務(wù)快得多,所以只需一個(gè)喇叭就足夠了。由于沒有多線程的切換消耗,所有運(yùn)算都作用在實(shí)際的計(jì)算上,從而提高了處理量。
Node.js 在實(shí)時(shí)的 Web應(yīng)用上采用了基于 WebSocket的推送技術(shù)。這意味著在經(jīng)過(guò)了20多年的基于無(wú)狀態(tài)的請(qǐng)求-返回機(jī)制的無(wú)狀態(tài)交互之后,終于有了實(shí)時(shí)的、雙向連接的Web應(yīng)用,客戶端和服務(wù)器端都可以發(fā)起通信,能夠自由地交換數(shù)據(jù)。與此形成鮮明對(duì)比的是傳統(tǒng)的 Web響應(yīng)模式,客戶端總是主動(dòng)發(fā)起通信而服務(wù)端被動(dòng)返回。此外,這些都是基于運(yùn)行在標(biāo)準(zhǔn)80端口上的開放Web組件(HTML、CSS和JS)。
盡管 Flash 和 Java Applet 的形式已經(jīng)應(yīng)用很多年了,但實(shí)際上這些方式只是使用網(wǎng)絡(luò)將數(shù)據(jù)傳遞到客戶端上的沙箱(Sandboxie)環(huán)境。它們都是隔離運(yùn)行的,而且經(jīng)常操作到需要額外的權(quán)限之類的非標(biāo)準(zhǔn)端口。憑借獨(dú)特的優(yōu)勢(shì),目前Node.js已在許多著名公司的產(chǎn)品中發(fā)揮了關(guān)鍵作用。
Node.js 的主要思路是:使用非阻塞的、事件驅(qū)動(dòng)的 I/O操作來(lái)保持在處理跨平臺(tái)(across distributed devices)數(shù)據(jù)密集型實(shí)時(shí)應(yīng)用時(shí)的輕巧高效。簡(jiǎn)單講,Node.js 不是一個(gè)即將主導(dǎo)Web開發(fā)的銀彈(silver bullet)級(jí)的平臺(tái)。相反,它是一個(gè)滿足特別需求的平臺(tái)。事實(shí)上,使用它進(jìn)行繁重的計(jì)算等于摒棄Node 所有的優(yōu)點(diǎn)。Node 真正的亮點(diǎn)在于建設(shè)高性能、高擴(kuò)展性的互聯(lián)網(wǎng)應(yīng)用,因?yàn)樗軌蛱幚睚嫶蟮?、高吞吐量的并發(fā)連接。
傳統(tǒng)的網(wǎng)絡(luò)服務(wù)技術(shù),是每新增一個(gè)連接(請(qǐng)求)便生成一個(gè)新的線程,這個(gè)新的線程會(huì)占用系統(tǒng)內(nèi)存,最終會(huì)占據(jù)所有的可用內(nèi)存。而 Node.js使用非阻塞的異步 I/O 調(diào)用,僅運(yùn)行在一個(gè)單線程中,所有連接都由該線程處理,全部掛在該線程的事件循環(huán)中,可以允許其支持?jǐn)?shù)萬(wàn)個(gè)并發(fā)連接。
當(dāng)所有客戶端請(qǐng)求共享單一線程時(shí) Node.js也會(huì)出現(xiàn)問(wèn)題,這也是編寫 Node.js 應(yīng)用的潛在缺陷。首先,大量的計(jì)算可能會(huì)使 Node 的單線程暫時(shí)失去反應(yīng),并導(dǎo)致所有的其他客戶端的請(qǐng)求一直阻塞至計(jì)算結(jié)束。其次,開發(fā)人員需要非常小心地避免 Exception 阻塞核心的事件循環(huán),因?yàn)檫@將導(dǎo)致Node.js 實(shí)例的終止(即程序崩潰)。
CRM管理系統(tǒng)的軟件架構(gòu)組成如圖1所示:
圖1 CRM管理系統(tǒng)的軟件架構(gòu)Fig.1 Software architecture of CRM management system
圖 1顯示了 CRM 系統(tǒng)的工作流程:瀏覽器端通過(guò) Apps發(fā)送請(qǐng)求(Ajax)至后臺(tái)(Server),后臺(tái)尋找此請(qǐng)求所對(duì)應(yīng)的方法,這些方法通過(guò)與數(shù)據(jù)庫(kù)的交互工具(MongoSkin等)來(lái)實(shí)現(xiàn)對(duì)數(shù)據(jù)的增、刪、改、查,再把相應(yīng)的結(jié)果返給 Apps,然后通過(guò) Html及 javescript顯示在瀏覽器(Browser)段,這樣就可以將客戶數(shù)據(jù)展示在瀏覽器端對(duì)應(yīng)的功能區(qū),也可以實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)中所存用戶數(shù)據(jù)的增、刪、改、查等處理。
CRM系統(tǒng)中的網(wǎng)頁(yè)主要是基于HTML、CSS和javascript技術(shù)實(shí)現(xiàn)的,再通過(guò)JQuery、Bootstrap等輔助工具來(lái)更好地實(shí)現(xiàn)所需功能和頁(yè)面的美觀。
開發(fā)一個(gè) Web 應(yīng)用程序,最重要的莫過(guò)于數(shù)據(jù)庫(kù)的使用。過(guò)去 PHP 有 MySQL 當(dāng)最佳伙伴,而現(xiàn)在 Node.js 有MongoDB 做最佳的組合。MongoDB 是 NoSQL(非關(guān)系型數(shù)據(jù)庫(kù))的代表之一,它是一個(gè)基于分布式文件存儲(chǔ)的數(shù)據(jù)庫(kù),由 C++語(yǔ)言編寫,其采用 JSON/BSON 作為數(shù)據(jù)儲(chǔ)存和溝通的格式,亦使用 javascript 做為服務(wù)器端(Server-side)的執(zhí)行語(yǔ)言,一切設(shè)計(jì)習(xí)慣都與 Node.js 非常吻合,搭配使用也方便快捷。
該系統(tǒng)使用MongoDB數(shù)據(jù)庫(kù),它擁有 NoSQL 的普遍特性,不用預(yù)先定義數(shù)據(jù)結(jié)構(gòu)(Schema),并且能夠勝任大數(shù)據(jù)量下任意字段的查詢,寫入性能高,可寫入百萬(wàn)級(jí)別的數(shù)據(jù)。MongoDB比普通關(guān)系型數(shù)據(jù)庫(kù)快。因此,針對(duì) CRM 系統(tǒng)大數(shù)據(jù)量的用戶數(shù)據(jù)和ESMS架構(gòu)所采用的Node.js技術(shù),使用MongoDB數(shù)據(jù)庫(kù)。
CRM 管理系統(tǒng)含用戶登錄、系統(tǒng)首頁(yè)平臺(tái)、用戶管理、商品分析等功能模塊,基于 Node.js、Html、javascript等技術(shù)應(yīng)用MongoDb數(shù)據(jù)庫(kù)搭建了這些功能平臺(tái),用戶可以依據(jù)興趣或需求點(diǎn)擊相關(guān)按鈕進(jìn)入相關(guān)頁(yè)面查看。
用戶使用賬號(hào)、密碼完成登錄,登錄成功會(huì)看到系統(tǒng)首頁(yè),如登錄失敗會(huì)有失敗提示。登錄界面如圖2所示。
圖2 登錄界面Fig.2 Login interface
系統(tǒng)首頁(yè)分為 3部分內(nèi)容:①標(biāo)題欄為業(yè)務(wù)功能區(qū),通過(guò)點(diǎn)擊標(biāo)題欄中的功能區(qū)可以進(jìn)入到相對(duì)應(yīng)的功能模塊;②報(bào)表分析區(qū),通過(guò)采樣將客戶數(shù)據(jù)進(jìn)行分析和整理,然后以圖形的方式直觀地顯示出來(lái);③登入用戶顯示及注銷區(qū),用戶點(diǎn)擊登錄名后的下拉箭頭,可以選擇退出系統(tǒng),也可以修改個(gè)人信息情況。
系統(tǒng)首頁(yè)界面如圖3所示。
客戶管理模塊界圖面如圖4所示。
該模塊主要有:會(huì)員列表、會(huì)員自定義分組、會(huì)員等級(jí)設(shè)定等功能。用戶點(diǎn)選菜單中的 [客戶管理] → [會(huì)員列表] 功能,系統(tǒng)顯示會(huì)員列表界面。會(huì)員列表界面可以支持多種分類查詢,查詢功能包含分組查詢和條件查詢。
圖3 系統(tǒng)首頁(yè)界面Fig.3 Interface of system homepage
圖4 客戶管理模塊界面Fig.4 Interface of client management module
在頁(yè)面中輸入?yún)R入渠道、姓名、性別、手機(jī)號(hào)等字段中任意要搜索的值,點(diǎn)擊確定,觸發(fā)以下方法并傳入相應(yīng)參數(shù):
最后將查找出的 json數(shù)據(jù)返回前臺(tái),前臺(tái)會(huì)據(jù)此畫出對(duì)應(yīng)的表格等操作。
通過(guò)以上前后臺(tái)數(shù)據(jù)傳遞代碼可以看出,當(dāng)請(qǐng)求發(fā)到Node.js后,它會(huì)采用回掉(CallBack)的方式來(lái)處理事件,整個(gè)過(guò)程沒有阻塞也不需要等待?;谶@樣的機(jī)制,理論上陸續(xù)有用戶請(qǐng)求連接,Node.js都可以進(jìn)行響應(yīng),因此 Node.js能支持比 Java、PHP程序更高的并發(fā)量,雖然 Java、PHP也可以通過(guò)子線程的方式來(lái)實(shí)現(xiàn)并發(fā)請(qǐng)求,但顯然 Node.js的回掉函數(shù)和異步機(jī)制性能更高。由于要實(shí)現(xiàn)的操作系統(tǒng)可能會(huì)有很多的并發(fā)情況和I/O請(qǐng)求,因此采用Node.js和MongoDB的開發(fā)模式會(huì)更加高效易用。
同樣,其他的一些功能模塊也是采用類似的邏輯,只是按照不同的需求而搭建不同的頁(yè)面結(jié)構(gòu)來(lái)完成,如商品分析、客戶服務(wù)、系統(tǒng)數(shù)據(jù)管理等功能。
介紹了Node.js以及以Node.js為基礎(chǔ)開發(fā)框架的應(yīng)用系統(tǒng) CRM。它使用 Google的 V8虛擬機(jī)來(lái)解析和執(zhí)行javascript代碼,也可以說(shuō) Node.js就等于“運(yùn)行時(shí)環(huán)境+庫(kù)”。它使用單線程和非阻塞I/O,這使得架構(gòu)性能更好,開發(fā)代碼更為整潔,同時(shí) Node.js是一個(gè)非常靠近底層的工具庫(kù)或運(yùn)行環(huán)境,可以精細(xì)控制 Request 和 Response 的時(shí)間和內(nèi)容,而且它的異步回調(diào)模式能夠更好地處理大并發(fā)事件。因此,CRM 管理系統(tǒng)使用 Node.js可以更好地處理多人操作的并發(fā)情況以及大數(shù)據(jù)量所帶來(lái)的問(wèn)題,通過(guò) Node.js的異步模式和其特有的監(jiān)聽方式,可以更好地對(duì)用戶數(shù)據(jù)進(jìn)行統(tǒng)計(jì)和采樣,使操作人員更好地掌握用戶的相關(guān)數(shù)據(jù)。
隨著信息化服務(wù)時(shí)代的到來(lái),Web服務(wù)的高效性和準(zhǔn)確性也日益重要。綜合Node.js的優(yōu)勢(shì),其在未來(lái)的Web開發(fā)和其他軟件開發(fā)領(lǐng)域一定會(huì)得到廣泛應(yīng)用■。
[1]李松峰.JQuery基礎(chǔ)教程[M].北京:人民郵電出版社,2012.
[2][美]Mike,Wilson著;林冀,范俊,張鵬譯.Node應(yīng)用程序構(gòu)建[M].北京:人民郵電出版社,2014.
[3]黃丹華.Node.js開發(fā)實(shí)戰(zhàn)詳解[M].北京:清華大學(xué)出版社,2014.
[4]郭遠(yuǎn)威.大數(shù)據(jù)存儲(chǔ)MongoDB實(shí)戰(zhàn)指南[M].北京:人民郵電出版社,2015.
[5]Bowers M,Synodinos D,Sumner V.Pro HTML5 and CSS3 Design Patterns[Z].2013:1.
[6]李安瑜.Web Service技術(shù)與實(shí)現(xiàn)[M].北京:國(guó)防工業(yè)出版社,2003.